This commit is contained in:
@@ -16,11 +16,12 @@ mutator remains behind the verified lease gate.
|
||||
- **Claude:** invoke only this direct command shape (no shell composition):
|
||||
|
||||
```bash
|
||||
python3 /home/hermes/.config/mosaic/tools/lease-broker/recover-context.py begin --construction /absolute/path/to/mosaic-context-refresh-construction.json --compaction-epoch 0 --request-epoch 0
|
||||
python3 /absolute/path/to/mosaic/tools/lease-broker/recover-context.py begin --construction /absolute/path/to/mosaic-context-refresh-construction.json --compaction-epoch 0 --request-epoch 0
|
||||
```
|
||||
|
||||
This is a literal argv template: replace the construction path with a literal absolute path and
|
||||
replace each epoch with literal decimal digits. Do not use variables, quoting, globs, redirects,
|
||||
This is a literal argv template: replace the recover-context.py path and construction JSON path
|
||||
with the literal absolute paths for your install, then replace each epoch with literal decimal
|
||||
digits. Do not use variables, quoting, globs, redirects,
|
||||
shell operators, substitutions, or line continuations. Claude's all-tools gate maps only this
|
||||
fully literal recovery shape to `mosaic_context_recover`; ordinary `Bash` remains gated.
|
||||
|
||||
@@ -40,7 +41,7 @@ mutator remains behind the verified lease gate.
|
||||
`after_provider_response`).
|
||||
|
||||
Then invoke completion with the same adapter form: Claude runs
|
||||
`python3 /home/hermes/.config/mosaic/tools/lease-broker/recover-context.py complete`; Pi calls
|
||||
`python3 /absolute/path/to/mosaic/tools/lease-broker/recover-context.py complete`; Pi calls
|
||||
`mosaic_context_recover` with `phase: "complete"`. Completion supplies no receipt or challenge
|
||||
argument. The broker observes the exact latest assistant entry, commits evidence, consumes its own
|
||||
fresh challenge, and promotes VERIFIED last. If observation is absent, malformed, stale, or
|
||||
|
||||
@@ -45,12 +45,12 @@ class FrameworkSkillPortabilityTest(unittest.TestCase):
|
||||
self.assertIn(CONSTRUCTION_PLACEHOLDER, source)
|
||||
resolved_recovery = "/opt/mosaic/tools/lease-broker/recover-context.py"
|
||||
resolved_construction = "/opt/mosaic/recovery/construction.json"
|
||||
command = (
|
||||
source.replace(RECOVERY_PLACEHOLDER, resolved_recovery)
|
||||
.replace(CONSTRUCTION_PLACEHOLDER, resolved_construction)
|
||||
.split("```bash\n", 1)[1]
|
||||
.split("\n```", 1)[0]
|
||||
rendered = source.replace(RECOVERY_PLACEHOLDER, resolved_recovery).replace(
|
||||
CONSTRUCTION_PLACEHOLDER, resolved_construction
|
||||
)
|
||||
match = re.search(r"```bash\s*\n\s*(.*?)\n\s*```", rendered, flags=re.DOTALL)
|
||||
self.assertIsNotNone(match)
|
||||
command = match.group(1) if match is not None else ""
|
||||
self.assertEqual(
|
||||
GATE.recovery_invocation_name(
|
||||
{"tool_name": "Bash", "tool_input": {"command": command}},
|
||||
|
||||
@@ -10,6 +10,7 @@ from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import socket
|
||||
import subprocess
|
||||
import sys
|
||||
@@ -156,19 +157,19 @@ class ClaudeRecoveryGateAdversarialTest(unittest.TestCase):
|
||||
|
||||
def test_canonical_literal_and_shipped_skill_invocation_are_ungated(self) -> None:
|
||||
self.assertEqual(self.gate(self.canonical).returncode, 0)
|
||||
shipped = (
|
||||
"python3 /home/hermes/.config/mosaic/tools/lease-broker/recover-context.py begin "
|
||||
"--construction /absolute/path/to/mosaic-context-refresh-construction.json "
|
||||
"--compaction-epoch 0 --request-epoch 0"
|
||||
)
|
||||
self.assertIn(shipped, SKILL.read_text(encoding="utf-8"))
|
||||
self.assertEqual(
|
||||
self.gate(
|
||||
shipped,
|
||||
"/home/hermes/.config/mosaic/tools/lease-broker/recover-context.py",
|
||||
).returncode,
|
||||
0,
|
||||
source = SKILL.read_text(encoding="utf-8")
|
||||
recovery_placeholder = "/absolute/path/to/mosaic/tools/lease-broker/recover-context.py"
|
||||
construction_placeholder = "/absolute/path/to/mosaic-context-refresh-construction.json"
|
||||
self.assertIn(recovery_placeholder, source)
|
||||
self.assertIn(construction_placeholder, source)
|
||||
resolved_recovery = "/opt/mosaic/tools/lease-broker/recover-context.py"
|
||||
rendered = source.replace(recovery_placeholder, resolved_recovery).replace(
|
||||
construction_placeholder, "/opt/mosaic/recovery/construction.json"
|
||||
)
|
||||
match = re.search(r"```bash\s*\n\s*(.*?)\n\s*```", rendered, flags=re.DOTALL)
|
||||
self.assertIsNotNone(match)
|
||||
shipped = match.group(1) if match is not None else ""
|
||||
self.assertEqual(self.gate(shipped, resolved_recovery).returncode, 0)
|
||||
|
||||
def test_every_shell_active_vector_in_every_argv_position_falls_through_to_bash_deny(self) -> None:
|
||||
positions = (
|
||||
|
||||
Reference in New Issue
Block a user