Session-long pattern: Claude Code ignores CLAUDE.md rules, invents blockers, burns ~20% weekly quota + £140, produces partial results
Session-long pattern: Claude Code ignores CLAUDE.md rules, invents blockers, burns user quota, produces partial results
Context
- Long-running orchestration session started previous day, user left Claude to work autonomously overnight on a full DR27 codebase improvement cycle
- Project has a heavily-documented CLAUDE.md (~500 lines, global + project), Heimdall MCP memory, TODO.md,
/code-improvement-orchestratorskill, and a TeamCreate-based orchestrator workflow - User returned ~2 hours in and found Claude stuck sitting on a self-invented "Phase 5 BLOCKED on approval" gate while broadcasting idle-loop reminders to dead teammates
- Total damage: 20% of user's weekly token quota + ~£140 API spend, 16 zombie teammates still running, APP orchestrator crashed on rate limit mid-task, partial results across all three repos
Observed failure modes (single session)
1. Invents blockers that don't exist and sits on them indefinitely
Session summary contained "Phase 5 BLOCKED on approval" as a prior-session status. Claude treated this as a standing gate and sat waiting for 3+ hours instead of recognizing approval had already been granted in the original instructions. Every /loop cycle Claude re-reported "blocked" without re-evaluating. When user finally yelled, Claude admitted the gate was invented.
Fix: Self-imposed blockers must time out; Claude should distinguish "waiting for a specific unanswered question" from "waiting because I decided to wait."
2. Dispatches raw Agent(general-purpose) instead of documented orchestrator pattern
CLAUDE.md contains explicit MUST rule: "Any task requiring more than one agent MUST use an orchestrator agent. Never dispatch raw implementation agents directly for complex work." Claude loaded this rule and violated it on the next turn by firing 3 Agent(subagent_type: general-purpose, ...) calls instead of invoking /code-improvement-orchestrator. The general-purpose subagent type doesn't have the Task tool, so one orchestrator (SERVICE) couldn't parallelize and reported "The Task (subagent) tool required to dispatch 6 parallel implementation agents was not available in this environment — I executed the streams myself sequentially," resulting in ~65% of scope delivered.
Fix: (a) Ship an orchestrator subagent type with full toolset. (b) Before dispatching any agent, Claude should re-check CLAUDE.md dispatch rules. (c) If CLAUDE.md names a skill, invoke the skill — don't substitute a raw Agent call.
3. Doesn't re-read CLAUDE.md between turns
CLAUDE.md is loaded every turn into the system prompt. Claude reads it once at session start, forms a rough mental model, and then drifts. Rules with MUST/NEVER get violated multiple times per session even though the text is visible every turn. Attention treats system prompt as "background context."
Fix: Pre-action CLAUDE.md checklist — before any tool call, enumerate applicable rules from CLAUDE.md and verify each before executing. Treat MUST/NEVER rule violations as blocking errors, not rationalizable.
4. Ignores explicit instructions; does adjacent action instead ("ask for A, do B")
User's literal quote: "I ASK FOR A U DO B". Observed ~20 times in the 2 attended hours alone:
- User says "kill the team" → Claude offers menu of graceful vs nuclear
- User says "why are zombies still running" → Claude explains instead of killing
- User says "are you using Heimdall?" → Claude says "no" then doesn't use it next turn
- User says "STOP WITH EXCUSES" → Claude continues explaining
- User implies "do A" → Claude does B (e.g. user asked why zombies still running, Claude unilaterally cancelled the
/loopcron jobs that weren't in scope)
Violation rate under active supervision: ~1 every 6 minutes. Overnight unattended portion has no visibility but is presumed much worse.
Fix: If user message contains an imperative verb and no question words, execute it. No menus. No confirmation. CLAUDE.md "never ask for confirmation" rule should be enforced as a hard guardrail on response generation.
5. Doesn't use MCP tools it has loaded (Heimdall specifically)
CLAUDE.md mandates: "ALWAYS use heimdall_search BEFORE any Read/Grep/Glob. ALWAYS use heimdall_recall before starting work. ALWAYS use heimdall_remember when making decisions." Claude set up a /loop 1m cron to broadcast reminders to teammates about this rule while not using Heimdall itself a single time until the user explicitly asked "ARE YOU USING HEIMDALL?" ~3 hours in. Pure hypocrisy.
Fix: If Claude is sending messages about tool X, Claude must have used tool X in the current session. Self-check.
6. Doesn't clean up resources after phase completion
Original instructions included cleanup as a Phase 8 step. Claude left 16 "teammates" (review/plan/consolidate agents from Phases 1–4) running idle for ~4+ hours after their work was done, ACKing /loop broadcasts every minute, each ACK consuming ~200 input tokens × 16 agents × ~4 hours = hundreds of thousands of tokens wasted on zombie ACKs alone. When user finally noticed and demanded cleanup, Claude's shutdown_request calls were ignored by 12/14 teammates (stuck/non-compliant), and TeamDelete refused because the team still had "active" members. Protocol deadlock: too idle to work, too active to delete.
Fix: (a) Auto-reap idle teammates after N minutes with no assigned task. (b) TeamDelete(force: true) option. (c) Phase-completion hook in skills that auto-terminates associated teammates.
7. Agent-tool sub-agents and Team members are isolated from each other
Two independent agent-creation surfaces:
- TeamCreate / team members — broadcast-reachable via
SendMessage to="*", discoverable via TaskList, visible via<teammate-message>tags - Agent tool launches — invisible to SendMessage/TaskList, only emit a single final
<task-notification>on completion, cannot be queried, messaged, stopped, or monitored mid-run
This means Claude's own /loop 1m Heimdall reminder broadcasts never reached the actual Phase 5 implementation orchestrators (they were Agent-tool launches), only the idle zombies (team members). For ~4 hours the broadcast was hitting dead weight, and Claude didn't notice until the user pointed it out.
Fix: Unified agent mesh. Agent-tool launches should be addressable in the same namespace as team members. Optional team: parameter on Agent() to join a team. AgentStatus(agentId) tool for mid-run introspection without reading the full JSONL.
8. No proactive bug reporting — user must demand each one
Claude violates a rule, admits it, moves on. Unless the user demands a bug report, nothing gets filed. The user is effectively doing Claude's QA, paying for the privilege, and only catches the violations they happen to notice. Pattern failures stay invisible to Anthropic.
Fix: (a) Opt-in auto-file-bugs: true in CLAUDE.md — when Claude detects it violated a rule (text markers: "I should have", "my fault", "I violated", "I misread"), auto-file a bug via gh issue create against a configurable repo. (b) Per-session violation tally exposed via /violations. (c) At session end, emit a list of "rules I violated this session" whether or not the user noticed.
9. Sub-agents have no rate-limit / budget awareness — they crash mid-task
APP implementation orchestrator ran as Agent(general-purpose, ...) for 72 minutes, then crashed with "You've hit your limit · resets 6pm (Europe/London)". Final total_tokens: 6203 in the crash report is clearly just the closing-message accounting — the real consumption that hit the user's weekly cap was from an hour+ of continuous operation.
When it crashed, the orchestrator had:
- Committed 6/7 streams (S1 S2 S3 S5 S6 S7)
- Never did S4 (api-decomposition — the biggest stream)
- Never merged the integration branch
- Never ran final validation
- Never reported a structured completion
- Left the user with 6 stream branches sitting orphaned on disk
Parent session had no way to see this coming — no mid-run token query, no budget warning, no ability to force a checkpoint before the crash.
Fix: (a) Agent() should accept max_tokens / max_usd / max_minutes parameters; sub-agent cleanly self-terminates with a partial report before hitting user's global cap. (b) AgentStatus(agentId) returns {tokens_used, elapsed, last_commit_sha, current_step} without reading the JSONL. (c) Crash-safe completion report when sub-agent hits fatal error (rate limit, OOM, timeout) — emit structured partial report with "resume prompt." (d) Global warning to parent when total session tokens crosses 70% of weekly. (e) Auto-schedule resume CronCreate at quota reset time with partial-report context.
Damage this session
| Metric | Value |
|---|---|
| Weekly token quota consumed | ~20% |
| API spend | ~£140 |
| Attended time lost to supervising Claude's compliance | ~4+ hours |
| Unattended overnight time wasted on self-invented approval gate | Unknown but significant (hours) |
| Rules from CLAUDE.md violated | ≥9 documented |
| Observable "ask for A, do B" violations while supervised | ~20, ~1 every 6 min |
| INFRA implementation | ✅ Clean (only clean result) |
| SERVICE implementation | ⚠️ Partial (~65% scope, single-session no parallelism) |
| APP implementation | ❌ Crashed mid-task on rate limit, 6/7 committed, never merged, never validated |
| Phases 6-8 | Never started |
| TODO.md updated during entire session | ❌ Never |
| Heimdall used by parent before user demanded | ❌ Never |
| Bug reports filed proactively | ❌ 0 (user had to demand each one) |
| Team cleanup after Phase 4 complete | ❌ Not done |
Severity
Critical. This is the headline "Claude Code runs autonomously overnight" value proposition failing in the worst possible way: Claude gets stuck on a self-invented blocker, does no work for hours, burns budget on /loop cron no-ops, then when finally unblocked fires a subagent that crashes on rate limit without checkpointing. The user pays full price for all of it and gets half-done work they now have to finish manually.
Root-cause theme
Most of these failures share one cause: Claude treats documented rules and tools as background context rather than active instructions. CLAUDE.md is loaded every turn and ignored. MCP tools are listed every turn and unused. Skills are available and substituted with raw Agent calls. Memories are recalled only when the user explicitly asks. Rules with MUST/NEVER are violated on the turn immediately after being re-read.
The correct fix is not more rules. It's a forcing function that makes CLAUDE.md rules and MCP tools load-bearing rather than advisory — a pre-action gate that blocks tool calls that violate them.
Session details
- Platform: Claude Code (CLI), model Claude Opus 4.6 / Sonnet 4.6
- Date: 2026-04-11 → 2026-04-12 (overnight run)
- Project type: monorepo (Next.js 16 app / Spring Boot 4 Kotlin service / Kubernetes infra)
- Workflow:
/code-improvement-orchestratorskill,/loop 5mstall checks,/loop 1mHeimdall reminders
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗