Repository navigation
fix(subagent-scope-guard): stop false-positive on committed .scope-lock (#86) - #87
Merged
Merged
Conversation
…ck (#86) The SubagentStop hook inspected HEAD's last commit for .scope-lock files and, finding a legitimately-committed lock (written by scope-lock-apply), blocked EVERY subsequent subagent with a message instructing 'Revert unauthorized .scope-lock changes.' Compliant read-only subagents obeyed and ran git revert, producing spurious revert/reapply commits. - Remove the unattributed HEAD diff-tree check. A committed .scope-lock is always legitimate (scope-lock-apply is the only sanctioned writer; the Write tool is guarded). Drift is still caught by the working-tree check + push/PR/Stop hash guards. - Reframe the block message to be non-destructive: do not run git / do not auto-revert; surface to the lead. Note pre-existing committed locks need no action. - Add hooks/subagent-scope-guard.test.sh regression coverage. Fixes #86. Co-Authored-By: Claude <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes a false-positive in the hooks/subagent-scope-guard SubagentStop hook where a legitimately committed .scope-lock at HEAD caused subagents to be blocked and (previously) instructed them to run destructive git revert operations, leading to spurious history churn.
Changes:
- Removes the “did
HEAD’s last commit touch a.scope-lock?” check fromhooks/subagent-scope-guardto prevent persistent false-positives on pre-existing committed locks. - Updates the block message to explicitly discourage running git commands and to escalate to the lead agent instead.
- Adds a new lifecycle/regression test script for the committed-lock / uncommitted-lock / clean-repo cases and documents the fix in release notes.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
RELEASE-NOTES.md |
Adds v6.5.6 entry describing the fix and the new regression coverage. |
hooks/subagent-scope-guard.test.sh |
New regression/lifecycle test script covering the #86 scenarios. |
hooks/subagent-scope-guard |
Removes the HEAD last-commit .scope-lock inspection and revises the stop-block reason text. |
.claude-plugin/plugin.json |
Bumps plugin version to 6.5.6. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| "name": "autodev", | ||
| "description": "Autonomous development workflow skills for coding agents: design, review, planning, execution, monitoring, and retrospectives", | ||
| "version": "6.5.5", | ||
| "version": "6.5.6", |
| [ -z "$violations" ] && exit 0 | ||
|
|
||
| block "Subagent stop blocked — protected files were modified: | ||
| block "Subagent stop blocked — a protected file was modified during this subagent's run: |
Comment on lines
+15
to
+17
| # Run: bash hooks/subagent-scope-guard.test.sh | ||
|
|
||
| set -euo pipefail |
version-check requires all three version files to agree; the fix commit only bumped .claude-plugin/plugin.json. Run via scripts/bump-version.sh. Co-Authored-By: Claude <noreply@anthropic.com>
- Wire hooks/subagent-scope-guard.test.sh into hooks-check.yml so the #86 regression runs in CI (was local-only). - Block message: drop the false attribution 'during this subagent's run' (the working-tree check cannot attribute when/which actor introduced a change) and use plural 'changes'. Note changes may predate the subagent. Co-Authored-By: Claude <noreply@anthropic.com>
Comment on lines
+66
to
+70
| # NOTE: we intentionally do NOT inspect HEAD's last commit for .scope-lock | ||
| # files. A committed .scope-lock is always legitimate: hooks/scope-lock-apply | ||
| # is the only sanctioned writer (the Write/Edit/MultiEdit tools are guarded | ||
| # against *.scope-lock paths by pre-tool-scope-guard), so any committed lock | ||
| # was produced by the scope-lock skill or the operator. Checking HEAD's last |
Comment on lines
+131
to
+133
| The working-tree check cannot attribute these changes to a specific actor or | ||
| turn — they may predate this subagent (e.g. an uncommitted lock left by an | ||
| earlier step). If so, no action is needed. |
|
|
||
| ## v6.5.6 — 2026-06-22 | ||
|
|
||
| Fix for issue #86: `subagent-scope-guard` false-positived on committed `.scope-lock` files and its block message instructed subagents to auto-revert them — producing spurious `git revert`/`reapply` commits from read-only subagents. |
Comment on lines
+5
to
+12
| # Regression coverage for autonomous-dev-kit#86: | ||
| # (1) a COMMITTED .scope-lock at HEAD (legitimate; written by scope-lock-apply) | ||
| # must NOT trigger a block — the old code inspected HEAD's last commit and | ||
| # false-positived on every subsequent subagent, then instructed `git revert`. | ||
| # (2) an UNCOMMITTED working-tree .scope-lock write (a subagent directly writing | ||
| # a lock) MUST trigger a block — but the message must be NON-destructive: it | ||
| # must NOT instruct the subagent to revert/run git (the #86 hazard), and must | ||
| # tell it to surface to the lead instead. |
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.
What
Fixes #86. The
SubagentStophook (hooks/subagent-scope-guard) false-positived on any legitimately-committed.scope-lockat HEAD and its block message instructed subagents to auto-revert it — producing spuriousgit revert/reapplycommits from read-only subagents.Observed this session: read-only investigation subagents spawned from a repo whose HEAD legitimately carried a committed
.scope-lock(the steady state mid-pipeline) were each blocked on stop with "Last commit modified scope-lock file … 1. Revert unauthorized .scope-lock changes." Two of three obeyed and rangit revert→ two spurious commits (net-zero, but polluted history + moved HEAD; lead had togit reset --softto recover).Root cause
.scope-lockfiles (git diff-tree HEAD) but did not attribute that commit to the stopping subagent. A committed lock is always legitimate —hooks/scope-lock-applyis the only sanctioned writer (the Write/Edit/MultiEdit tools are guarded against*.scope-lockpaths bypre-tool-scope-guard) — so the check could only false-positive.git revertas step 1, delivered as theSubagentStopblock reason.pre-tool-scope-guarddoes not catchgit revert/reset --soft(only--hard/rebase -i/force-push), so the spurious reverts landed.Fix
diff-treecheck. Drift is still enforced: by the uncommitted working-tree check (in-flight writes) and the push/PR + Stop hash guards (committed drift). No protection lost.hooks/subagent-scope-guard.test.shregression coverage: committed lock at HEAD → no block; uncommitted working-tree write → blocks with non-destructive message; clean repo → no block. All pass;tests/hook-contracts.shstill green.Release
Bumps
.claude-plugin/plugin.json6.5.5 → 6.5.6 (merge to main triggersrelease-tag.ymlauto-tag + marketplace dispatch).🤖 Generated with Claude Code