Summary
A from-scratch re-drive after resolving a sprint-status escalation retains the story's recorded task.spec_file, but the generic dev launcher ignores it and invokes bmad-build-auto with only the bare story key.
That prevents build-auto's explicit-spec early route from seeing the existing ready-for-dev spec. The session falls through to the freeform/epic planning route and can block on work that should never run during a resolved implementation re-drive.
In the observed run, the fallback route regenerated a tracked epic-context cache, dirtied its own worktree, then failed its subsequent clean-tree preflight. The run escalated again before implementation began.
Environment
- Observed with
bmad-loop 0.9.1
- Sprint-status source mode
scm.isolation = "worktree"
- Generic Codex dev adapter
- Upstream primitive:
bmad-build-auto
- The same bare-key branch is still present in the v0.10.0 source
Preconditions
- A sprint-status story has an existing frozen spec with
status: ready-for-dev.
- The story previously escalated.
- The operator resolves the escalation and re-arms it from scratch (no restore patch).
- The task retains a valid
spec_file.
The state immediately before the failing dispatch had the equivalent of:
source: sprint-status
phase: escalated
spec_file: _bmad-output/implementation-artifacts/spec-<story-key>.md
restore_patch: None
Steps to reproduce
- Run a sprint-status story through a CRITICAL escalation after its spec has been recorded.
- Resolve it and run a normal from-scratch re-arm.
- Resume the run.
- Inspect the next dev task's
prompt.txt.
Expected behavior
Because task.spec_file is known and re-arm has reset it to ready-for-dev, the dev prompt should explicitly identify that spec, for example:
/bmad-build-auto Resume the autonomous dev session on the ready-for-dev spec at `_bmad-output/implementation-artifacts/spec-<story-key>.md`.
That lets build-auto's first intent check route directly to implementation.
Actual behavior
The generated prompt contains only:
/bmad-build-auto <story-key>
The installed v0.9.1 implementation does this in Engine._generic_dev_prompt:
if feedback is None:
if task.restore_patch and task.spec_file:
return explicit_restore_prompt
return f"/{self._dev_skill()} {task.story_key}"
Thus, a normal resolved re-drive with task.spec_file and no restore patch is indistinguishable from an initial bare-key dispatch.
The v0.10.0 implementation appears to retain the same behavior:
https://github.com/bmad-code-org/bmad-loop/blob/v0.10.0/src/bmad_loop/engine.py
Observed failure chain
- Bare-key prompt bypassed build-auto's existing-spec
ready-for-dev -> implement early route.
- Build-auto treated the key as freeform epic intent.
- Its epic-context cache freshness check considered the cache stale using worktree mtimes.
- It regenerated the tracked epic-context file.
- Its own clean-tree sanity check then observed that generated change.
- It halted as blocked with the equivalent condition:
dirty tree after required epic-context compilation
- The orchestrator projected that generic blocked result as another CRITICAL escalation.
Only the generated context/result artifacts changed; implementation and verification never started.
Root cause
runs.rearm_escalation correctly retains task.spec_file and resets the spec to ready-for-dev, but Engine._generic_dev_prompt consults the recorded path only for:
- patch restoration, or
- deterministic-verification repair (
feedback is not None).
It does not consult it for an ordinary resolved, from-scratch re-drive.
Suggested fix
When feedback is None, prefer an explicit spec invocation whenever task.spec_file is present:
if feedback is None:
if task.restore_patch and task.spec_file:
return explicit_restore_review_prompt
if task.spec_file:
return (
f"/{self._dev_skill()} Resume the autonomous dev session on the "
f"ready-for-dev spec at `{task.spec_file}`."
)
return f"/{self._dev_skill()} {task.story_key}"
The wording is illustrative; the invariant is that a re-drive with a recorded spec must name that spec so build-auto takes its explicit-spec route.
Regression tests requested
- A fresh sprint-status attempt with no
spec_file still receives the bare story-key prompt.
- A normal re-armed task with
spec_file and no restore patch receives an explicit-spec prompt.
- Patch-restore re-drives retain the existing in-review wording.
- Verification-repair re-drives retain the existing feedback wording.
- Relative and worktree-rebased spec paths both resolve correctly.
- A resolved
ready-for-dev story reaches implementation without epic-context compilation or generic planning preflight.
Related issue
#123 is adjacent but not a duplicate: it concerns rollback behavior after a spec-only dirty attempt. This report concerns the earlier prompt-routing defect that sends a resolved re-drive through the wrong build-auto path.
Summary
A from-scratch re-drive after resolving a sprint-status escalation retains the story's recorded
task.spec_file, but the generic dev launcher ignores it and invokesbmad-build-autowith only the bare story key.That prevents build-auto's explicit-spec early route from seeing the existing
ready-for-devspec. The session falls through to the freeform/epic planning route and can block on work that should never run during a resolved implementation re-drive.In the observed run, the fallback route regenerated a tracked epic-context cache, dirtied its own worktree, then failed its subsequent clean-tree preflight. The run escalated again before implementation began.
Environment
bmad-loop 0.9.1scm.isolation = "worktree"bmad-build-autoPreconditions
status: ready-for-dev.spec_file.The state immediately before the failing dispatch had the equivalent of:
Steps to reproduce
prompt.txt.Expected behavior
Because
task.spec_fileis known and re-arm has reset it toready-for-dev, the dev prompt should explicitly identify that spec, for example:That lets build-auto's first intent check route directly to implementation.
Actual behavior
The generated prompt contains only:
The installed v0.9.1 implementation does this in
Engine._generic_dev_prompt:Thus, a normal resolved re-drive with
task.spec_fileand no restore patch is indistinguishable from an initial bare-key dispatch.The v0.10.0 implementation appears to retain the same behavior:
https://github.com/bmad-code-org/bmad-loop/blob/v0.10.0/src/bmad_loop/engine.py
Observed failure chain
ready-for-dev -> implementearly route.Only the generated context/result artifacts changed; implementation and verification never started.
Root cause
runs.rearm_escalationcorrectly retainstask.spec_fileand resets the spec toready-for-dev, butEngine._generic_dev_promptconsults the recorded path only for:feedback is not None).It does not consult it for an ordinary resolved, from-scratch re-drive.
Suggested fix
When
feedback is None, prefer an explicit spec invocation whenevertask.spec_fileis present:The wording is illustrative; the invariant is that a re-drive with a recorded spec must name that spec so build-auto takes its explicit-spec route.
Regression tests requested
spec_filestill receives the bare story-key prompt.spec_fileand no restore patch receives an explicit-spec prompt.ready-for-devstory reaches implementation without epic-context compilation or generic planning preflight.Related issue
#123 is adjacent but not a duplicate: it concerns rollback behavior after a spec-only dirty attempt. This report concerns the earlier prompt-routing defect that sends a resolved re-drive through the wrong build-auto path.