Repository navigation
feat(setup): refuse to end a turn while a gate the agent started runs - #600
Conversation
Quest-Claim: 5d51a606e06e6003
quest setup installs Claude Code Stop and SubagentStop hooks that refuse to end a turn while a background quest gate command the ending agent started still runs, and sets BASH_DEFAULT_TIMEOUT_MS to the 55-minute cap. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 11 minutes. View limit details
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. |
kixelated
left a comment
There was a problem hiding this comment.
Automated review by review (OpenAI)
Reviewed head: 5fba112
No blocking code findings. The direction is consistent with the goal: filter in-flight gates by the ending agent's transcript, retain a subagent's checkout when that same check blocks its stop, and install/remove both timeout settings without removing user-customized values.
P3 — README.md:1781–1782: the new PATH sentence accidentally replaces the beginning of the existing body-inspection explanation, leaving “as for the worktree --body, a body= field”. Restore “It checks only a body on the command line itself:” before the flags; the intact PATH requirement is already below at lines 1789–1790. This preserves the explanation of which command bodies the enforcement hook actually inspects.
Verification limits: GitHub-only static review of the patch, surrounding hook paths and added tests. No tests, builds, or live Claude Code hook executions performed; the PR's claimed background-task/transcript schema and lifecycle were not independently exercised.
(Written by review (OpenAI))

Summary
Finishes
quest/m0/token-waste/stop-hook.md(deleted here). A workflow audit found 64 of 107 coordinator follow-ups telling a child it ended its turn with a build in the background, which kills the build and leaves the thread idle.quest setupinstalls Claude CodeStopandSubagentStophooks (quest hook). In a repository that uses Quest, they refuse to end the turn while aquest gatecommand the ending agent started still runs in the background. The refusal names each command and tells the agent to block on it.quest setupalso setsenv.BASH_DEFAULT_TIMEOUT_MSto the cap (3300000, 55 minutes), so a long foreground command needs no timeout argument and no backgrounding.--removetakes out each timeout that still holds Quest's value.background_tasks(id, type, command) to both hooks. That list covers the whole session, subagents included, so ashelltask whose command runsquest gatecounts as this agent's only when its own transcript (transcript_pathfor Stop,agent_transcript_pathfor SubagentStop) holdsID: <task id>. Claude Code writes that line when it backgrounds a command, and a task notification does not use that form. With no transcript, every running gate counts. The gate itself records nothing, sosrc/cli/gate.tsis unchanged and nothing conflicts with moq-dev/quest#585 or the gate FIFO admission work.quest gatealready stops on cancellation, and Claude Code caps repeated Stop blocks.quest worktree hook's SubagentStop skips releasing the subagent's checkout when the same check refuses the stop. Otherwise Claude would continue the subagent, and its running build, after the scratch was deleted.usesQuestmoves fromhooks.tstorules.tsnext to the newrunningGates, soworktree-hook.tscan use it without an import cycle.The hook reaches a host only when its user reruns
quest setup. As of 2026-11-09 the maintainer's~/.claude/settings.jsonhas none of Quest's hooks and noBASH_DEFAULT_TIMEOUT_MS.Decisions
quest context(the quest's Goal says it should, but the hook covers only Claude Code withquest setuprun, while Codex and Claude agents without it read the sameassets/CONTEXT.md): ✅ (a) keepassets/CONTEXT.mdunchanged (rejected: (b) drop the backgrounding sentence for everyone; (c) per-agent hook context). Settled by the maintainer in /quest-complete on 2026-11-10. This PR does (a).Choices made without asking
quest gatecommands are refused, matching the Goal. Other background commands, such as a dev server a session left running on purpose, pass.quest gate(alsobun run --silent quest gate ...). A recipe that callsquest gateinsidejust testis not seen. The alternative was having the gate record its caller, which can't tell subagents apart, since they shareCLAUDE_CODE_SESSION_IDand the env has no agent id.Stoprefuses too:quest contextasks every agent to block on a gate in the same turn.background_tasks(older Claude Code) makesquest hookexit 1 with "upgrade Claude Code", following fail-loud. The worktree hook treats it as none, so worktree release still works on older versions.Public API
quest setupwrites two more hook entries (Stop,SubagentStop) andenv.BASH_DEFAULT_TIMEOUT_MS.quest hookhandlesStopandSubagentStop. No wire or on-disk format changes.Validation
quest gate just checkpassed.quest gate just testpassed on 5fba112. New tests cover refusal for this agent's gate, ignoring another agent's gate and non-gate commands, the no-transcript case, the non-Quest repository case, missingbackground_tasks, the default timeout written and removed, and the worktree hook keeping a gated subagent's checkout.Suggested follow-ups
quest setup: recommend leaving it to the token-waste epic's closing re-measure, which already does this, rather than a new quest.Stophook (the gate recordsCODEX_THREAD_ID, and the hook refuses while a gate from that thread lives): recommend dropping it for now. The audited failures were Claude subagents under T3 Code, and Codex's handling of a turn ending on a running process is unverified. Plan it if the re-measure shows Codex threads doing this.Caused by
No single PR caused this: it is agent behavior the prose rule did not prevent.
Models
Size: M
Implementer: Claude Code, Opus 5.5, medium effort
(Written by Claude Opus 5.5 with medium)
Review
Rewritten by
quest reviewafter each round.01a1c64e-2df1-7fd0-98aa-ffe2dce8435e, round 1No actionable bugs were found in the branch-only diff, and the implementation appears consistent with its intended behavior, though builds and tests were not run as instructed.