Skip to content

feat(cmd): launch terminal commands under entry-declared security context - #558

Merged
wolfy-j merged 5 commits into
mainfrom
feat/terminal-command-security
Aug 8, 2026
Merged

feat(cmd): launch terminal commands under entry-declared security context#558
wolfy-j merged 5 commits into
mainfrom
feat/terminal-command-security

Conversation

@wolfy-j

@wolfy-j wolfy-j commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Problem

Strict security mode exposed that CLI terminal commands start without the actor and policy scope declared for that command. Security checks then deny because the process frame is incomplete.

Change

A command can declare its launch security context in meta.command.security:

meta:
  command:
    name: test
    security:
      actor:
        id: app:runner
        meta:
          tenant: acme
      policies:
        - app:runner_policy
  • Command metadata is decoded into the existing typed security.Config; actor metadata is preserved and malformed known fields are rejected.
  • system/security.ResolveConfigPairs is the single resolution path used by both WithSecurityConfig and terminal command launch.
  • Resolution preserves an inherited actor when none is declared and merges declared policies into an inherited scope.
  • The CLI attaches the resolved actor and scope to process.Start.Context, which the terminal host applies to the process frame.
  • Missing registries, policies, groups, malformed declarations, and entry lookup failures abort launch before the process manager is called.

WithSecurityConfig remains a compatibility wrapper: it applies all successfully resolved pairs and retains its existing tolerant behavior for unresolved references.

Security boundary

The declaration lives under meta.command, so it is honored only by the trusted CLI terminal-launch path. Ordinary process spawns do not consume it. Entries without the declaration retain their existing behavior.

Verification

  • Typed metadata tests cover actor metadata, policy/group IDs, malformed fields, empty declarations, and forward-compatible unknown fields.
  • Resolver tests cover missing registries/references, actor inheritance, scope merging, and transport into the same frame shape used by the terminal host.
  • Launch tests prove invalid declarations fail before process-manager startup.
  • go test ./..., targeted race tests, and linters for the changed packages pass locally.

…text

A command entry may declare meta.command.security (actor id plus policy and
group references). The CLI launcher resolves it against the deployment's
security registry and attaches the actor and scope to the process start
context, so the command runs with a complete security context under strict
mode instead of having every check denied.

The block lives inside meta.command deliberately: it applies only to the
trusted terminal-launcher path — the operator started the command on their
own deployment — and never to ordinary spawns of the same process entry.
Unknown entries, commands without the block, and unresolvable references keep
today's behavior.
wolfy-j added a commit to wippyai/framework that referenced this pull request Aug 8, 2026
The runner discovers and executes arbitrary registry entries, so it declares
meta.command.security with its own actor and an unrestricted runner_policy.
The CLI launcher (wippyai/runtime#558) resolves the block and installs the
context at start, which restores test discovery under strict security mode —
previously the actor-less runner process had every registry read denied and
reported 'No tests found'.
wolfy-j added a commit to wippyai/kickside-module that referenced this pull request Aug 8, 2026
…contract

Initializer: single-pass longest-first replacement so starter-prefixed module
names cannot be corrupted by rescanning replaced output; bare Starter prose
falls back to the module title/name; pg_database templates to
<org>_test_<module>; the initializer test skips on initialized checkouts so
make verify works after init.

Checks: check-module now requires the vite process.env define shim (the fleet
pattern), requires shell-import-map packages to stay external, enforces the
:host height + overflow scroll contract for page components (shell surface
ancestors hide overflow and silently clip non-scrolling pages), and scans
leftovers with identity-aware lookaheads so starter-* module names pass.

Harness: depends on wippy/security so host-managed services (bootloader,
migration) resolve their wippy.security:process scope under strict security
mode; test targets in Makefile and make.ps1 fail on 'No tests found' (the
runner exits 0 on empty discovery); strict-mode runner support arrives with
wippyai/runtime#558 + wippy/test 0.4.17 — until a CLI release carries #558,
CI stays pinned to the last-good version.

Frontend: @wippy-fe pinned 0.0.53, define shim and full external roster in
vite config (0.0.53 pulls pinia transitively; a bundled copy breaks on
process.env in the shadow DOM).

Blocks: canonical kickside.block/v1 example (block.write_log + function
implementation) with a wiring test, so modules ship composable capability.

Docs: AGENTS.md gains the live hub wiki + wippy.ai doc endpoints and a
reuse-before-you-build discipline (discover hub/kickside subsystems before
implementing); dev-loop documents the two-phase bootstrap and the
user_security_scope overlay binding; publish excludes wippy.lock.
@wolfy-j
wolfy-j merged commit b5a56f3 into main Aug 8, 2026
4 checks passed
@wolfy-j
wolfy-j deleted the feat/terminal-command-security branch August 8, 2026 23:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant