Nine and a Half Hours on a Prompt Nobody Saw
On 2026-10-15 Coop started a Claude Code worker in the background for todo #460, a change to Dad's browser app. Its first Write met a guard that Claude Code 2.1.301 had just added for background sessions: in a checkout other sessions may share, a background chat must isolate itself before its first edit. The worker did what the guard suggested. It made a git worktree under its own job folder and called EnterWorktree on it.
That call needs a person's permission. A background chat asks for it the only way it can, by stopping at a prompt and waiting. Remote Control, the door Dad uses to reach such a chat from his phone, never showed the prompt. So the chat sat there for nine and a half hours. Coop knew the whole time that something was wrong: its activity reading said needs_input. That was all it knew. The chief's escalation could only tell Dad to go and look, and "go and look" from a phone in another country is not an instruction anyone can follow.
Two different failures hid in that one incident. Coop could have known the answer to the question in advance, and did not give it. And when a chat truly does need a person, Coop could see that it waited, but not on what. This lesson is the repair of both, plus a third failure the repair itself caused the next day.
Answer the Question You Already Know
Should a Coop worker work in a separate worktree? Coop answered that long before the guard existed. A worker works on the checkout it was given, the one the assignment names, and when another session is in the same checkout the work envelope says so (Track 3's shared_checkout disclosure) and tells it to stage only its own files. A worktree under a job folder would put the work where no other session, no office pull and no review would look for it.
So since 2026-10-16 (todo #463) every Claude worker Coop starts carries two more flags: --settings '{"worktree":{"bgIsolation":"none"}}', which turns the background isolation guard off for that session, and --disallowedTools EnterWorktree, which takes the tool away entirely. Two details are worth stealing:
- Order matters.
--disallowedToolstakes every word up to the next option as a tool name, and the setup prompt is the last word on the command line. So the flags sit before--effort, whose option ends the list. Put them last, right ahead of the prompt, and the whole setup prompt would be read as one more tool to forbid. - The answer has to survive a restart. Claude's background daemon saves a session's launch options in its job record (
respawnFlags), so a session that is later woken (the next lesson) keeps both flags. An answer given once at launch and lost at the first wake would bring the same prompt back.
Notice what Coop did not do. It did not answer the permission prompt. It removed the question before it could be asked. Coop never answers a native permission prompt, and neither can the chief: a peer cannot grant Dad's permission. The flags are not a bypass of a decision Dad would make; they are a decision Coop's design already made, written where the CLI can read it.
What Is It Waiting On?
Some questions cannot be answered in advance: a worker asks which of two layouts Dad wants, or needs permission for a command nobody predicted. For those, the useful fact is not needs_input but the question itself. Claude's session registry never says what a chat waits on. Its transcript does.
Since #463 a needs_input reading carries a waiting_on line read from the last 256 KB of the chat's transcript:
- a tool call that never got a result is the question: a permission prompt for that call, quoted with its input;
- an
AskUserQuestioncall is quoted as its question with its choices; - an
ExitPlanModecall is an approval of its plan; - with no call pending, the chat's last words are what it asked.
The engine stores it as activity_waiting on the session and shows it everywhere the reading goes, as runtime.waiting_on. Now an escalation can say this chat wants permission to run this exact command, and where Dad answers it.
A Status That Outlived Its Cause
The repair shipped in the morning. By the evening it had raised a false alarm. On 2026-10-16 the worker for todo #467 went waiting in Claude's registry at 09:25:16, on a call to an MCP tool. Then it kept working: 21 more minutes, through a commit and a long git push, and ended its turn normally. The registry entry never moved again. The new detector trusted it and told Dad the chat was waiting on him, while Remote Control showed it running.
This is Track 4's oldest lesson in a new costume. Codex's observer called a running turn interrupted; Claude's registry called a working chat waiting. Both were honest reports, by another process, of a moment that had passed. So since todo #468 the registry's waiting is a hypothesis, and the transcript decides it:
- The wait is real while a call made no later than ten seconds after the status was written (
WAIT_SLACK; one reply's calls land seconds apart) still has no result. That call is quoted aswaiting_on. - A running command is not a question. Claude asks before it runs a command, so a
Bashcall whose command is running right now as a child shell of the chat's own process is working, not waiting. The host helper gained achildrenprimitive so this reads the same on any fleet Mac. - A transcript that moved on after the status, with no such call, means the status is stale: idle if the newest event ended the turn, otherwise working.
- With neither, the chat waits on its last words, as before.
The One Reading That Wakes the Chief
Track 6's lesson on waking says activity readings only record and never wake the chief, with one exception. Until #463 there was no exception; this is it. A chat that holds work and has read needs_input for fifteen minutes (NEEDS_INPUT_SECONDS; readings repeat on a heartbeat, so the wake comes at most a heartbeat later) makes every pending obligation on its bindings due at once, and unparks the parked ones: the chief parked them on what it knew, and a person-shaped wait is news. It happens once per waiting episode. The session remembers which episode it escalated (activity_escalated holds that episode's start), so a chat waiting for an hour wakes the chief once, not four times.
The chief's contract tells it what to do with the wake: escalate to Dad once, quoting waiting_on, and say where he answers it (the assignment's Remote Control link, or claude attach on the Mac that runs the chat). A new question after an earlier escalation is new evidence, so the chief's repeat guard lets it through. A chat stuck on a person is the one case where waiting quietly is the wrong default, because the only party who can unstick it is the one who does not know.