Repository navigation
cleanup: close #134 Low findings in inventory, snapshots and worktree checks - #181
Merged
Merged
Conversation
Every prompt starts a new route, so binding protected-path grants to the route voided them on each user message and forced a new grant for the same edit again and again. A branch-bound grant is already held to the repository, branch ref, anchor ancestry, exact files and TTL, so it no longer checks the route. Production and external-write grants keep their exact route, HEAD and tree binding. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR
The security review found that change_id is now the only task binding of a branch-bound grant and that no test pinned it, nor the protected-path scope guard. Add a test for each; both mutants are now killed. Update the has_valid_approval docstring. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR
Skipping the route broke session isolation: a grant issued in one session also served another session in the same worktree (tests/test_control_plane_sessions failed on CI). A protected-path grant now records its session and checks that instead of the route, so later prompts of the same session keep it and another session never gets it. Without a known session on both sides the exact route is still required. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR
A session without its own route pointer reads the shared route of another session, and 'manual' is not a session. The check now uses the caller's bound session and skips the route only when caller, route and grant name the same session. getzilla_approve.py binds CLAUDE_CODE_SESSION_ID. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR
… to date - QUICKSTART: launcher, runtime evidence without report commits, route reconcile, review snapshots, light lane, and a disk cleanup section. - START_HERE and REFERENCE: current main a45fbdd, correct v2.3.0 link, continuation at issue #134; REFERENCE lists all getzilla commands. - PROJECT_STATE: current_continuation moves to issue #134; the finished PR #79 contour is kept as historical_pr79_continuation. - CHANGELOG: 2.3.1 lists the work merged since 2026-10-21 (#121-#179). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR
A Commands section lists all launcher commands by task, with their main options. The source line names what 2.3.1 adds since v2.3.0, and the file map says where review copies live and how they are removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR
history takes a snapshot file, approve needs --reason, --add-reviewer works with --reconcile, getzilla test falls back to serial unittest without pytest-xdist, report overhead is per profile, and the state record counts the merged PRs from #114. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR
…tree checks - Inventory: a linked .getzilla or runtime folder is not read; one entry budget covers the copy search and all copy sizes; an unreadable folder, a linked copy root or a cut size makes the report incomplete. - Review snapshots: the parent-folder refusal has its own message, and the module says a snapshot holds committed content only. - Tests pin the guards that mutants survived before: annotated tag peel, marker removal after a failed worktree add, the main-worktree base, the marker schema, the 0700 mode, unregistered folders, the refs/worktree check, a failed reflog read, the 2 s margins. - getzilla status answers --help; a test runs --help for every command. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
…ctly the budget Review of #181: the copy folder listing was counted by the search and again by its size, and a search that used the full budget reported itself incomplete. Tests pin both boundaries. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR
Dimkox
pushed a commit
that referenced
this pull request
Oct 24, 2026
Dimkox
added a commit
that referenced
this pull request
Oct 24, 2026
* grants: a new route keeps a branch-bound protected-path grant Every prompt starts a new route, so binding protected-path grants to the route voided them on each user message and forced a new grant for the same edit again and again. A branch-bound grant is already held to the repository, branch ref, anchor ancestry, exact files and TTL, so it no longer checks the route. Production and external-write grants keep their exact route, HEAD and tree binding. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * grants: pin change_id and the scope guard in tests The security review found that change_id is now the only task binding of a branch-bound grant and that no test pinned it, nor the protected-path scope guard. Add a test for each; both mutants are now killed. Update the has_valid_approval docstring. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * grants: bind branch-bound grants to the session, not the route Skipping the route broke session isolation: a grant issued in one session also served another session in the same worktree (tests/test_control_plane_sessions failed on CI). A protected-path grant now records its session and checks that instead of the route, so later prompts of the same session keep it and another session never gets it. Without a known session on both sides the exact route is still required. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * Bind grant sessions to the caller, not the route A session without its own route pointer reads the shared route of another session, and 'manual' is not a session. The check now uses the caller's bound session and skips the route only when caller, route and grant name the same session. getzilla_approve.py binds CLAUDE_CODE_SESSION_ID. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * docs: bring QUICKSTART, START_HERE, REFERENCE, CHANGELOG and state up to date - QUICKSTART: launcher, runtime evidence without report commits, route reconcile, review snapshots, light lane, and a disk cleanup section. - START_HERE and REFERENCE: current main a45fbdd, correct v2.3.0 link, continuation at issue #134; REFERENCE lists all getzilla commands. - PROJECT_STATE: current_continuation moves to issue #134; the finished PR #79 contour is kept as historical_pr79_continuation. - CHANGELOG: 2.3.1 lists the work merged since 2026-10-21 (#121-#179). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * docs(readme): list every getzilla command and the current source state A Commands section lists all launcher commands by task, with their main options. The source line names what 2.3.1 adds since v2.3.0, and the file map says where review copies live and how they are removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * docs: fix command wording found in review of #180 history takes a snapshot file, approve needs --reason, --add-reviewer works with --reconcile, getzilla test falls back to serial unittest without pytest-xdist, report overhead is per profile, and the state record counts the merged PRs from #114. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * cleanup: close the #134 Low findings in inventory, snapshots and worktree checks - Inventory: a linked .getzilla or runtime folder is not read; one entry budget covers the copy search and all copy sizes; an unreadable folder, a linked copy root or a cut size makes the report incomplete. - Review snapshots: the parent-folder refusal has its own message, and the module says a snapshot holds committed content only. - Tests pin the guards that mutants survived before: annotated tag peel, marker removal after a failed worktree add, the main-worktree base, the marker schema, the 0700 mode, unregistered folders, the refs/worktree check, a failed reflog read, the 2 s margins. - getzilla status answers --help; a test runs --help for every command. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * cleanup: count each copy entry once and accept a search that uses exactly the budget Review of #181: the copy folder listing was counted by the search and again by its size, and a search that used the full budget reported itself incomplete. Tests pin both boundaries. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * contract: every Getzilla defect goes to a GitHub issue AGENTS.md now requires an issue in Dimkox/Getzilla for each defect in Getzilla itself, also one that was worked around: search first, no duplicates, Low findings into the collecting issue, no secrets or exploit commands, and an exact external-write grant first. Consumer projects get the same rule in the installed contract, with a ready issue text for the owner when filing upstream is not allowed. The delivery skill adds it as the last step of a task. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * contract: own-repository issues are in the L5 standing consent Review of #182: the new rule called issue writes an L5 process call while the L5 scope named only merge, tag and release. The owner asked for it, so the scope now covers the project's own GitHub issues; the checks-green condition stays on merge, tag and release. The search covers open and closed issues, the grant resource is named, consumer consent is recorded as an exact grant, and a test pins the rule. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * contract: issue grants follow the exact-HEAD binding; pin the secret bans Security review of #182: the rule said a tool grant lasts its TTL, but external-write grants stay bound to route, change, HEAD and tree. The test now also pins the bans on secrets and customer data. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR --------- Co-authored-by: Claude <noreply@anthropic.com>
Dimkox
added a commit
that referenced
this pull request
Oct 25, 2026
…t margin (#188) * grants: a new route keeps a branch-bound protected-path grant Every prompt starts a new route, so binding protected-path grants to the route voided them on each user message and forced a new grant for the same edit again and again. A branch-bound grant is already held to the repository, branch ref, anchor ancestry, exact files and TTL, so it no longer checks the route. Production and external-write grants keep their exact route, HEAD and tree binding. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * grants: pin change_id and the scope guard in tests The security review found that change_id is now the only task binding of a branch-bound grant and that no test pinned it, nor the protected-path scope guard. Add a test for each; both mutants are now killed. Update the has_valid_approval docstring. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * grants: bind branch-bound grants to the session, not the route Skipping the route broke session isolation: a grant issued in one session also served another session in the same worktree (tests/test_control_plane_sessions failed on CI). A protected-path grant now records its session and checks that instead of the route, so later prompts of the same session keep it and another session never gets it. Without a known session on both sides the exact route is still required. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * Bind grant sessions to the caller, not the route A session without its own route pointer reads the shared route of another session, and 'manual' is not a session. The check now uses the caller's bound session and skips the route only when caller, route and grant name the same session. getzilla_approve.py binds CLAUDE_CODE_SESSION_ID. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * docs: bring QUICKSTART, START_HERE, REFERENCE, CHANGELOG and state up to date - QUICKSTART: launcher, runtime evidence without report commits, route reconcile, review snapshots, light lane, and a disk cleanup section. - START_HERE and REFERENCE: current main a45fbdd, correct v2.3.0 link, continuation at issue #134; REFERENCE lists all getzilla commands. - PROJECT_STATE: current_continuation moves to issue #134; the finished PR #79 contour is kept as historical_pr79_continuation. - CHANGELOG: 2.3.1 lists the work merged since 2026-10-21 (#121-#179). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * docs(readme): list every getzilla command and the current source state A Commands section lists all launcher commands by task, with their main options. The source line names what 2.3.1 adds since v2.3.0, and the file map says where review copies live and how they are removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * docs: fix command wording found in review of #180 history takes a snapshot file, approve needs --reason, --add-reviewer works with --reconcile, getzilla test falls back to serial unittest without pytest-xdist, report overhead is per profile, and the state record counts the merged PRs from #114. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * cleanup: close the #134 Low findings in inventory, snapshots and worktree checks - Inventory: a linked .getzilla or runtime folder is not read; one entry budget covers the copy search and all copy sizes; an unreadable folder, a linked copy root or a cut size makes the report incomplete. - Review snapshots: the parent-folder refusal has its own message, and the module says a snapshot holds committed content only. - Tests pin the guards that mutants survived before: annotated tag peel, marker removal after a failed worktree add, the main-worktree base, the marker schema, the 0700 mode, unregistered folders, the refs/worktree check, a failed reflog read, the 2 s margins. - getzilla status answers --help; a test runs --help for every command. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * cleanup: count each copy entry once and accept a search that uses exactly the budget Review of #181: the copy folder listing was counted by the search and again by its size, and a search that used the full budget reported itself incomplete. Tests pin both boundaries. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * contract: every Getzilla defect goes to a GitHub issue AGENTS.md now requires an issue in Dimkox/Getzilla for each defect in Getzilla itself, also one that was worked around: search first, no duplicates, Low findings into the collecting issue, no secrets or exploit commands, and an exact external-write grant first. Consumer projects get the same rule in the installed contract, with a ready issue text for the owner when filing upstream is not allowed. The delivery skill adds it as the last step of a task. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * contract: own-repository issues are in the L5 standing consent Review of #182: the new rule called issue writes an L5 process call while the L5 scope named only merge, tag and release. The owner asked for it, so the scope now covers the project's own GitHub issues; the checks-green condition stays on merge, tag and release. The search covers open and closed issues, the grant resource is named, consumer consent is recorded as an exact grant, and a test pins the rule. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * contract: issue grants follow the exact-HEAD binding; pin the secret bans Security review of #182: the rule said a tool grant lasts its TTL, but external-write grants stay bound to route, change, HEAD and tree. The test now also pins the bans on secrets and customer data. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * tests: give the Node transparency adapter tests room on loaded runners (#187) test_node_adapter_behavior timed out after 10 s on a busy public linux runner while it only checks adapter behavior. Both Node calls now allow 60 s; the neighbouring stubborn-child test already allows 45 s. Fixes #187. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * workflow: harness notices keep the route; spec and transition use the package (#185, #186) - A prompt made only of <task-notification> or <system-reminder> envelopes keeps the active route like a short reply, and never creates a route. Text next to an envelope is a normal prompt. - getzilla spec generate/validate --change-id use the package folder that change start created (the runtime one; legacy tracked packages stay readable), so no stray file lands in engineering/changes. - getzilla change transition answers a refused move with exit 2 and the allowed next states, not a traceback. Fixes #185. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * workflow: a notice skips routing only when no route exists (#188 review) Review of #188: a notice next to a route of another session, or a closed route, built no route, so the session fell back to that route. Such a route is now replaced as before; the no-route rule applies only when no route exists at all. The transition hint names allowed states only for an invalid move, not for a gate refusal. Tests cover both cases and envelope edge forms (zero-width tail, attributes, case, crossed tags). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR --------- Co-authored-by: Claude <noreply@anthropic.com>
Dimkox
added a commit
that referenced
this pull request
Oct 25, 2026
… session (#189) * grants: a new route keeps a branch-bound protected-path grant Every prompt starts a new route, so binding protected-path grants to the route voided them on each user message and forced a new grant for the same edit again and again. A branch-bound grant is already held to the repository, branch ref, anchor ancestry, exact files and TTL, so it no longer checks the route. Production and external-write grants keep their exact route, HEAD and tree binding. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * grants: pin change_id and the scope guard in tests The security review found that change_id is now the only task binding of a branch-bound grant and that no test pinned it, nor the protected-path scope guard. Add a test for each; both mutants are now killed. Update the has_valid_approval docstring. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * grants: bind branch-bound grants to the session, not the route Skipping the route broke session isolation: a grant issued in one session also served another session in the same worktree (tests/test_control_plane_sessions failed on CI). A protected-path grant now records its session and checks that instead of the route, so later prompts of the same session keep it and another session never gets it. Without a known session on both sides the exact route is still required. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * Bind grant sessions to the caller, not the route A session without its own route pointer reads the shared route of another session, and 'manual' is not a session. The check now uses the caller's bound session and skips the route only when caller, route and grant name the same session. getzilla_approve.py binds CLAUDE_CODE_SESSION_ID. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * docs: bring QUICKSTART, START_HERE, REFERENCE, CHANGELOG and state up to date - QUICKSTART: launcher, runtime evidence without report commits, route reconcile, review snapshots, light lane, and a disk cleanup section. - START_HERE and REFERENCE: current main a45fbdd, correct v2.3.0 link, continuation at issue #134; REFERENCE lists all getzilla commands. - PROJECT_STATE: current_continuation moves to issue #134; the finished PR #79 contour is kept as historical_pr79_continuation. - CHANGELOG: 2.3.1 lists the work merged since 2026-10-21 (#121-#179). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * docs(readme): list every getzilla command and the current source state A Commands section lists all launcher commands by task, with their main options. The source line names what 2.3.1 adds since v2.3.0, and the file map says where review copies live and how they are removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * docs: fix command wording found in review of #180 history takes a snapshot file, approve needs --reason, --add-reviewer works with --reconcile, getzilla test falls back to serial unittest without pytest-xdist, report overhead is per profile, and the state record counts the merged PRs from #114. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * cleanup: close the #134 Low findings in inventory, snapshots and worktree checks - Inventory: a linked .getzilla or runtime folder is not read; one entry budget covers the copy search and all copy sizes; an unreadable folder, a linked copy root or a cut size makes the report incomplete. - Review snapshots: the parent-folder refusal has its own message, and the module says a snapshot holds committed content only. - Tests pin the guards that mutants survived before: annotated tag peel, marker removal after a failed worktree add, the main-worktree base, the marker schema, the 0700 mode, unregistered folders, the refs/worktree check, a failed reflog read, the 2 s margins. - getzilla status answers --help; a test runs --help for every command. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * cleanup: count each copy entry once and accept a search that uses exactly the budget Review of #181: the copy folder listing was counted by the search and again by its size, and a search that used the full budget reported itself incomplete. Tests pin both boundaries. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * contract: every Getzilla defect goes to a GitHub issue AGENTS.md now requires an issue in Dimkox/Getzilla for each defect in Getzilla itself, also one that was worked around: search first, no duplicates, Low findings into the collecting issue, no secrets or exploit commands, and an exact external-write grant first. Consumer projects get the same rule in the installed contract, with a ready issue text for the owner when filing upstream is not allowed. The delivery skill adds it as the last step of a task. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * contract: own-repository issues are in the L5 standing consent Review of #182: the new rule called issue writes an L5 process call while the L5 scope named only merge, tag and release. The owner asked for it, so the scope now covers the project's own GitHub issues; the checks-green condition stays on merge, tag and release. The search covers open and closed issues, the grant resource is named, consumer consent is recorded as an exact grant, and a test pins the rule. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * contract: issue grants follow the exact-HEAD binding; pin the secret bans Security review of #182: the rule said a tool grant lasts its TTL, but external-write grants stay bound to route, change, HEAD and tree. The test now also pins the bans on secrets and customer data. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * tests: give the Node transparency adapter tests room on loaded runners (#187) test_node_adapter_behavior timed out after 10 s on a busy public linux runner while it only checks adapter behavior. Both Node calls now allow 60 s; the neighbouring stubborn-child test already allows 45 s. Fixes #187. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * workflow: harness notices keep the route; spec and transition use the package (#185, #186) - A prompt made only of <task-notification> or <system-reminder> envelopes keeps the active route like a short reply, and never creates a route. Text next to an envelope is a normal prompt. - getzilla spec generate/validate --change-id use the package folder that change start created (the runtime one; legacy tracked packages stay readable), so no stray file lands in engineering/changes. - getzilla change transition answers a refused move with exit 2 and the allowed next states, not a traceback. Fixes #185. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * workflow: a notice skips routing only when no route exists (#188 review) Review of #188: a notice next to a route of another session, or a closed route, built no route, so the session fell back to that route. Such a route is now replaced as before; the no-route rule applies only when no route exists at all. The transition hint names allowed states only for an invalid move, not for a gate refusal. Tests cover both cases and envelope edge forms (zero-width tail, attributes, case, crossed tags). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * fix: #134 slice B — runner verdicts, report escaping, protected-write session - run_named_tests and run_trust_tests use _run_directory, so a failed cleanup of the run folder (a locked file on Windows) no longer replaces the test verdict. - getzilla report prints journal route ids with control and format characters replaced by '?'. - getzilla protected-write binds the caller session like approve, so a session-bound grant follows its later routes on that path too. - Tests: cleanup error keeps both verdicts; hostile route id; the protected-write CLI with and without a session; the approve CLI GETZILLA_SESSION_ID fallback and CLAUDE_CODE_SESSION_ID precedence. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * fix: escape the report profile too; the cleanup test removes its folders (#189 review) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR --------- Co-authored-by: Claude <noreply@anthropic.com>
Dimkox
added a commit
that referenced
this pull request
Oct 25, 2026
* grants: a new route keeps a branch-bound protected-path grant Every prompt starts a new route, so binding protected-path grants to the route voided them on each user message and forced a new grant for the same edit again and again. A branch-bound grant is already held to the repository, branch ref, anchor ancestry, exact files and TTL, so it no longer checks the route. Production and external-write grants keep their exact route, HEAD and tree binding. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * grants: pin change_id and the scope guard in tests The security review found that change_id is now the only task binding of a branch-bound grant and that no test pinned it, nor the protected-path scope guard. Add a test for each; both mutants are now killed. Update the has_valid_approval docstring. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * grants: bind branch-bound grants to the session, not the route Skipping the route broke session isolation: a grant issued in one session also served another session in the same worktree (tests/test_control_plane_sessions failed on CI). A protected-path grant now records its session and checks that instead of the route, so later prompts of the same session keep it and another session never gets it. Without a known session on both sides the exact route is still required. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * Bind grant sessions to the caller, not the route A session without its own route pointer reads the shared route of another session, and 'manual' is not a session. The check now uses the caller's bound session and skips the route only when caller, route and grant name the same session. getzilla_approve.py binds CLAUDE_CODE_SESSION_ID. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * docs: bring QUICKSTART, START_HERE, REFERENCE, CHANGELOG and state up to date - QUICKSTART: launcher, runtime evidence without report commits, route reconcile, review snapshots, light lane, and a disk cleanup section. - START_HERE and REFERENCE: current main a45fbdd, correct v2.3.0 link, continuation at issue #134; REFERENCE lists all getzilla commands. - PROJECT_STATE: current_continuation moves to issue #134; the finished PR #79 contour is kept as historical_pr79_continuation. - CHANGELOG: 2.3.1 lists the work merged since 2026-10-21 (#121-#179). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * docs(readme): list every getzilla command and the current source state A Commands section lists all launcher commands by task, with their main options. The source line names what 2.3.1 adds since v2.3.0, and the file map says where review copies live and how they are removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * docs: fix command wording found in review of #180 history takes a snapshot file, approve needs --reason, --add-reviewer works with --reconcile, getzilla test falls back to serial unittest without pytest-xdist, report overhead is per profile, and the state record counts the merged PRs from #114. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * cleanup: close the #134 Low findings in inventory, snapshots and worktree checks - Inventory: a linked .getzilla or runtime folder is not read; one entry budget covers the copy search and all copy sizes; an unreadable folder, a linked copy root or a cut size makes the report incomplete. - Review snapshots: the parent-folder refusal has its own message, and the module says a snapshot holds committed content only. - Tests pin the guards that mutants survived before: annotated tag peel, marker removal after a failed worktree add, the main-worktree base, the marker schema, the 0700 mode, unregistered folders, the refs/worktree check, a failed reflog read, the 2 s margins. - getzilla status answers --help; a test runs --help for every command. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * cleanup: count each copy entry once and accept a search that uses exactly the budget Review of #181: the copy folder listing was counted by the search and again by its size, and a search that used the full budget reported itself incomplete. Tests pin both boundaries. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * contract: every Getzilla defect goes to a GitHub issue AGENTS.md now requires an issue in Dimkox/Getzilla for each defect in Getzilla itself, also one that was worked around: search first, no duplicates, Low findings into the collecting issue, no secrets or exploit commands, and an exact external-write grant first. Consumer projects get the same rule in the installed contract, with a ready issue text for the owner when filing upstream is not allowed. The delivery skill adds it as the last step of a task. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * contract: own-repository issues are in the L5 standing consent Review of #182: the new rule called issue writes an L5 process call while the L5 scope named only merge, tag and release. The owner asked for it, so the scope now covers the project's own GitHub issues; the checks-green condition stays on merge, tag and release. The search covers open and closed issues, the grant resource is named, consumer consent is recorded as an exact grant, and a test pins the rule. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * contract: issue grants follow the exact-HEAD binding; pin the secret bans Security review of #182: the rule said a tool grant lasts its TTL, but external-write grants stay bound to route, change, HEAD and tree. The test now also pins the bans on secrets and customer data. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * tests: give the Node transparency adapter tests room on loaded runners (#187) test_node_adapter_behavior timed out after 10 s on a busy public linux runner while it only checks adapter behavior. Both Node calls now allow 60 s; the neighbouring stubborn-child test already allows 45 s. Fixes #187. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * workflow: harness notices keep the route; spec and transition use the package (#185, #186) - A prompt made only of <task-notification> or <system-reminder> envelopes keeps the active route like a short reply, and never creates a route. Text next to an envelope is a normal prompt. - getzilla spec generate/validate --change-id use the package folder that change start created (the runtime one; legacy tracked packages stay readable), so no stray file lands in engineering/changes. - getzilla change transition answers a refused move with exit 2 and the allowed next states, not a traceback. Fixes #185. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * workflow: a notice skips routing only when no route exists (#188 review) Review of #188: a notice next to a route of another session, or a closed route, built no route, so the session fell back to that route. Such a route is now replaced as before; the no-route rule applies only when no route exists at all. The transition hint names allowed states only for an invalid move, not for a gate refusal. Tests cover both cases and envelope edge forms (zero-width tail, attributes, case, crossed tags). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * fix: #134 slice B — runner verdicts, report escaping, protected-write session - run_named_tests and run_trust_tests use _run_directory, so a failed cleanup of the run folder (a locked file on Windows) no longer replaces the test verdict. - getzilla report prints journal route ids with control and format characters replaced by '?'. - getzilla protected-write binds the caller session like approve, so a session-bound grant follows its later routes on that path too. - Tests: cleanup error keeps both verdicts; hostile route id; the protected-write CLI with and without a session; the approve CLI GETZILLA_SESSION_ID fallback and CLAUDE_CODE_SESSION_ID precedence. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * fix: escape the report profile too; the cleanup test removes its folders (#189 review) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * test(eu-ai-act): cover the deferred negative cases from #122 - accepted_by: missing, empty, short or non-string role; missing, empty, malformed or impossible date. - Matrix sources: ftp, gopher, file and mailto schemes and a URL without a host are refused. - Attestation identity: attestation_id, key_id and policy_digest missing, empty or of the wrong type are refused. - The verifier refusal uses a working executable inside the project, so only the location guard can stop it. - The first audit call uses the captured providers, never the engine loader. - An archive install (getzilla.zip, no inherited PYTHONPATH) finds the scaffold templates through STACK_DIR. Each test fails when its guard is removed (7 of 7 mutants killed). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR --------- Co-authored-by: Claude <noreply@anthropic.com>
Dimkox
added a commit
that referenced
this pull request
Oct 25, 2026
…#192) * grants: a new route keeps a branch-bound protected-path grant Every prompt starts a new route, so binding protected-path grants to the route voided them on each user message and forced a new grant for the same edit again and again. A branch-bound grant is already held to the repository, branch ref, anchor ancestry, exact files and TTL, so it no longer checks the route. Production and external-write grants keep their exact route, HEAD and tree binding. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * grants: pin change_id and the scope guard in tests The security review found that change_id is now the only task binding of a branch-bound grant and that no test pinned it, nor the protected-path scope guard. Add a test for each; both mutants are now killed. Update the has_valid_approval docstring. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * grants: bind branch-bound grants to the session, not the route Skipping the route broke session isolation: a grant issued in one session also served another session in the same worktree (tests/test_control_plane_sessions failed on CI). A protected-path grant now records its session and checks that instead of the route, so later prompts of the same session keep it and another session never gets it. Without a known session on both sides the exact route is still required. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * Bind grant sessions to the caller, not the route A session without its own route pointer reads the shared route of another session, and 'manual' is not a session. The check now uses the caller's bound session and skips the route only when caller, route and grant name the same session. getzilla_approve.py binds CLAUDE_CODE_SESSION_ID. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * docs: bring QUICKSTART, START_HERE, REFERENCE, CHANGELOG and state up to date - QUICKSTART: launcher, runtime evidence without report commits, route reconcile, review snapshots, light lane, and a disk cleanup section. - START_HERE and REFERENCE: current main a45fbdd, correct v2.3.0 link, continuation at issue #134; REFERENCE lists all getzilla commands. - PROJECT_STATE: current_continuation moves to issue #134; the finished PR #79 contour is kept as historical_pr79_continuation. - CHANGELOG: 2.3.1 lists the work merged since 2026-10-21 (#121-#179). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * docs(readme): list every getzilla command and the current source state A Commands section lists all launcher commands by task, with their main options. The source line names what 2.3.1 adds since v2.3.0, and the file map says where review copies live and how they are removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * docs: fix command wording found in review of #180 history takes a snapshot file, approve needs --reason, --add-reviewer works with --reconcile, getzilla test falls back to serial unittest without pytest-xdist, report overhead is per profile, and the state record counts the merged PRs from #114. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * cleanup: close the #134 Low findings in inventory, snapshots and worktree checks - Inventory: a linked .getzilla or runtime folder is not read; one entry budget covers the copy search and all copy sizes; an unreadable folder, a linked copy root or a cut size makes the report incomplete. - Review snapshots: the parent-folder refusal has its own message, and the module says a snapshot holds committed content only. - Tests pin the guards that mutants survived before: annotated tag peel, marker removal after a failed worktree add, the main-worktree base, the marker schema, the 0700 mode, unregistered folders, the refs/worktree check, a failed reflog read, the 2 s margins. - getzilla status answers --help; a test runs --help for every command. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * cleanup: count each copy entry once and accept a search that uses exactly the budget Review of #181: the copy folder listing was counted by the search and again by its size, and a search that used the full budget reported itself incomplete. Tests pin both boundaries. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * contract: every Getzilla defect goes to a GitHub issue AGENTS.md now requires an issue in Dimkox/Getzilla for each defect in Getzilla itself, also one that was worked around: search first, no duplicates, Low findings into the collecting issue, no secrets or exploit commands, and an exact external-write grant first. Consumer projects get the same rule in the installed contract, with a ready issue text for the owner when filing upstream is not allowed. The delivery skill adds it as the last step of a task. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * contract: own-repository issues are in the L5 standing consent Review of #182: the new rule called issue writes an L5 process call while the L5 scope named only merge, tag and release. The owner asked for it, so the scope now covers the project's own GitHub issues; the checks-green condition stays on merge, tag and release. The search covers open and closed issues, the grant resource is named, consumer consent is recorded as an exact grant, and a test pins the rule. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * contract: issue grants follow the exact-HEAD binding; pin the secret bans Security review of #182: the rule said a tool grant lasts its TTL, but external-write grants stay bound to route, change, HEAD and tree. The test now also pins the bans on secrets and customer data. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * tests: give the Node transparency adapter tests room on loaded runners (#187) test_node_adapter_behavior timed out after 10 s on a busy public linux runner while it only checks adapter behavior. Both Node calls now allow 60 s; the neighbouring stubborn-child test already allows 45 s. Fixes #187. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * workflow: harness notices keep the route; spec and transition use the package (#185, #186) - A prompt made only of <task-notification> or <system-reminder> envelopes keeps the active route like a short reply, and never creates a route. Text next to an envelope is a normal prompt. - getzilla spec generate/validate --change-id use the package folder that change start created (the runtime one; legacy tracked packages stay readable), so no stray file lands in engineering/changes. - getzilla change transition answers a refused move with exit 2 and the allowed next states, not a traceback. Fixes #185. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * workflow: a notice skips routing only when no route exists (#188 review) Review of #188: a notice next to a route of another session, or a closed route, built no route, so the session fell back to that route. Such a route is now replaced as before; the no-route rule applies only when no route exists at all. The transition hint names allowed states only for an invalid move, not for a gate refusal. Tests cover both cases and envelope edge forms (zero-width tail, attributes, case, crossed tags). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * fix: #134 slice B — runner verdicts, report escaping, protected-write session - run_named_tests and run_trust_tests use _run_directory, so a failed cleanup of the run folder (a locked file on Windows) no longer replaces the test verdict. - getzilla report prints journal route ids with control and format characters replaced by '?'. - getzilla protected-write binds the caller session like approve, so a session-bound grant follows its later routes on that path too. - Tests: cleanup error keeps both verdicts; hostile route id; the protected-write CLI with and without a session; the approve CLI GETZILLA_SESSION_ID fallback and CLAUDE_CODE_SESSION_ID precedence. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * fix: escape the report profile too; the cleanup test removes its folders (#189 review) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * test(eu-ai-act): cover the deferred negative cases from #122 - accepted_by: missing, empty, short or non-string role; missing, empty, malformed or impossible date. - Matrix sources: ftp, gopher, file and mailto schemes and a URL without a host are refused. - Attestation identity: attestation_id, key_id and policy_digest missing, empty or of the wrong type are refused. - The verifier refusal uses a working executable inside the project, so only the location guard can stop it. - The first audit call uses the captured providers, never the engine loader. - An archive install (getzilla.zip, no inherited PYTHONPATH) finds the scaffold templates through STACK_DIR. Each test fails when its guard is removed (7 of 7 mutants killed). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * fix(eu-ai-act): confirmation and review dates must be past YYYY-MM-DD (#191) date.fromisoformat on Python 3.11+ also accepts 20261020 and week dates such as 2026-W43-1, and str() let an integer through. A future date also passed as a human confirmation. - _iso_day accepts only a YYYY-MM-DD string. - A class confirmation, an exemption confirmation and a high-residual accepted_by refuse a date after the evaluation day. - A risk record's reviewed date uses the same parser and refuses a future date. Tests cover the basic, integer, week and future forms for each caller. 8 of 8 guard mutants are killed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR --------- Co-authored-by: Claude <noreply@anthropic.com>
Dimkox
added a commit
that referenced
this pull request
Oct 25, 2026
… repo (#194) * grants: a new route keeps a branch-bound protected-path grant Every prompt starts a new route, so binding protected-path grants to the route voided them on each user message and forced a new grant for the same edit again and again. A branch-bound grant is already held to the repository, branch ref, anchor ancestry, exact files and TTL, so it no longer checks the route. Production and external-write grants keep their exact route, HEAD and tree binding. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * grants: pin change_id and the scope guard in tests The security review found that change_id is now the only task binding of a branch-bound grant and that no test pinned it, nor the protected-path scope guard. Add a test for each; both mutants are now killed. Update the has_valid_approval docstring. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * grants: bind branch-bound grants to the session, not the route Skipping the route broke session isolation: a grant issued in one session also served another session in the same worktree (tests/test_control_plane_sessions failed on CI). A protected-path grant now records its session and checks that instead of the route, so later prompts of the same session keep it and another session never gets it. Without a known session on both sides the exact route is still required. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * Bind grant sessions to the caller, not the route A session without its own route pointer reads the shared route of another session, and 'manual' is not a session. The check now uses the caller's bound session and skips the route only when caller, route and grant name the same session. getzilla_approve.py binds CLAUDE_CODE_SESSION_ID. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * docs: bring QUICKSTART, START_HERE, REFERENCE, CHANGELOG and state up to date - QUICKSTART: launcher, runtime evidence without report commits, route reconcile, review snapshots, light lane, and a disk cleanup section. - START_HERE and REFERENCE: current main a45fbdd, correct v2.3.0 link, continuation at issue #134; REFERENCE lists all getzilla commands. - PROJECT_STATE: current_continuation moves to issue #134; the finished PR #79 contour is kept as historical_pr79_continuation. - CHANGELOG: 2.3.1 lists the work merged since 2026-10-21 (#121-#179). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * docs(readme): list every getzilla command and the current source state A Commands section lists all launcher commands by task, with their main options. The source line names what 2.3.1 adds since v2.3.0, and the file map says where review copies live and how they are removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * docs: fix command wording found in review of #180 history takes a snapshot file, approve needs --reason, --add-reviewer works with --reconcile, getzilla test falls back to serial unittest without pytest-xdist, report overhead is per profile, and the state record counts the merged PRs from #114. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * cleanup: close the #134 Low findings in inventory, snapshots and worktree checks - Inventory: a linked .getzilla or runtime folder is not read; one entry budget covers the copy search and all copy sizes; an unreadable folder, a linked copy root or a cut size makes the report incomplete. - Review snapshots: the parent-folder refusal has its own message, and the module says a snapshot holds committed content only. - Tests pin the guards that mutants survived before: annotated tag peel, marker removal after a failed worktree add, the main-worktree base, the marker schema, the 0700 mode, unregistered folders, the refs/worktree check, a failed reflog read, the 2 s margins. - getzilla status answers --help; a test runs --help for every command. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * cleanup: count each copy entry once and accept a search that uses exactly the budget Review of #181: the copy folder listing was counted by the search and again by its size, and a search that used the full budget reported itself incomplete. Tests pin both boundaries. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * contract: every Getzilla defect goes to a GitHub issue AGENTS.md now requires an issue in Dimkox/Getzilla for each defect in Getzilla itself, also one that was worked around: search first, no duplicates, Low findings into the collecting issue, no secrets or exploit commands, and an exact external-write grant first. Consumer projects get the same rule in the installed contract, with a ready issue text for the owner when filing upstream is not allowed. The delivery skill adds it as the last step of a task. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * contract: own-repository issues are in the L5 standing consent Review of #182: the new rule called issue writes an L5 process call while the L5 scope named only merge, tag and release. The owner asked for it, so the scope now covers the project's own GitHub issues; the checks-green condition stays on merge, tag and release. The search covers open and closed issues, the grant resource is named, consumer consent is recorded as an exact grant, and a test pins the rule. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * contract: issue grants follow the exact-HEAD binding; pin the secret bans Security review of #182: the rule said a tool grant lasts its TTL, but external-write grants stay bound to route, change, HEAD and tree. The test now also pins the bans on secrets and customer data. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * tests: give the Node transparency adapter tests room on loaded runners (#187) test_node_adapter_behavior timed out after 10 s on a busy public linux runner while it only checks adapter behavior. Both Node calls now allow 60 s; the neighbouring stubborn-child test already allows 45 s. Fixes #187. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * workflow: harness notices keep the route; spec and transition use the package (#185, #186) - A prompt made only of <task-notification> or <system-reminder> envelopes keeps the active route like a short reply, and never creates a route. Text next to an envelope is a normal prompt. - getzilla spec generate/validate --change-id use the package folder that change start created (the runtime one; legacy tracked packages stay readable), so no stray file lands in engineering/changes. - getzilla change transition answers a refused move with exit 2 and the allowed next states, not a traceback. Fixes #185. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * workflow: a notice skips routing only when no route exists (#188 review) Review of #188: a notice next to a route of another session, or a closed route, built no route, so the session fell back to that route. Such a route is now replaced as before; the no-route rule applies only when no route exists at all. The transition hint names allowed states only for an invalid move, not for a gate refusal. Tests cover both cases and envelope edge forms (zero-width tail, attributes, case, crossed tags). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * fix: #134 slice B — runner verdicts, report escaping, protected-write session - run_named_tests and run_trust_tests use _run_directory, so a failed cleanup of the run folder (a locked file on Windows) no longer replaces the test verdict. - getzilla report prints journal route ids with control and format characters replaced by '?'. - getzilla protected-write binds the caller session like approve, so a session-bound grant follows its later routes on that path too. - Tests: cleanup error keeps both verdicts; hostile route id; the protected-write CLI with and without a session; the approve CLI GETZILLA_SESSION_ID fallback and CLAUDE_CODE_SESSION_ID precedence. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * fix: escape the report profile too; the cleanup test removes its folders (#189 review) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * test(eu-ai-act): cover the deferred negative cases from #122 - accepted_by: missing, empty, short or non-string role; missing, empty, malformed or impossible date. - Matrix sources: ftp, gopher, file and mailto schemes and a URL without a host are refused. - Attestation identity: attestation_id, key_id and policy_digest missing, empty or of the wrong type are refused. - The verifier refusal uses a working executable inside the project, so only the location guard can stop it. - The first audit call uses the captured providers, never the engine loader. - An archive install (getzilla.zip, no inherited PYTHONPATH) finds the scaffold templates through STACK_DIR. Each test fails when its guard is removed (7 of 7 mutants killed). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * fix(eu-ai-act): confirmation and review dates must be past YYYY-MM-DD (#191) date.fromisoformat on Python 3.11+ also accepts 20261020 and week dates such as 2026-W43-1, and str() let an integer through. A future date also passed as a human confirmation. - _iso_day accepts only a YYYY-MM-DD string. - A class confirmation, an exemption confirmation and a high-residual accepted_by refuse a date after the evaluation day. - A risk record's reviewed date uses the same parser and refuses a future date. Tests cover the basic, integer, week and future forms for each caller. 8 of 8 guard mutants are killed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * fix(policy): guard every MCP write tool and bind GitHub writes to the repo (#193, #184) SIDE_EFFECT_TOOL matched a write verb only right after `__`, so GitHub MCP tools with the verb inside the name passed with no grant: issue_write, add_issue_comment, push_files, resolve_review_thread, enable_pr_auto_merge, fork_repository, actions_run_trigger and more. - The regex now covers more leading verbs, a `write` token anywhere and actions_run. Read tools (get_*, list_*, search_*, *_read, get_check_run, run_secret_scanning) stay unguarded. - A GitHub MCP write that names owner/repo must target the repository that grants bind to (case-insensitive). Another repository, a partial or non-string target, or a project without a GitHub origin is refused. A call without owner/repo keeps the tool-name grant check. Tests pin 18 write tools, 13 read tools and the repository binding. 10 of 10 guard mutants are killed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * fix(policy): GitHub MCP tools fail closed; camelCase and hyphen verbs (#193 review) The review of 172e4cf found write tools that the verb list still missed: run_workflow, manage_*_subscription, star/unstar_repository, reprioritize_sub_issue on GitHub, and camelCase or hyphen names on other servers (executeWrite, createJiraIssue, batchUpdate, management-projects-create). A GitHub server under another name also skipped the repository binding. - mcp_side_effect: a server whose name contains "github" treats every tool as a write unless it is a known read (get_, list_, search_, download_, *_read, actions/projects get/list, run_secret_scanning). - Other servers: a verb also ends at an uppercase letter and may start a "-" token; manage, star, unstar, reprioritize, run and transition join the list. - The repository binding covers every GitHub-named server, and owner and repo must be plain GitHub names ([A-Za-z0-9._-]). - policy.sensitive_action uses the same mcp_side_effect. 14 of 14 guard mutants are killed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * fix(policy): keep actions_run on every server; match verbs in the action only (#193) c65d5ea dropped the actions_run branch, so actions_run_trigger on a GitHub server named without "github" (mcp__gh__) needed no grant again. It also scanned the whole tool name, so a verb in a server name such as cloud-run made every tool on that server a write. - SIDE_EFFECT_TOOL matches ^actions_run again. - mcp_side_effect scans only the action part of the tool name. 16 of 16 guard mutants are killed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * fix(policy): scan every segment after the MCP server name (#193 review) 5be3a29 scanned only the last `__` segment, so a verb in an earlier segment (mcp__x__delete__file) passed as a read with no grant. The action is now everything after the server segment. A write hint that appears only in the server name (slack-post) is still not seen; that limit is tracked in #195 and pinned as a known read. 17 of 17 guard mutants are killed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR --------- Co-authored-by: Claude <noreply@anthropic.com>
Dimkox
added a commit
that referenced
this pull request
Oct 26, 2026
…_copy (#197) * grants: a new route keeps a branch-bound protected-path grant Every prompt starts a new route, so binding protected-path grants to the route voided them on each user message and forced a new grant for the same edit again and again. A branch-bound grant is already held to the repository, branch ref, anchor ancestry, exact files and TTL, so it no longer checks the route. Production and external-write grants keep their exact route, HEAD and tree binding. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * grants: pin change_id and the scope guard in tests The security review found that change_id is now the only task binding of a branch-bound grant and that no test pinned it, nor the protected-path scope guard. Add a test for each; both mutants are now killed. Update the has_valid_approval docstring. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * grants: bind branch-bound grants to the session, not the route Skipping the route broke session isolation: a grant issued in one session also served another session in the same worktree (tests/test_control_plane_sessions failed on CI). A protected-path grant now records its session and checks that instead of the route, so later prompts of the same session keep it and another session never gets it. Without a known session on both sides the exact route is still required. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * Bind grant sessions to the caller, not the route A session without its own route pointer reads the shared route of another session, and 'manual' is not a session. The check now uses the caller's bound session and skips the route only when caller, route and grant name the same session. getzilla_approve.py binds CLAUDE_CODE_SESSION_ID. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * docs: bring QUICKSTART, START_HERE, REFERENCE, CHANGELOG and state up to date - QUICKSTART: launcher, runtime evidence without report commits, route reconcile, review snapshots, light lane, and a disk cleanup section. - START_HERE and REFERENCE: current main a45fbdd, correct v2.3.0 link, continuation at issue #134; REFERENCE lists all getzilla commands. - PROJECT_STATE: current_continuation moves to issue #134; the finished PR #79 contour is kept as historical_pr79_continuation. - CHANGELOG: 2.3.1 lists the work merged since 2026-10-21 (#121-#179). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * docs(readme): list every getzilla command and the current source state A Commands section lists all launcher commands by task, with their main options. The source line names what 2.3.1 adds since v2.3.0, and the file map says where review copies live and how they are removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * docs: fix command wording found in review of #180 history takes a snapshot file, approve needs --reason, --add-reviewer works with --reconcile, getzilla test falls back to serial unittest without pytest-xdist, report overhead is per profile, and the state record counts the merged PRs from #114. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * cleanup: close the #134 Low findings in inventory, snapshots and worktree checks - Inventory: a linked .getzilla or runtime folder is not read; one entry budget covers the copy search and all copy sizes; an unreadable folder, a linked copy root or a cut size makes the report incomplete. - Review snapshots: the parent-folder refusal has its own message, and the module says a snapshot holds committed content only. - Tests pin the guards that mutants survived before: annotated tag peel, marker removal after a failed worktree add, the main-worktree base, the marker schema, the 0700 mode, unregistered folders, the refs/worktree check, a failed reflog read, the 2 s margins. - getzilla status answers --help; a test runs --help for every command. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * cleanup: count each copy entry once and accept a search that uses exactly the budget Review of #181: the copy folder listing was counted by the search and again by its size, and a search that used the full budget reported itself incomplete. Tests pin both boundaries. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * contract: every Getzilla defect goes to a GitHub issue AGENTS.md now requires an issue in Dimkox/Getzilla for each defect in Getzilla itself, also one that was worked around: search first, no duplicates, Low findings into the collecting issue, no secrets or exploit commands, and an exact external-write grant first. Consumer projects get the same rule in the installed contract, with a ready issue text for the owner when filing upstream is not allowed. The delivery skill adds it as the last step of a task. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * contract: own-repository issues are in the L5 standing consent Review of #182: the new rule called issue writes an L5 process call while the L5 scope named only merge, tag and release. The owner asked for it, so the scope now covers the project's own GitHub issues; the checks-green condition stays on merge, tag and release. The search covers open and closed issues, the grant resource is named, consumer consent is recorded as an exact grant, and a test pins the rule. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * contract: issue grants follow the exact-HEAD binding; pin the secret bans Security review of #182: the rule said a tool grant lasts its TTL, but external-write grants stay bound to route, change, HEAD and tree. The test now also pins the bans on secrets and customer data. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * tests: give the Node transparency adapter tests room on loaded runners (#187) test_node_adapter_behavior timed out after 10 s on a busy public linux runner while it only checks adapter behavior. Both Node calls now allow 60 s; the neighbouring stubborn-child test already allows 45 s. Fixes #187. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * workflow: harness notices keep the route; spec and transition use the package (#185, #186) - A prompt made only of <task-notification> or <system-reminder> envelopes keeps the active route like a short reply, and never creates a route. Text next to an envelope is a normal prompt. - getzilla spec generate/validate --change-id use the package folder that change start created (the runtime one; legacy tracked packages stay readable), so no stray file lands in engineering/changes. - getzilla change transition answers a refused move with exit 2 and the allowed next states, not a traceback. Fixes #185. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * workflow: a notice skips routing only when no route exists (#188 review) Review of #188: a notice next to a route of another session, or a closed route, built no route, so the session fell back to that route. Such a route is now replaced as before; the no-route rule applies only when no route exists at all. The transition hint names allowed states only for an invalid move, not for a gate refusal. Tests cover both cases and envelope edge forms (zero-width tail, attributes, case, crossed tags). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * fix: #134 slice B — runner verdicts, report escaping, protected-write session - run_named_tests and run_trust_tests use _run_directory, so a failed cleanup of the run folder (a locked file on Windows) no longer replaces the test verdict. - getzilla report prints journal route ids with control and format characters replaced by '?'. - getzilla protected-write binds the caller session like approve, so a session-bound grant follows its later routes on that path too. - Tests: cleanup error keeps both verdicts; hostile route id; the protected-write CLI with and without a session; the approve CLI GETZILLA_SESSION_ID fallback and CLAUDE_CODE_SESSION_ID precedence. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * fix: escape the report profile too; the cleanup test removes its folders (#189 review) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * test(eu-ai-act): cover the deferred negative cases from #122 - accepted_by: missing, empty, short or non-string role; missing, empty, malformed or impossible date. - Matrix sources: ftp, gopher, file and mailto schemes and a URL without a host are refused. - Attestation identity: attestation_id, key_id and policy_digest missing, empty or of the wrong type are refused. - The verifier refusal uses a working executable inside the project, so only the location guard can stop it. - The first audit call uses the captured providers, never the engine loader. - An archive install (getzilla.zip, no inherited PYTHONPATH) finds the scaffold templates through STACK_DIR. Each test fails when its guard is removed (7 of 7 mutants killed). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * fix(eu-ai-act): confirmation and review dates must be past YYYY-MM-DD (#191) date.fromisoformat on Python 3.11+ also accepts 20261020 and week dates such as 2026-W43-1, and str() let an integer through. A future date also passed as a human confirmation. - _iso_day accepts only a YYYY-MM-DD string. - A class confirmation, an exemption confirmation and a high-residual accepted_by refuse a date after the evaluation day. - A risk record's reviewed date uses the same parser and refuses a future date. Tests cover the basic, integer, week and future forms for each caller. 8 of 8 guard mutants are killed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * fix(policy): guard every MCP write tool and bind GitHub writes to the repo (#193, #184) SIDE_EFFECT_TOOL matched a write verb only right after `__`, so GitHub MCP tools with the verb inside the name passed with no grant: issue_write, add_issue_comment, push_files, resolve_review_thread, enable_pr_auto_merge, fork_repository, actions_run_trigger and more. - The regex now covers more leading verbs, a `write` token anywhere and actions_run. Read tools (get_*, list_*, search_*, *_read, get_check_run, run_secret_scanning) stay unguarded. - A GitHub MCP write that names owner/repo must target the repository that grants bind to (case-insensitive). Another repository, a partial or non-string target, or a project without a GitHub origin is refused. A call without owner/repo keeps the tool-name grant check. Tests pin 18 write tools, 13 read tools and the repository binding. 10 of 10 guard mutants are killed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * fix(policy): GitHub MCP tools fail closed; camelCase and hyphen verbs (#193 review) The review of 172e4cf found write tools that the verb list still missed: run_workflow, manage_*_subscription, star/unstar_repository, reprioritize_sub_issue on GitHub, and camelCase or hyphen names on other servers (executeWrite, createJiraIssue, batchUpdate, management-projects-create). A GitHub server under another name also skipped the repository binding. - mcp_side_effect: a server whose name contains "github" treats every tool as a write unless it is a known read (get_, list_, search_, download_, *_read, actions/projects get/list, run_secret_scanning). - Other servers: a verb also ends at an uppercase letter and may start a "-" token; manage, star, unstar, reprioritize, run and transition join the list. - The repository binding covers every GitHub-named server, and owner and repo must be plain GitHub names ([A-Za-z0-9._-]). - policy.sensitive_action uses the same mcp_side_effect. 14 of 14 guard mutants are killed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * fix(policy): keep actions_run on every server; match verbs in the action only (#193) c65d5ea dropped the actions_run branch, so actions_run_trigger on a GitHub server named without "github" (mcp__gh__) needed no grant again. It also scanned the whole tool name, so a verb in a server name such as cloud-run made every tool on that server a write. - SIDE_EFFECT_TOOL matches ^actions_run again. - mcp_side_effect scans only the action part of the tool name. 16 of 16 guard mutants are killed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * fix(policy): scan every segment after the MCP server name (#193 review) 5be3a29 scanned only the last `__` segment, so a verb in an earlier segment (mcp__x__delete__file) passed as a read with no grant. The action is now everything after the server segment. A write hint that appears only in the server name (slack-post) is still not seen; that limit is tracked in #195 and pinned as a known read. 17 of 17 guard mutants are killed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * test(support): retry project_copy cleanup after a late .git write (#196) A passing test failed on CI because TemporaryDirectory cleanup hit "Directory not empty: .git": something still added a file under .git while rmtree ran. Local probes (40 hook runs, loose-object count far below gc.auto) did not reproduce it, so the root cause stays open. project_copy now uses _test_directory: the stdlib cleanup (which also resets read-only files on Windows) is retried up to four times with a short pause, and the last failure is still raised. Tests cover one transient failure and a lasting one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * test(support): turn off git auto maintenance in the git fixture (#196) Review lead: git 2.46+ runs auto maintenance detached after a commit, and it can still take a lock under .git/objects while the fixture is removed. project_copy(git=True) now sets maintenance.auto=false and gc.auto=0 before its first commit; the cleanup retry stays as a backstop. The lasting-failure test now detaches the TemporaryDirectory finalizer, so it no longer emits an implicit-cleanup ResourceWarning. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR --------- Co-authored-by: Claude <noreply@anthropic.com>
Dimkox
added a commit
that referenced
this pull request
Oct 26, 2026
…199) * grants: a new route keeps a branch-bound protected-path grant Every prompt starts a new route, so binding protected-path grants to the route voided them on each user message and forced a new grant for the same edit again and again. A branch-bound grant is already held to the repository, branch ref, anchor ancestry, exact files and TTL, so it no longer checks the route. Production and external-write grants keep their exact route, HEAD and tree binding. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * grants: pin change_id and the scope guard in tests The security review found that change_id is now the only task binding of a branch-bound grant and that no test pinned it, nor the protected-path scope guard. Add a test for each; both mutants are now killed. Update the has_valid_approval docstring. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * grants: bind branch-bound grants to the session, not the route Skipping the route broke session isolation: a grant issued in one session also served another session in the same worktree (tests/test_control_plane_sessions failed on CI). A protected-path grant now records its session and checks that instead of the route, so later prompts of the same session keep it and another session never gets it. Without a known session on both sides the exact route is still required. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * Bind grant sessions to the caller, not the route A session without its own route pointer reads the shared route of another session, and 'manual' is not a session. The check now uses the caller's bound session and skips the route only when caller, route and grant name the same session. getzilla_approve.py binds CLAUDE_CODE_SESSION_ID. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * docs: bring QUICKSTART, START_HERE, REFERENCE, CHANGELOG and state up to date - QUICKSTART: launcher, runtime evidence without report commits, route reconcile, review snapshots, light lane, and a disk cleanup section. - START_HERE and REFERENCE: current main a45fbdd, correct v2.3.0 link, continuation at issue #134; REFERENCE lists all getzilla commands. - PROJECT_STATE: current_continuation moves to issue #134; the finished PR #79 contour is kept as historical_pr79_continuation. - CHANGELOG: 2.3.1 lists the work merged since 2026-10-21 (#121-#179). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * docs(readme): list every getzilla command and the current source state A Commands section lists all launcher commands by task, with their main options. The source line names what 2.3.1 adds since v2.3.0, and the file map says where review copies live and how they are removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * docs: fix command wording found in review of #180 history takes a snapshot file, approve needs --reason, --add-reviewer works with --reconcile, getzilla test falls back to serial unittest without pytest-xdist, report overhead is per profile, and the state record counts the merged PRs from #114. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * cleanup: close the #134 Low findings in inventory, snapshots and worktree checks - Inventory: a linked .getzilla or runtime folder is not read; one entry budget covers the copy search and all copy sizes; an unreadable folder, a linked copy root or a cut size makes the report incomplete. - Review snapshots: the parent-folder refusal has its own message, and the module says a snapshot holds committed content only. - Tests pin the guards that mutants survived before: annotated tag peel, marker removal after a failed worktree add, the main-worktree base, the marker schema, the 0700 mode, unregistered folders, the refs/worktree check, a failed reflog read, the 2 s margins. - getzilla status answers --help; a test runs --help for every command. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * cleanup: count each copy entry once and accept a search that uses exactly the budget Review of #181: the copy folder listing was counted by the search and again by its size, and a search that used the full budget reported itself incomplete. Tests pin both boundaries. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * contract: every Getzilla defect goes to a GitHub issue AGENTS.md now requires an issue in Dimkox/Getzilla for each defect in Getzilla itself, also one that was worked around: search first, no duplicates, Low findings into the collecting issue, no secrets or exploit commands, and an exact external-write grant first. Consumer projects get the same rule in the installed contract, with a ready issue text for the owner when filing upstream is not allowed. The delivery skill adds it as the last step of a task. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * contract: own-repository issues are in the L5 standing consent Review of #182: the new rule called issue writes an L5 process call while the L5 scope named only merge, tag and release. The owner asked for it, so the scope now covers the project's own GitHub issues; the checks-green condition stays on merge, tag and release. The search covers open and closed issues, the grant resource is named, consumer consent is recorded as an exact grant, and a test pins the rule. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * contract: issue grants follow the exact-HEAD binding; pin the secret bans Security review of #182: the rule said a tool grant lasts its TTL, but external-write grants stay bound to route, change, HEAD and tree. The test now also pins the bans on secrets and customer data. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * tests: give the Node transparency adapter tests room on loaded runners (#187) test_node_adapter_behavior timed out after 10 s on a busy public linux runner while it only checks adapter behavior. Both Node calls now allow 60 s; the neighbouring stubborn-child test already allows 45 s. Fixes #187. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * workflow: harness notices keep the route; spec and transition use the package (#185, #186) - A prompt made only of <task-notification> or <system-reminder> envelopes keeps the active route like a short reply, and never creates a route. Text next to an envelope is a normal prompt. - getzilla spec generate/validate --change-id use the package folder that change start created (the runtime one; legacy tracked packages stay readable), so no stray file lands in engineering/changes. - getzilla change transition answers a refused move with exit 2 and the allowed next states, not a traceback. Fixes #185. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * workflow: a notice skips routing only when no route exists (#188 review) Review of #188: a notice next to a route of another session, or a closed route, built no route, so the session fell back to that route. Such a route is now replaced as before; the no-route rule applies only when no route exists at all. The transition hint names allowed states only for an invalid move, not for a gate refusal. Tests cover both cases and envelope edge forms (zero-width tail, attributes, case, crossed tags). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * fix: #134 slice B — runner verdicts, report escaping, protected-write session - run_named_tests and run_trust_tests use _run_directory, so a failed cleanup of the run folder (a locked file on Windows) no longer replaces the test verdict. - getzilla report prints journal route ids with control and format characters replaced by '?'. - getzilla protected-write binds the caller session like approve, so a session-bound grant follows its later routes on that path too. - Tests: cleanup error keeps both verdicts; hostile route id; the protected-write CLI with and without a session; the approve CLI GETZILLA_SESSION_ID fallback and CLAUDE_CODE_SESSION_ID precedence. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * fix: escape the report profile too; the cleanup test removes its folders (#189 review) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * test(eu-ai-act): cover the deferred negative cases from #122 - accepted_by: missing, empty, short or non-string role; missing, empty, malformed or impossible date. - Matrix sources: ftp, gopher, file and mailto schemes and a URL without a host are refused. - Attestation identity: attestation_id, key_id and policy_digest missing, empty or of the wrong type are refused. - The verifier refusal uses a working executable inside the project, so only the location guard can stop it. - The first audit call uses the captured providers, never the engine loader. - An archive install (getzilla.zip, no inherited PYTHONPATH) finds the scaffold templates through STACK_DIR. Each test fails when its guard is removed (7 of 7 mutants killed). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * fix(eu-ai-act): confirmation and review dates must be past YYYY-MM-DD (#191) date.fromisoformat on Python 3.11+ also accepts 20261020 and week dates such as 2026-W43-1, and str() let an integer through. A future date also passed as a human confirmation. - _iso_day accepts only a YYYY-MM-DD string. - A class confirmation, an exemption confirmation and a high-residual accepted_by refuse a date after the evaluation day. - A risk record's reviewed date uses the same parser and refuses a future date. Tests cover the basic, integer, week and future forms for each caller. 8 of 8 guard mutants are killed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * fix(policy): guard every MCP write tool and bind GitHub writes to the repo (#193, #184) SIDE_EFFECT_TOOL matched a write verb only right after `__`, so GitHub MCP tools with the verb inside the name passed with no grant: issue_write, add_issue_comment, push_files, resolve_review_thread, enable_pr_auto_merge, fork_repository, actions_run_trigger and more. - The regex now covers more leading verbs, a `write` token anywhere and actions_run. Read tools (get_*, list_*, search_*, *_read, get_check_run, run_secret_scanning) stay unguarded. - A GitHub MCP write that names owner/repo must target the repository that grants bind to (case-insensitive). Another repository, a partial or non-string target, or a project without a GitHub origin is refused. A call without owner/repo keeps the tool-name grant check. Tests pin 18 write tools, 13 read tools and the repository binding. 10 of 10 guard mutants are killed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * fix(policy): GitHub MCP tools fail closed; camelCase and hyphen verbs (#193 review) The review of 172e4cf found write tools that the verb list still missed: run_workflow, manage_*_subscription, star/unstar_repository, reprioritize_sub_issue on GitHub, and camelCase or hyphen names on other servers (executeWrite, createJiraIssue, batchUpdate, management-projects-create). A GitHub server under another name also skipped the repository binding. - mcp_side_effect: a server whose name contains "github" treats every tool as a write unless it is a known read (get_, list_, search_, download_, *_read, actions/projects get/list, run_secret_scanning). - Other servers: a verb also ends at an uppercase letter and may start a "-" token; manage, star, unstar, reprioritize, run and transition join the list. - The repository binding covers every GitHub-named server, and owner and repo must be plain GitHub names ([A-Za-z0-9._-]). - policy.sensitive_action uses the same mcp_side_effect. 14 of 14 guard mutants are killed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * fix(policy): keep actions_run on every server; match verbs in the action only (#193) c65d5ea dropped the actions_run branch, so actions_run_trigger on a GitHub server named without "github" (mcp__gh__) needed no grant again. It also scanned the whole tool name, so a verb in a server name such as cloud-run made every tool on that server a write. - SIDE_EFFECT_TOOL matches ^actions_run again. - mcp_side_effect scans only the action part of the tool name. 16 of 16 guard mutants are killed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * fix(policy): scan every segment after the MCP server name (#193 review) 5be3a29 scanned only the last `__` segment, so a verb in an earlier segment (mcp__x__delete__file) passed as a read with no grant. The action is now everything after the server segment. A write hint that appears only in the server name (slack-post) is still not seen; that limit is tracked in #195 and pinned as a known read. 17 of 17 guard mutants are killed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * test(support): retry project_copy cleanup after a late .git write (#196) A passing test failed on CI because TemporaryDirectory cleanup hit "Directory not empty: .git": something still added a file under .git while rmtree ran. Local probes (40 hook runs, loose-object count far below gc.auto) did not reproduce it, so the root cause stays open. project_copy now uses _test_directory: the stdlib cleanup (which also resets read-only files on Windows) is retried up to four times with a short pause, and the last failure is still raised. Tests cover one transient failure and a lasting one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * test(support): turn off git auto maintenance in the git fixture (#196) Review lead: git 2.46+ runs auto maintenance detached after a commit, and it can still take a lock under .git/objects while the fixture is removed. project_copy(git=True) now sets maintenance.auto=false and gc.auto=0 before its first commit; the cleanup retry stays as a backstop. The lasting-failure test now detaches the TemporaryDirectory finalizer, so it no longer emits an implicit-cleanup ResourceWarning. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR * test(verifier): stub ruff and bandit where tests pin later PR checks (#198) In PR mode a missing bandit is a required refusal, and every later check is skipped. The cloud container has no bandit, so five tests that pin factory-postgres-exit and the full-suite marker saw "not executed after required refusal" instead of the result they check. CI has bandit, so they passed there. The verifier's fail-closed behavior is right; the tests now stub _ruff and _bandit as passing (doctor tests via _installed_linters, scope tests in _run), so the host's tools cannot change their outcome. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BhxEnEALZRsc7kaPwG2kiR --------- Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Slice A of the Low batch in #134: the findings from the reviews of #174–#178 and #180.
What changed
resource_inventory.py):.getzillaor runtime folder. It reports itself incomplete instead.review_snapshot.py):getzilla status --helpprints help instead of the status JSON..getzilla, runtime folder or copy root; an unreadable copy folder; the shared budget; a missing runtime folder; a..part on its own.worktree add, the main-worktree base from a task worktree, marker schema, 0700 mode on an existing folder, a marker next to an unregistered folder, option-shaped revisions.refs/worktreeon its own (the reflog is expired first), a failed reflog read,assertIs(False)for the 2 s start margin, and the 2 s future tolerance at +1 s and +5 s.find_rootat the test project.--helpwith a usage line.Mutation probes (private scratch copy)
--end-of-options. Git rejects option-shaped revisions with or without it, so the mutant is equivalent; the flag stays as defense in depth.not linkedterm in thecompletevalue; it is removed.Not in this PR (stays in #134)
getzilla_protected_write.pysession binding. A local grant conflict blocked the edit. It fails closed today.GETZILLA_SESSION_IDCLI test.Checks
test_package_status,test_text_writes,test_structureandtest_policy: 154 passed.Generated by Claude Code