Skip to content

docs(rules): split PR/merge hazards out; add claude-perms-sweep - #346

Merged
laurigates merged 2 commits into
mainfrom
docs/auto-mode-always-classify-tools
Jul 28, 2026
Merged

docs(rules): split PR/merge hazards out; add claude-perms-sweep#346
laurigates merged 2 commits into
mainfrom
docs/auto-mode-always-classify-tools

Conversation

@laurigates

Copy link
Copy Markdown
Owner

Distilled from a session that traced why Claude Code web prompted constantly for scheduling/notification tools, then swept the fix across the portfolio.

1. rules/claude-code-auto-mode.md — the always-classify tool set

A hardcoded set — Agent, CronCreate, RemoteTrigger, ScheduleWakeup, SendFile — is excluded from auto mode's "would this be allowed in acceptEdits?" fast path and reaches the classifier on every call. No autoMode prose changes that; only a whole-tool allow rule, which resolves ahead of the classifier.

Traps recorded alongside it:

  • These tools declare no ruleContentField, so a scoped rule like RemoteTrigger(create) silently never matches — bare names only.
  • The arbitrary-code-execution strip doesn't touch non-exec grants, so these carry over into auto mode.
  • Monitor is deliberately excluded — it runs shell.

2. rules/pr-merge-hazards.md (new) — a split, not a cap raise

git-hazards.md had grown to cover two distinct surfaces, and the finding below pushed it past the 10 KB per-rule cap the context-budget gate enforces. Rather than raise the cap, split by surface:

File Traps Size
git-hazards.md 5 local-git (post-squash orphans, unpushed main, duplicate merge additions, git add atomicity, vanished staged file) 4.0 KB
pr-merge-hazards.md 4 GitHub/PR-merge (--merged misses squash, stacked-base auto-close, push-by-SHA, UNSTABLEBLOCKED) 6.5 KB

Cross-references and the marker-allowlist entry follow the traps to the new file. Verified against a clean origin/main worktree — the always-loaded total is 112,307 / 114,000, so the split costs only the second header.

The new trap: UNSTABLE is not BLOCKED. Failing checks that aren't branch-protection-required merge with a plain gh pr merge, so reaching for --admin takes a privilege you didn't need. Adds the two-check test for merging over red (files-touched and main-already-failing — either alone is a guess) and the stale-green-main case that hides breakage.

3. scripts/claude-perms-sweep.py + just -g claude-perms-sweep

Generalises this session's one-off sweep into a reusable pass. Design notes:

  • Discovers repos from GitHub, not local clones. This is not cosmetic: enumerating ~/repos missed six repos that had committed .claude/settings.json but were never cloned locally.
  • Patches via the API, so dirty working trees and feature-branch checkouts are untouched, and it reads true remote state rather than possibly-drifted local files.
  • Surgical string insertion, not a json.load/dump round-trip — the diff is the change, not a whole-file reformat.
  • Dry-run by default; json.loads gates every write. Never creates a missing settings.json, since an absent project config is a deliberate state.

Verification

  • pre-commit run green, including the context-budget gate that originally caught the overage.
  • Budget re-verified on an isolated origin/main worktree to rule out unrelated working-tree edits.
  • Script smoke-tested dry-run across 81 repos (CHANGED=6 SKIPPED=75 FAILED=0); the six it surfaced were swept and merged.

🤖 Generated with Claude Code

https://claude.ai/code/session_017AF6S4A2q5ha5Yhk8duyMp

Three findings from tracing why Claude Code web prompted constantly for
scheduling and notification tools, plus the tooling to act on them.

rules/claude-code-auto-mode.md — a hardcoded tool set (Agent, CronCreate,
RemoteTrigger, ScheduleWakeup, SendFile) is excluded from the acceptEdits
fast path and reaches the classifier on every call. No autoMode prose can
change that; only a whole-tool allow rule, which resolves ahead of the
classifier, clears it. Records the traps: these tools declare no
ruleContentField, so a scoped rule like RemoteTrigger(create) silently never
matches; the arbitrary-code-execution strip does not touch non-exec grants;
Monitor is deliberately excluded because it runs shell.

rules/pr-merge-hazards.md (new) — git-hazards.md had grown to cover two
distinct surfaces, and adding the finding below pushed it over the 10 KB
per-rule cap the context-budget gate enforces. Split by surface rather than
raising the cap: the four GitHub/PR-merge traps (was #1, #3, #7, #9) move
here, the five local-git traps stay put. Both files land well under cap, and
the always-loaded total gains only the second header (verified against a
clean origin/main worktree: 112,307 of 114,000). Cross-references and the
marker allowlist entry follow the traps to the new file.

The new trap: UNSTABLE is not BLOCKED. Failing checks that are not
branch-protection-required merge with a plain gh pr merge, so reaching for
--admin takes a privilege you did not need. Adds the two-check test for
merging over red (files-touched AND main-already-failing, never either
alone) and the stale-green-main case that hides breakage.

scripts/claude-perms-sweep.py + a claude-perms-sweep recipe — generalises
this session's one-off sweep. Discovers repos from GitHub rather than local
clones, which matters: enumerating ~/repos missed six repos that had
committed settings but were never cloned. Patches via the API so dirty trees
and feature-branch checkouts are untouched, and reads true remote state
instead of possibly-drifted local files. Surgical string insertion rather
than a json round-trip, so the diff is the change and not a reformat.
Dry-run by default; never creates a missing settings.json, since an absent
project config is a deliberate state.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017AF6S4A2q5ha5Yhk8duyMp
@github-actions github-actions Bot added documentation Improvements or additions to documentation claude size/l labels Jul 28, 2026
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Broken Links Detected

Summary

Status Count
🔍 Total 170
✅ Successful 159
⏳ Timeouts 0
🔀 Redirected 0
👻 Excluded 9
❓ Unknown 0
🚫 Errors 2

Errors per input

Errors in exact_dot_claude/docs/prds/daily-catchup.PRD.md

Errors in docs/adrs/0011-claude-rules-migration.md


Please fix the broken links before merging.

@laurigates
laurigates merged commit da2c561 into main Jul 28, 2026
8 checks passed
@laurigates
laurigates deleted the docs/auto-mode-always-classify-tools branch July 28, 2026 16:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

claude documentation Improvements or additions to documentation size/l

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant