workflow-fix: crash-fix circuit-breaker → re-plan on spent fallback ladder
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.
Overview / Motivation
Auto-filed by the workflow-fix-on-bug protocol from a workflow-fix candidate
raised on task #664 (emitting agent: general-purpose deep-dive diagnostic,
PM-session routed). Task #664's autonomous /issue --auto crash-fix loop
reached round 18 against a pre-registered Option-A→Option-B gate fallback
ladder; the binding "route to planner, not another gauge tweak" instruction
had to be hand-written into the r18 code-review marker because no mechanical
guardrail enforced it.
Goal
Add a crash-fix circuit-breaker to the /issue recovery path that, when N
failures share the same (phase, failure_class, assert-tag) signature OR a
plan-enumerated Option A/B/... fallback set is exhausted for the same gate,
STOPS relaunching and routes to task.py set-status <N> planning +
re-invoke /adversarial-planner per pivot_criteria.plan_contradiction_replan
— and add the matching "enumerated-fallback-exhaustion" sub-clause to
workflow.yaml § pivot_criteria so the SKILL.md step and the orchestrator
prose point at one canonical predicate.
Workflow gap
- Bug observed: #664's crash-fix loop reached round 18 against a pre-registered Option-A→Option-B gate fallback with no mechanical circuit-breaker forcing a re-plan once the gate's enumerated escape options were spent; the route-to-planner instruction had to be hand-written into the r18 code-review marker.
- Why it is a workflow gap:
pivot_criteria.plan_contradiction_replanand the "~3 fundamentally different strategies then pivot" rule exist only as orchestrator-judgment PROSE. The/issuecrash-fix recovery path has no step that counts same-failure-class rounds (or detects "the plan's enumerated fallback options for this gate are spent") and auto-routes toset-status planning+/adversarial-planner. So an autonomous session can burn rounds (and GPU-hours) past the point the project's own pivot rule says to re-plan. - Confidence (emitter): medium
Proposed change (candidate diff sketch — refine in planning)
+ ### Crash-fix circuit-breaker (recovery path)
+ Before any Nth relaunch, scan events.jsonl epm:failure markers:
+ - if >= K (default 4) failures share the same (phase, failure_class, assert-tag) signature, OR
+ - if a plan-enumerated fallback set (e.g. §11 "Option A -> Option B") has been tried to exhaustion and the SAME gate still trips,
+ then DO NOT relaunch. Run `task.py set-status <N> planning` and re-invoke
+ `/adversarial-planner` with pivot scope naming the contradiction
+ (workflow.yaml § pivot_criteria.plan_contradiction_replan). Autonomous sessions
+ post `Decision: re-plan` and continue; do not park for the user unless the
+ re-plan concludes a Goal-level research call only the user can make.
Plus a new explicit sub-clause under workflow.yaml § pivot_criteria.plan_contradiction_replan:
the "enumerated-fallback-exhaustion" trigger — "the plan pre-registered a finite
escape ladder (e.g. Option A → Option B) and the ladder is spent while the same
gate still trips" — so both the SKILL.md circuit-breaker and the orchestrator
prose reference one canonical named predicate.
Scope / surfaces
- Primary targets:
.claude/skills/issue/SKILL.md,.claude/workflow.yaml - These two changes are COUPLED (the SKILL.md step references the workflow.yaml predicate) and MUST land together / stay consistent — that is why they are one task, not two.
- Grep before editing:
grep -niE 'pivot_criteria|plan_contradiction_replan|crash.?fix|circuit|fallback|fundamentally different strateg' .claude/skills/issue/SKILL.md .claude/workflow.yaml CLAUDE.mdand reconcile with the existing prose (do not duplicate the generic cap-3 pivot path; this is the narrower enumerated-ladder-exhaustion case). - Keep CLAUDE.md's "Autonomous mode: a self-defeating PLAN routes to /adversarial-planner re-plan" bullet consistent if you touch it.
Constraints / invariants
- Workflow-surface only — never experiment code,
configs/, ortasks/. scripts/workflow_lint.py --check-askspasses; ruff on any touched script passes; ifworkflow.yamlorCLAUDE.mdchange, they stay consistent with SKILL.md and the rule files.- This session runs under
EPM_WORKFLOW_FIX_SESSION=1and carries aworkflow_fix_target:Provenance line — it MUST NOT auto-route any of its own subagents' workflow-fix candidates (recursion guard).
Provenance
- workflow_fix_target: .claude/skills/issue/SKILL.md, .claude/workflow.yaml
- fingerprint: 6575b87f356d
target_file: .claude/skills/issue/SKILL.md bug_observed: Task #664's autonomous crash-fix loop reached round 18 against a pre-registered Option-A→Option-B gate fallback with no mechanical circuit-breaker forcing a /adversarial-planner re-plan once the gate's enumerated escape options are exhausted; the "route to planner not another tweak" instruction had to be written by hand into the r18 code-review marker. why_workflow_gap: The pivot_criteria.plan_contradiction_replan rule and the "~3 fundamentally different strategies then pivot" rule exist only as orchestrator-judgment prose; the /issue crash-fix recovery path has no step that counts same-failure-class rounds (or detects "the plan's enumerated fallback options for this gate are spent") and auto-routes to set-status planning + re-invoke /adversarial-planner. proposed_change: Add a crash-fix circuit-breaker step to the /issue recovery path — when N>=K (e.g. K=4) epm:failure markers share the same failure-class/phase signature OR a plan-enumerated Option A/B/... fallback set is exhausted for the same gate, STOP relaunching and route to task.py set-status planning + /adversarial-planner with explicit pivot scope, per pivot_criteria.plan_contradiction_replan. diff_sketch: |
-
Crash-fix circuit-breaker (recovery path)
- Before any Nth relaunch, scan events.jsonl epm:failure markers:
-
- if >= K (default 4) failures share the same (phase, failure_class, assert-tag) signature, OR
-
- if a plan-enumerated fallback set (e.g. §11 "Option A -> Option B") has been tried to exhaustion and the SAME gate still trips,
- then DO NOT relaunch. Run
task.py set-status <N> planningand re-invoke /adversarial-plannerwith pivot scope naming the contradiction- (workflow.yaml § pivot_criteria.plan_contradiction_replan). Autonomous sessions
- post
Decision: re-planand continue; do not park for the user unless the - re-plan concludes a Goal-level research call only the user can make. confidence: medium related_task: #664
Coupled prose follow-up (folded into this task per the coupling note above): workflow.yaml § pivot_criteria.plan_contradiction_replan should grow an explicit "enumerated-fallback-exhaustion" sub-clause so the SKILL.md circuit-breaker and the orchestrator prose point at one canonical predicate.