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):
|
- **Claude:** invoke only this direct command shape (no shell composition):
|
||||||
|
|
||||||
```bash
|
```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
|
This is a literal argv template: replace the recover-context.py path and construction JSON path
|
||||||
replace each epoch with literal decimal digits. Do not use variables, quoting, globs, redirects,
|
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
|
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.
|
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`).
|
`after_provider_response`).
|
||||||
|
|
||||||
Then invoke completion with the same adapter form: Claude runs
|
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
|
`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
|
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
|
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)
|
self.assertIn(CONSTRUCTION_PLACEHOLDER, source)
|
||||||
resolved_recovery = "/opt/mosaic/tools/lease-broker/recover-context.py"
|
resolved_recovery = "/opt/mosaic/tools/lease-broker/recover-context.py"
|
||||||
resolved_construction = "/opt/mosaic/recovery/construction.json"
|
resolved_construction = "/opt/mosaic/recovery/construction.json"
|
||||||
command = (
|
rendered = source.replace(RECOVERY_PLACEHOLDER, resolved_recovery).replace(
|
||||||
source.replace(RECOVERY_PLACEHOLDER, resolved_recovery)
|
CONSTRUCTION_PLACEHOLDER, resolved_construction
|
||||||
.replace(CONSTRUCTION_PLACEHOLDER, resolved_construction)
|
|
||||||
.split("```bash\n", 1)[1]
|
|
||||||
.split("\n```", 1)[0]
|
|
||||||
)
|
)
|
||||||
|
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(
|
self.assertEqual(
|
||||||
GATE.recovery_invocation_name(
|
GATE.recovery_invocation_name(
|
||||||
{"tool_name": "Bash", "tool_input": {"command": command}},
|
{"tool_name": "Bash", "tool_input": {"command": command}},
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import socket
|
import socket
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
@@ -156,19 +157,19 @@ class ClaudeRecoveryGateAdversarialTest(unittest.TestCase):
|
|||||||
|
|
||||||
def test_canonical_literal_and_shipped_skill_invocation_are_ungated(self) -> None:
|
def test_canonical_literal_and_shipped_skill_invocation_are_ungated(self) -> None:
|
||||||
self.assertEqual(self.gate(self.canonical).returncode, 0)
|
self.assertEqual(self.gate(self.canonical).returncode, 0)
|
||||||
shipped = (
|
source = SKILL.read_text(encoding="utf-8")
|
||||||
"python3 /home/hermes/.config/mosaic/tools/lease-broker/recover-context.py begin "
|
recovery_placeholder = "/absolute/path/to/mosaic/tools/lease-broker/recover-context.py"
|
||||||
"--construction /absolute/path/to/mosaic-context-refresh-construction.json "
|
construction_placeholder = "/absolute/path/to/mosaic-context-refresh-construction.json"
|
||||||
"--compaction-epoch 0 --request-epoch 0"
|
self.assertIn(recovery_placeholder, source)
|
||||||
)
|
self.assertIn(construction_placeholder, source)
|
||||||
self.assertIn(shipped, SKILL.read_text(encoding="utf-8"))
|
resolved_recovery = "/opt/mosaic/tools/lease-broker/recover-context.py"
|
||||||
self.assertEqual(
|
rendered = source.replace(recovery_placeholder, resolved_recovery).replace(
|
||||||
self.gate(
|
construction_placeholder, "/opt/mosaic/recovery/construction.json"
|
||||||
shipped,
|
|
||||||
"/home/hermes/.config/mosaic/tools/lease-broker/recover-context.py",
|
|
||||||
).returncode,
|
|
||||||
0,
|
|
||||||
)
|
)
|
||||||
|
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:
|
def test_every_shell_active_vector_in_every_argv_position_falls_through_to_bash_deny(self) -> None:
|
||||||
positions = (
|
positions = (
|
||||||
|
|||||||
Reference in New Issue
Block a user