workflow-fix: no recovery ladder when the subagent MODEL POOL is exhausted; reconciler site has no valid fallback
Highlight text on any card (body, plan, or an event) to anchor a comment, or leave a whole-task comment here. Mention @claude to summon a reply.
No comments yet.
Goal
Give the five Codex-ensemble review sites — and the reconciler in
particular — a defined recovery path when the SUBAGENT MODEL POOL is
exhausted, which today has none.
Provenance
- workflow_fix_target: .claude/rules/context-hygiene.md
- fingerprint: 1577da44cef4
- additional_targets: .claude/rules/codex-ensemble-review.md, .claude/skills/issue/SKILL.md, .claude/agents/reconciler.md
- verified-at-filing: n/a — hand-filed from #2387 round 5 (observed live), not routed
through a
workflow-fix-candidate v1block; the gap is the ABSENCE of a model-quota rung incontext-hygiene.md, confirmed by grep: the file's ladders cover refusal (a)-(g) and autocompact-thrash Class 1/2 only.
Surfaced live on #2387 round 5 (2026-08-29). The round-5 code review split
PASS (Claude) vs FAIL (Codex), which routes to the binding reconciler. Four
consecutive reconciler spawns died immediately on You've reached your Fable 5 limit, across ~1 h with escalating holds (0 / 10 / 30 min). No durable output
any time. The task cannot advance: a split verdict has exactly one sanctioned
resolver, and that resolver cannot be spawned.
The gap
.claude/rules/context-hygiene.md carries recovery ladders for the two known
subagent-death classes — spurious usage-policy refusals (rungs a-g) and
autocompact thrash (Class 1 reduced-window, Class 2 fixed-overhead). Neither
covers MODEL QUOTA EXHAUSTION, and the two documented escapes are both
structurally unavailable for it:
- Per-call model pin is inert.
CLAUDE_CODE_SUBAGENT_MODELin~/.claude/settings.jsonsits at the TOP of the resolution chain, above the Agent-toolmodelparameter. The refusal ladder already records this as the rung-(b2) PRECEDENCE CAVEAT and resolves it with "remove the env line and start a fresh session" — which an autonomous mid-run session cannot do, and which would break the prompt-cache key besides. - Cross-vendor Codex dispatch is structurally wrong AT THIS SITE. It is the refusal ladder's escape hatch, but the reconciler exists to adjudicate a Claude-vs-Codex disagreement; a Codex reconciler would rule on its own verdict. This is not a cost or quality objection, it is a validity one.
The retry pacing is also undefined, and the natural instinct is wrong. The 429
ladder (minute-boundary + escalating holds, "retry anyway" at the ~10 min cap)
assumes a per-minute bucket that replenishes continuously. A model quota pool
does not. On #2387 that mismatch produced three retries in 25 minutes that
could not have succeeded. The right analogue is the Codex quota sentinel
(.claude/cache/codex-quota-exhausted-until), which parses a reset time and
short-circuits dispatch until it passes — but no equivalent exists for the
Claude-side subagent model pool, and the error text names no reset time.
Scope
.claude/rules/context-hygiene.md— add a THIRD subagent-death class (model-quota exhaustion) beside refusal and thrash, with its own ladder and its own pacing note distinguishing quota pools from per-minute buckets..claude/rules/codex-ensemble-review.mdand.claude/skills/issue/SKILL.mdStep 5c — say what a site does when the binding resolver cannot be spawned at all. Today Step 5c defines PASS+PASS, FAIL+FAIL, and PASS-vs-FAIL, and assumes the third can always be resolved..claude/agents/reconciler.md— the site-specific note that cross-vendor substitution is invalid here, so the generic escape does not apply.
Acceptance
- A documented ladder for model-quota exhaustion, stating explicitly which generic escapes do NOT apply to the reconciler site and why (validity, not cost).
- A pacing rule that distinguishes quota pools from per-minute buckets, so a session does not run the 429 ladder against a quota wall.
- A defined terminal for the case where the pool stays exhausted long enough
that retrying is futile. Candidates, to be decided by the planner — do NOT
assume the first: (a) park via
epm:failure v1+status:blockedwith afailure_class: infrareason naming the pool, surfacing to the user, who holds the only real levers (/usage-credits, repinning the env var); (b) a[epm-inline-fallback]-tokened orchestrator composition, which the existing rule permits only for a workflow-fix task fixing this failure mode or refusal rung (c) — note this task IS such a workflow-fix task, so whether that carve-out should extend here is a real question, not a rhetorical one; (c) a persisted quota sentinel mirroring the Codex one, so later sessions short-circuit instead of re-discovering the wall. Whichever is chosen, the independence guarantee must be either preserved or its breach recorded in a durable, greppable form. - If (c) is adopted, the sentinel must fail OPEN exactly as the Codex one does — an unreadable or implausible sentinel never wedges dispatch off.
- Existing workflow-lint and spec tests stay green.
Notes for the planner
- Do NOT solve this by removing
CLAUDE_CODE_SUBAGENT_MODEL. The pin is deliberate and cross-project; the fix is a defined path when the pinned pool is dry. - The failure is silent in a specific way worth preserving against: the agent dies with an API error and no durable output, so a session that does not run the durable-verdict-first probe would mistake it for a no-show and could take a single-reviewer decision the site does not sanction. Any ladder here should restate that probe.
- Check whether the watcher should observe repeated model-quota deaths at all. Today nothing counts them, so a session can burn hours retrying with no external signal.