Skip to content

fix(subagent-scope-guard): stop false-positive on committed .scope-lock (#86) - #87

Merged
intel352 merged 3 commits into
mainfrom
fix/subagent-scope-guard-false-positive-86
Jun 23, 2026
Merged

intel352 merged 3 commits into
mainfrom
fix/subagent-scope-guard-false-positive-86

Conversation

@intel352

Copy link
Copy Markdown
Contributor

What

Fixes #86. The SubagentStop hook (hooks/subagent-scope-guard) false-positived on any legitimately-committed .scope-lock at HEAD and its block message instructed subagents to auto-revert it — producing spurious git revert/reapply commits 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 ran git revert → two spurious commits (net-zero, but polluted history + moved HEAD; lead had to git reset --soft to recover).

Root cause

  1. The hook inspected HEAD's last commit for .scope-lock files (git diff-tree HEAD) but did not attribute that commit to the stopping subagent. A committed 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 the check could only false-positive.
  2. The block message instructed git revert as step 1, delivered as the SubagentStop block reason. pre-tool-scope-guard does not catch git revert/reset --soft (only --hard/rebase -i/force-push), so the spurious reverts landed.

Fix

  • Remove the unattributed HEAD diff-tree check. 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.
  • Reframe the block message to be non-destructive: run no git command / 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: committed lock at HEAD → no block; uncommitted working-tree write → blocks with non-destructive message; clean repo → no block. All pass; tests/hook-contracts.sh still green.

Release

Bumps .claude-plugin/plugin.json 6.5.5 → 6.5.6 (merge to main triggers release-tag.yml auto-tag + marketplace dispatch).

🤖 Generated with Claude Code

…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>
Copilot AI review requested due to automatic review settings June 23, 2026 01:05

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 from hooks/subagent-scope-guard to 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",
Comment thread hooks/subagent-scope-guard Outdated
[ -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
Jon Langevin and others added 2 commits June 22, 2026 21:08
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>
Copilot AI review requested due to automatic review settings June 23, 2026 01:11
@intel352
intel352 merged commit c9563e1 into main Jun 23, 2026
12 checks passed

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.

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.
Comment thread RELEASE-NOTES.md

## 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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

subagent-scope-guard false-positives on pre-existing committed .scope-lock; block message instructs auto-revert (spurious commits)

2 participants