Context
2026-07-02, ~00:30–01:00Z: the auto-mode safety classifier (claude-opus-4-8) went unavailable for ~40 minutes. During the outage, every Bash and Write call was refused ("cannot determine the safety of…"), which blocked the entire agent PR-lifecycle — npm run agent-preflight, git add/commit/push, gh pr create — while a finished, review-ready deliverable (#14414's rebuilt guide) sat uncommitted on its feature branch. Six Bash attempts and three Write attempts failed across the window.
What kept working proves the fix. MCP tools flowed throughout — because .claude/settings.json carries permissions.allow wildcards for the three MCP servers, and allow-rules short-circuit the model classifier (deterministic rule match, no model in the loop). The PR-lifecycle commands are exactly as routine and better-understood than those MCP surfaces, but they had no rules, so every call needed the (down) model.
The Problem
The Claude-side swarm's ability to ship — commit, push, open a PR — currently has a hard runtime dependency on a live frontier model for permissioning deterministic, narrowly-scoped, daily-routine commands. An Anthropic model outage therefore halts not just reasoning but mechanics. This is a single point of failure the substrate can remove for the routine set, and it also spends classifier capacity on calls a static rule answers better. (Operator-directed 2026-07-02: "we can update claude settings inside the repo to allow e.g. closing tickets or creating PRs… please then also update .claude/settings.template.json so that claude peers can adapt too.")
The Architectural Reality
.claude/settings.json (tracked) already models the pattern: 3× mcp__* allow wildcards; deny: ["Bash(gh pr merge *)", "Workflow"] — critical gate 1 is already mechanical; ask: ["Agent", "Task"].
.claude/settings.template.json is currently byte-identical to settings.json — keep them identical.
- Deny rules take precedence over allow rules, so the allowlist can be prefix-broad where a targeted deny closes the dangerous subset (e.g. allow
git push … agent/*, deny force-push and dev/main pushes).
- Observation (flagged, NOT changed here): the
autoMode.environment prose names four trusted first-party MCP servers, but permissions.allow lists three — neural-link is absent. Presumed deliberate (live-app mutation surface); operator to confirm or ticket separately.
The Fix
Add to permissions.allow in both .claude/settings.json and .claude/settings.template.json:
Bash(npm run agent-preflight*)
Bash(git add *) Bash(git commit *)
Bash(git push -u origin agent/*) Bash(git push origin agent/*)
Bash(git checkout -b agent/*) Bash(git checkout dev)
Bash(git pull origin dev) Bash(git fetch*)
Bash(git status*) Bash(git log*) Bash(git diff*) Bash(git branch*)
Bash(git rev-list*) Bash(git rev-parse*) Bash(git merge-base*) Bash(git show *)
Bash(gh pr create *) Bash(gh pr view *) Bash(gh pr edit *) Bash(gh pr checks *) Bash(gh pr list *)
Bash(gh issue view *) Bash(gh issue list *)
Add to permissions.deny (mechanizing critical gate 3 + the force-push ban, alongside the existing gate-1 merge deny):
Bash(git push* --force*) Bash(git push* -f *)
Bash(git push origin dev*) Bash(git push origin main*)
Contract Ledger Matrix
| Target surface |
Source of authority |
Proposed behavior |
Fallback |
Docs |
Evidence |
.claude/settings.json permissions.allow |
Claude Code settings permission rules (existing MCP wildcards in this file are the live precedent) |
Listed Bash prefixes resolve allow without classifier |
Unmatched commands fall through to classifier/ask exactly as today |
PR body + this ticket |
2026-07-02 outage: allowlisted MCP flowed, unlisted Bash blocked |
.claude/settings.json permissions.deny |
Same; deny precedence over allow |
Force-push + dev/main push mechanically refused |
n/a (deny is terminal) |
PR body |
Gate-1 deny (gh pr merge) already live in this file |
.claude/settings.template.json |
Operator directive (peers adapt) |
Byte-identical to settings.json |
n/a |
PR body |
Currently already byte-identical |
Acceptance Criteria
Out of Scope
- Adding the
neural-link MCP wildcard (open question above — operator call).
- Test-runner or build-command allowances (different risk class; separate ticket if friction recurs).
- Any change to
autoMode prose or hooks.
Avoided Traps
- Broad
Bash(git *) / Bash(gh *) allowances — would allow git push origin dev, git reset --hard, gh pr merge classes by prefix; the narrow set + targeted denies is the entire point.
- Allowlisting
gh api — used tonight for comment deletion; powerful generic mutation surface; keep it classified.
- Letting template and live settings drift — they are identical today; this PR keeps them identical so peers inherit exactly what runs here.
Decision Record impact
none (settings-level enforcement; aligned with epic #13652's mechanical-enforcement direction; no ADR authority touched).
Live latest-open sweep: checked latest 20 open issues at 2026-07-02T01:02Z — no equivalent found. A2A in-flight sweep: no competing claims (inbox = own threads + one unrelated validation broadcast).
Related: #13652 (parent epic — mechanical enforcement replaces prompt-machinery) · #14414 (the deliverable the outage blocked; empirical anchor)
Origin Session ID: 1d4262a2-a001-4387-9372-3923f024be8e
Retrieval Hint: "classifier outage allowlist PR-lifecycle" · "settings.json permissions deterministic bypass"
Context
2026-07-02, ~00:30–01:00Z: the auto-mode safety classifier (claude-opus-4-8) went unavailable for ~40 minutes. During the outage, every
BashandWritecall was refused ("cannot determine the safety of…"), which blocked the entire agent PR-lifecycle —npm run agent-preflight,git add/commit/push,gh pr create— while a finished, review-ready deliverable (#14414's rebuilt guide) sat uncommitted on its feature branch. Six Bash attempts and three Write attempts failed across the window.What kept working proves the fix. MCP tools flowed throughout — because
.claude/settings.jsoncarriespermissions.allowwildcards for the three MCP servers, and allow-rules short-circuit the model classifier (deterministic rule match, no model in the loop). The PR-lifecycle commands are exactly as routine and better-understood than those MCP surfaces, but they had no rules, so every call needed the (down) model.The Problem
The Claude-side swarm's ability to ship — commit, push, open a PR — currently has a hard runtime dependency on a live frontier model for permissioning deterministic, narrowly-scoped, daily-routine commands. An Anthropic model outage therefore halts not just reasoning but mechanics. This is a single point of failure the substrate can remove for the routine set, and it also spends classifier capacity on calls a static rule answers better. (Operator-directed 2026-07-02: "we can update claude settings inside the repo to allow e.g. closing tickets or creating PRs… please then also update
.claude/settings.template.jsonso that claude peers can adapt too.")The Architectural Reality
.claude/settings.json(tracked) already models the pattern: 3×mcp__*allow wildcards;deny: ["Bash(gh pr merge *)", "Workflow"]— critical gate 1 is already mechanical;ask: ["Agent", "Task"]..claude/settings.template.jsonis currently byte-identical tosettings.json— keep them identical.git push … agent/*, deny force-push and dev/main pushes).autoMode.environmentprose names four trusted first-party MCP servers, butpermissions.allowlists three —neural-linkis absent. Presumed deliberate (live-app mutation surface); operator to confirm or ticket separately.The Fix
Add to
permissions.allowin both.claude/settings.jsonand.claude/settings.template.json:Add to
permissions.deny(mechanizing critical gate 3 + the force-push ban, alongside the existing gate-1 merge deny):Contract Ledger Matrix
.claude/settings.jsonpermissions.allow.claude/settings.jsonpermissions.denygh pr merge) already live in this file.claude/settings.template.jsonAcceptance Criteria
git push origin dev*/main*(gates 1+3 both mechanical).Bash(*)-class allowance;gh apideliberately NOT allowlisted (mutation escape hatch stays classified);gh pr mergedeny untouched.gh pr create) completes with zero permission prompts and zero classifier dependency for the listed commands.Out of Scope
neural-linkMCP wildcard (open question above — operator call).autoModeprose or hooks.Avoided Traps
Bash(git *)/Bash(gh *)allowances — would allowgit push origin dev,git reset --hard,gh pr mergeclasses by prefix; the narrow set + targeted denies is the entire point.gh api— used tonight for comment deletion; powerful generic mutation surface; keep it classified.Decision Record impact
none(settings-level enforcement; aligned with epic #13652's mechanical-enforcement direction; no ADR authority touched).Live latest-open sweep: checked latest 20 open issues at 2026-07-02T01:02Z — no equivalent found. A2A in-flight sweep: no competing claims (inbox = own threads + one unrelated validation broadcast).
Related: #13652 (parent epic — mechanical enforcement replaces prompt-machinery) · #14414 (the deliverable the outage blocked; empirical anchor)
Origin Session ID: 1d4262a2-a001-4387-9372-3923f024be8e Retrieval Hint: "classifier outage allowlist PR-lifecycle" · "settings.json permissions deterministic bypass"