fix(lease): constrain read-only tool carve-outs
This commit is contained in:
@@ -50,8 +50,8 @@ LEASE_PENDING: Final = "PENDING_VERIFICATION"
|
||||
LEASE_PENDING_PROMOTION: Final = "PENDING_PROMOTION"
|
||||
LEASE_VERIFIED: Final = "VERIFIED"
|
||||
READ_ONLY_TOOLS: Final = {
|
||||
"claude": frozenset({"Read", "Grep", "Glob", "Ls", "Find"}),
|
||||
"pi": frozenset({"read", "grep", "find", "ls"}),
|
||||
"claude": frozenset({"Read", "Grep", "Glob"}),
|
||||
"pi": frozenset({"read", "ls"}),
|
||||
}
|
||||
RECOVERY_TOOL: Final = "mosaic_context_recover"
|
||||
|
||||
|
||||
@@ -37,22 +37,20 @@ READ_ONLY_TOOLS = daemon.READ_ONLY_TOOLS
|
||||
# mcp__<server>__<tool>, so they cannot replace these bare identities.
|
||||
CLAUDE_PROVEN_READ_ONLY_TOOLS: Final = frozenset({"Read", "Grep", "Glob"})
|
||||
|
||||
# W-C owns removal of these known-dead names from daemon.py. This pin is
|
||||
# deliberately two-sided: until W-C lands, each name must remain in the live
|
||||
# carve-out and absent from the installed/proven set. W-C must delete the pin in
|
||||
# the same commit that removes the daemon entries, or this suite turns red.
|
||||
KNOWN_DEAD_CLAUDE: Final = frozenset({"Ls", "Find"})
|
||||
|
||||
# W-B measured Pi 0.84.1 through getAllTools(), observed every tool_call name,
|
||||
# and cross-checked dist/core/tools/index.js:18. Keep the mutating names here so
|
||||
# a runtime registry change forces the security classification to be revisited.
|
||||
# and cross-checked dist/core/tools/index.js:18. Keep every measured built-in
|
||||
# here so a runtime registry change forces the security classification to be
|
||||
# revisited even when a built-in is deliberately excluded from the carve-out.
|
||||
PI_VERSION: Final = "0.84.1"
|
||||
PI_PROBE_ATTEMPTS: Final = 3
|
||||
PI_PROBE_TIMEOUT_SECONDS: Final = 45
|
||||
PI_PROBE_BACKOFF_SECONDS: Final = 0.25
|
||||
PI_PROVEN_READ_ONLY_TOOLS: Final = frozenset({"read", "grep", "find", "ls"})
|
||||
PI_PROVEN_READ_ONLY_TOOLS: Final = frozenset({"read", "ls"})
|
||||
PI_SUBPROCESS_TOOLS: Final = frozenset({"grep", "find"})
|
||||
PI_MUTATING_TOOLS: Final = frozenset({"bash", "edit", "write"})
|
||||
PI_MEASURED_BUILTINS: Final = PI_PROVEN_READ_ONLY_TOOLS | PI_MUTATING_TOOLS
|
||||
PI_MEASURED_BUILTINS: Final = (
|
||||
PI_PROVEN_READ_ONLY_TOOLS | PI_SUBPROCESS_TOOLS | PI_MUTATING_TOOLS
|
||||
)
|
||||
|
||||
# Pi 0.84.1 built-ins individually proven incapable of subprocess execution or
|
||||
# filesystem writes on their default path:
|
||||
@@ -177,25 +175,16 @@ class InvariantRTest(unittest.TestCase):
|
||||
def test_live_carve_out_has_only_supported_runtimes(self) -> None:
|
||||
self.assertEqual(set(READ_ONLY_TOOLS), {"claude", "pi"})
|
||||
|
||||
def test_claude_carve_out_is_registered_proven_and_pinned_for_w_c(self) -> None:
|
||||
def test_claude_carve_out_is_registered_and_proven(self) -> None:
|
||||
carve_out = set(READ_ONLY_TOOLS["claude"])
|
||||
falsifier = os.environ.get(CLAUDE_EXTRA_TOOL_ENV)
|
||||
if falsifier:
|
||||
carve_out.add(falsifier)
|
||||
|
||||
self.assertLessEqual(
|
||||
KNOWN_DEAD_CLAUDE,
|
||||
carve_out,
|
||||
"W-C changed the live Claude carve-out but left its known-defect pin stale",
|
||||
)
|
||||
self.assertTrue(
|
||||
KNOWN_DEAD_CLAUDE.isdisjoint(CLAUDE_PROVEN_READ_ONLY_TOOLS),
|
||||
"a W-C dead-name pin unexpectedly exists in Claude's installed/proven tool set",
|
||||
)
|
||||
self.assertEqual(
|
||||
carve_out - KNOWN_DEAD_CLAUDE,
|
||||
carve_out,
|
||||
set(CLAUDE_PROVEN_READ_ONLY_TOOLS),
|
||||
"every unpinned Claude carve-out must exist and be in the exact proven read-only allow-list",
|
||||
"every Claude carve-out must exist and be in the exact proven read-only allow-list",
|
||||
)
|
||||
|
||||
def test_pi_carve_out_has_no_exec_or_write_capability(self) -> None:
|
||||
|
||||
Reference in New Issue
Block a user