fix(#829): harden runtime launch guard against marker evasions
All checks were successful
ci/woodpecker/pr/ci Pipeline was successful

This commit is contained in:
ms-lead-reviewer
2026-07-18 00:17:50 -05:00
parent 64efdb4460
commit 1eb77c17f3
11 changed files with 316 additions and 62 deletions

View File

@@ -37,9 +37,11 @@ The executable submits the runtime's actual tool name to `authorize_tool`. Missi
## Runtime-launch choke-point and permanent guard
Every repository-owned Claude/Pi launch entry converges on `launch-runtime.py`, either directly or through `mosaic``execLeaseGatedRuntime`. PRDY init/update and QA remediation invoke the wrapper directly so their existing prompts, dangerous-permission flags, working directory, and environment survive without skipping broker registration. `@mosaicstack/coord` rewrites direct Claude commands to `mosaic claude` and rejects unknown custom Claude launchers.
Every repository-owned Claude/Pi launch entry converges on `launch-runtime.py`, either directly or through `mosaic``execLeaseGatedRuntime`. PRDY init/update and QA remediation invoke the wrapper directly so their existing prompts, dangerous-permission behavior, working directory, and environment survive without skipping broker registration. The raw Claude `--dangerously-skip-permissions` primitive is owned only by `launch-runtime.py`; callers request semantic `--dangerous` mode, and the wrapper validates Claude before injecting the primitive. `@mosaicstack/coord` rewrites direct Claude commands to `mosaic claude` and rejects unknown custom Claude launchers.
`check-runtime-launches.py` is the permanent completeness guard. It scans production shell, TypeScript/JavaScript, Python, and data launch definitions under `packages/`, `apps/`, `plugins/`, and `tools/`; direct literal, absolute-path, process-API, and dynamic runtime launches fail. It is mandatory in `@mosaicstack/mosaic`'s test script, so root CI fails when a future entry does not name the wrapper, `execLeaseGatedRuntime`, or a gated `mosaic` launch. Synthetic scanner tests prove representative bypass forms are rejected, while real-socket tests prove PRDY init/update and QA receive broker sessions and deny an unverified mutator.
`check-runtime-launches.py` is the permanent completeness guard. It scans production shell, TypeScript/JavaScript, Python, and data launch definitions under `packages/`, `apps/`, `plugins/`, and `tools/`; direct literal, absolute-path, process-API, dynamic, command-substitution, `eval`, and variable-execution runtime launches fail. Shell comments are stripped with quote awareness, wrapper prefixes are tokenized with `shlex`, and only an invocation in command position with `--runtime` before the command separator is gated. A direct command always wins over an inert marker on the same line. Independently, the raw dangerous primitive anywhere outside the choke-point is RED.
Both checks are load-bearing: command-position analysis covers consequential launches that do not use dangerous mode, while primitive ownership cannot be fooled by a comment or marker string for dangerous mode. The guard is mandatory in `@mosaicstack/mosaic`'s test script, so root CI fails on a future bypass. Permanent regressions cover the original add-ungated effectiveness probe, comments, strings, assignments, heredocs, continuations, command chains, command substitution, `eval`, and variable execution; real-socket tests prove PRDY init/update and QA receive broker sessions and deny an unverified mutator.
The live inventory is emitted by: