Skip to content

Resolved sprint-status re-drive ignores recorded spec_file and launches bare story key #630

Description

@givip

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

  1. A sprint-status story has an existing frozen spec with status: ready-for-dev.
  2. The story previously escalated.
  3. The operator resolves the escalation and re-arms it from scratch (no restore patch).
  4. 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

  1. Run a sprint-status story through a CRITICAL escalation after its spec has been recorded.
  2. Resolve it and run a normal from-scratch re-arm.
  3. Resume the run.
  4. 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

  1. Bare-key prompt bypassed build-auto's existing-spec ready-for-dev -> implement early route.
  2. Build-auto treated the key as freeform epic intent.
  3. Its epic-context cache freshness check considered the cache stale using worktree mtimes.
  4. It regenerated the tracked epic-context file.
  5. Its own clean-tree sanity check then observed that generated change.
  6. It halted as blocked with the equivalent condition:
dirty tree after required epic-context compilation
  1. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions