docs(rules): split PR/merge hazards out; add claude-perms-sweep - #346
Merged
Conversation
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
Contributor
|
| 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
- [404] https://docs.anthropic.com/claude-code/commands | Failed: Network error: Not Found
Errors in docs/adrs/0011-claude-rules-migration.md
- [ERROR] https://www.anthropic.com/engineering/claude-code-best-practices | Failed: Network error: error sending request for url (https://www.anthropic.com/engineering/claude-code-best-practices)
Full Github Actions output
Please fix the broken links before merging.
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.
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 setA 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. NoautoModeprose changes that; only a whole-tool allow rule, which resolves ahead of the classifier.Traps recorded alongside it:
ruleContentField, so a scoped rule likeRemoteTrigger(create)silently never matches — bare names only.Monitoris deliberately excluded — it runs shell.2.
rules/pr-merge-hazards.md(new) — a split, not a cap raisegit-hazards.mdhad 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:git-hazards.mdgit addatomicity, vanished staged file)pr-merge-hazards.md--mergedmisses squash, stacked-base auto-close, push-by-SHA,UNSTABLE≠BLOCKED)Cross-references and the marker-allowlist entry follow the traps to the new file. Verified against a clean
origin/mainworktree — the always-loaded total is 112,307 / 114,000, so the split costs only the second header.The new trap:
UNSTABLEis notBLOCKED. Failing checks that aren't branch-protection-required merge with a plaingh pr merge, so reaching for--admintakes 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-maincase that hides breakage.3.
scripts/claude-perms-sweep.py+just -g claude-perms-sweepGeneralises this session's one-off sweep into a reusable pass. Design notes:
~/reposmissed six repos that had committed.claude/settings.jsonbut were never cloned locally.json.load/dumpround-trip — the diff is the change, not a whole-file reformat.json.loadsgates every write. Never creates a missingsettings.json, since an absent project config is a deliberate state.Verification
pre-commit rungreen, including the context-budget gate that originally caught the overage.origin/mainworktree to rule out unrelated working-tree edits.CHANGED=6 SKIPPED=75 FAILED=0); the six it surfaced were swept and merged.🤖 Generated with Claude Code
https://claude.ai/code/session_017AF6S4A2q5ha5Yhk8duyMp