test(#829): extend guard evasion matrix and primitive invariant
This commit is contained in:
@@ -108,3 +108,5 @@ Carried authority chain also verified/read for the locked T-B gate contract: SPE
|
|||||||
- Reproduced RIDER E exactly at head `1792b7934dda7eff64a207b8b0edb9c460d4164b`: a temporary production file containing `exec claude --dangerously-skip-permissions "terra-r3" # launch-runtime.py` made the guard exit 0 and report `1 gated/1 total`.
|
- Reproduced RIDER E exactly at head `1792b7934dda7eff64a207b8b0edb9c460d4164b`: a temporary production file containing `exec claude --dangerously-skip-permissions "terra-r3" # launch-runtime.py` made the guard exit 0 and report `1 gated/1 total`.
|
||||||
- Root cause: classification searched the unparsed physical line, and the broad gated regex treated any `launch-runtime.py` substring—including comments and inert arguments—as an invocation before the direct-launch finding was evaluated.
|
- Root cause: classification searched the unparsed physical line, and the broad gated regex treated any `launch-runtime.py` substring—including comments and inert arguments—as an invocation before the direct-launch finding was evaluated.
|
||||||
- Round-4 plan: add permanent RED cases for the exact comment evasion plus string-argument, echo, and unrelated-variable marker evasions; tokenize/strip comments by launcher syntax; recognize only command-position wrapper invocations with `--runtime` and the gated command separator; retain 14/14 real inventory; rerun guard coverage and all gates fresh.
|
- Round-4 plan: add permanent RED cases for the exact comment evasion plus string-argument, echo, and unrelated-variable marker evasions; tokenize/strip comments by launcher syntax; recognize only command-position wrapper invocations with `--runtime` and the gated command separator; retain 14/14 real inventory; rerun guard coverage and all gates fresh.
|
||||||
|
- Mos Rider A/B decision: adopt **both** defenses. Command-position parsing remains necessary because a normal `claude -p` launch is consequential even without the dangerous flag. The primitive-location invariant is more mechanically robust for dangerous mode because it does not need to recognize a wrapper marker at all. Move the sole raw `--dangerously-skip-permissions` literal into `launch-runtime.py`; any occurrence in another production file is independently RED.
|
||||||
|
- Rider-A RED matrix adds heredoc body, backslash continuation, non-first `;`/`&&`/pipe commands, command substitution, `eval`, and variable-execution indirection in addition to the six marker/comment evasions. Before the augmented implementation, primitive ownership, command substitution, `eval`, variable execution, and the preserved 14-site inventory all fail.
|
||||||
|
|||||||
@@ -48,6 +48,14 @@ class RuntimeLaunchGuardTest(unittest.TestCase):
|
|||||||
"marker-argument.sh": 'exec claude --dangerously-skip-permissions "launch-runtime.py"\n',
|
"marker-argument.sh": 'exec claude --dangerously-skip-permissions "launch-runtime.py"\n',
|
||||||
"marker-echo.sh": 'exec claude --dangerously-skip-permissions "prompt"; echo launch-runtime.py\n',
|
"marker-echo.sh": 'exec claude --dangerously-skip-permissions "prompt"; echo launch-runtime.py\n',
|
||||||
"marker-variable.sh": 'marker=launch-runtime.py; exec claude --dangerously-skip-permissions "prompt"\n',
|
"marker-variable.sh": 'marker=launch-runtime.py; exec claude --dangerously-skip-permissions "prompt"\n',
|
||||||
|
"heredoc.sh": "cat <<'EOF'\nexec claude --dangerously-skip-permissions prompt # launch-runtime.py\nEOF\n",
|
||||||
|
"continued.sh": "exec \\\n claude --dangerously-skip-permissions prompt # launch-runtime.py\n",
|
||||||
|
"chain-semicolon.sh": "true; claude -p prompt\n",
|
||||||
|
"chain-and.sh": "true && claude -p prompt\n",
|
||||||
|
"chain-pipe.sh": "printf input | claude -p prompt\n",
|
||||||
|
"command-substitution.sh": "output=$(claude -p prompt)\n",
|
||||||
|
"eval.sh": "launcher='claude -p prompt'\neval \"$launcher\"\n",
|
||||||
|
"variable-exec.sh": "launcher=claude\n\"$launcher\" -p prompt\n",
|
||||||
}
|
}
|
||||||
for filename, source in cases.items():
|
for filename, source in cases.items():
|
||||||
with self.subTest(filename=filename):
|
with self.subTest(filename=filename):
|
||||||
@@ -65,6 +73,14 @@ class RuntimeLaunchGuardTest(unittest.TestCase):
|
|||||||
with self.subTest(filename=filename):
|
with self.subTest(filename=filename):
|
||||||
self.assertEqual(GUARD.scan_text(Path(filename), source), [])
|
self.assertEqual(GUARD.scan_text(Path(filename), source), [])
|
||||||
|
|
||||||
|
def test_dangerous_primitive_is_owned_only_by_the_choke_point(self) -> None:
|
||||||
|
primitive = "--dangerously-skip-permissions"
|
||||||
|
self.assertNotEqual(GUARD.scan_text(Path("caller.ts"), f"args = ['{primitive}'];\n"), [])
|
||||||
|
self.assertEqual(
|
||||||
|
GUARD.scan_text(Path("framework/tools/lease-broker/launch-runtime.py"), f'FLAG = "{primitive}"\n'),
|
||||||
|
[],
|
||||||
|
)
|
||||||
|
|
||||||
def test_repository_has_no_ungated_consequential_runtime_launch(self) -> None:
|
def test_repository_has_no_ungated_consequential_runtime_launch(self) -> None:
|
||||||
violations = GUARD.scan_repository(REPO_ROOT)
|
violations = GUARD.scan_repository(REPO_ROOT)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
@@ -72,6 +88,9 @@ class RuntimeLaunchGuardTest(unittest.TestCase):
|
|||||||
[],
|
[],
|
||||||
"\n".join(GUARD.format_violation(violation) for violation in violations),
|
"\n".join(GUARD.format_violation(violation) for violation in violations),
|
||||||
)
|
)
|
||||||
|
inventory = GUARD.inventory_repository(REPO_ROOT)
|
||||||
|
self.assertEqual(len(inventory), 14)
|
||||||
|
self.assertTrue(all(site.classification == "gated" for site in inventory))
|
||||||
|
|
||||||
def test_repository_walk_skips_tests_build_outputs_and_reports_unscannable_source(self) -> None:
|
def test_repository_walk_skips_tests_build_outputs_and_reports_unscannable_source(self) -> None:
|
||||||
with tempfile.TemporaryDirectory() as directory:
|
with tempfile.TemporaryDirectory() as directory:
|
||||||
|
|||||||
Reference in New Issue
Block a user