@ikunin/sprintpilot 2.2.9 → 2.2.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -632,6 +632,39 @@ function composeRuntimeState(persisted, profile, projectRoot) {
632
632
  remainingStoriesInEpic = epicStories.length;
633
633
  }
634
634
 
635
+ // Catch-all guard: if state.phase REQUIRES a story_key to emit a
636
+ // coherent action AND we still don't have one after every resolution
637
+ // path (queue / validator / sprint-status), reset phase to flowStart.
638
+ //
639
+ // Real-world scenario: a previous orchestrator version nulled
640
+ // current_story (e.g., v2.2.4's overzealous rejection) but didn't
641
+ // reset state.phase. Persisted state ends up with current_story: null
642
+ // at story_done. v2.2.9's reset only fires inside the rejection branch,
643
+ // so a NULL story_key doesn't trigger it (no rejection to fire). This
644
+ // guard catches that case + any future bug class where story_key
645
+ // ends up null at a story-bound phase.
646
+ //
647
+ // The reset is safe: the next emission re-enters story-start (or
648
+ // PREPARE_STORY_BRANCH per the migration rule) and picks the next
649
+ // pending story from queue / sprint-status.
650
+ const STORY_BOUND_PHASES_CATCH_ALL = new Set([
651
+ STATES.CHECK_READINESS,
652
+ STATES.DEV_RED,
653
+ STATES.DEV_GREEN,
654
+ STATES.CODE_REVIEW,
655
+ STATES.PATCH_APPLY,
656
+ STATES.PATCH_RETEST,
657
+ STATES.STORY_DONE,
658
+ STATES.STORY_LAND,
659
+ ]);
660
+ if (!resolvedStoryKey && STORY_BOUND_PHASES_CATCH_ALL.has(phase)) {
661
+ process.stderr.write(
662
+ `[autopilot] WARN phase "${phase}" requires a story_key but none resolved (queue empty, sprint-status lookup didn't fire for this phase). ` +
663
+ `Resetting to ${flowStart} so next emission re-enters story-start.\n`,
664
+ );
665
+ phase = flowStart;
666
+ }
667
+
635
668
  return {
636
669
  phase,
637
670
  story_key: resolvedStoryKey,
@@ -1,6 +1,6 @@
1
1
  addon:
2
2
  name: sprintpilot
3
- version: 2.2.9
3
+ version: 2.2.10
4
4
  description: Sprintpilot — autopilot and multi-agent addon for BMad Method (git workflow, parallel agents, autonomous story execution)
5
5
  bmad_compatibility: ">=6.2.0"
6
6
  modules:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ikunin/sprintpilot",
3
- "version": "2.2.9",
3
+ "version": "2.2.10",
4
4
  "description": "Sprintpilot — autopilot and multi-agent addon for BMad Method v6: git workflow, parallel agents, autonomous story execution",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {