@ikunin/sprintpilot 2.0.9 → 2.1.0
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.
- package/README.md +245 -10
- package/_Sprintpilot/Sprintpilot.md +1 -1
- package/_Sprintpilot/bin/autopilot.js +581 -0
- package/_Sprintpilot/lib/orchestrator/action-ledger.js +148 -0
- package/_Sprintpilot/lib/orchestrator/adapt.js +502 -0
- package/_Sprintpilot/lib/orchestrator/decision-log.js +224 -0
- package/_Sprintpilot/lib/orchestrator/divergence.js +201 -0
- package/_Sprintpilot/lib/orchestrator/git-plan.js +259 -0
- package/_Sprintpilot/lib/orchestrator/impact-classifier.js +108 -0
- package/_Sprintpilot/lib/orchestrator/land.js +155 -0
- package/_Sprintpilot/lib/orchestrator/parallel-batch.js +99 -0
- package/_Sprintpilot/lib/orchestrator/profile-rules.js +167 -0
- package/_Sprintpilot/lib/orchestrator/report.js +95 -0
- package/_Sprintpilot/lib/orchestrator/state-machine.js +402 -0
- package/_Sprintpilot/lib/orchestrator/state-store.js +260 -0
- package/_Sprintpilot/lib/orchestrator/user-command-applier.js +157 -0
- package/_Sprintpilot/lib/orchestrator/user-commands.js +115 -0
- package/_Sprintpilot/lib/orchestrator/verify.js +397 -0
- package/_Sprintpilot/manifest.yaml +1 -1
- package/_Sprintpilot/modules/git/config.yaml +26 -0
- package/_Sprintpilot/scripts/agent-adapter.js +4 -5
- package/_Sprintpilot/scripts/auto-merge-bmad-docs.js +112 -0
- package/_Sprintpilot/scripts/dispatch-layer.js +12 -8
- package/_Sprintpilot/scripts/infer-dependencies.js +78 -21
- package/_Sprintpilot/scripts/inject-tasks-section.js +4 -3
- package/_Sprintpilot/scripts/land-this-pr.js +110 -0
- package/_Sprintpilot/scripts/lint-test-pitfalls.js +133 -0
- package/_Sprintpilot/scripts/list-remaining-stories.js +1 -1
- package/_Sprintpilot/scripts/log-timing.js +12 -3
- package/_Sprintpilot/scripts/merge-shards.js +32 -12
- package/_Sprintpilot/scripts/post-green-gates.js +187 -0
- package/_Sprintpilot/scripts/preflight-merge.js +2 -1
- package/_Sprintpilot/scripts/resolve-dag.js +3 -1
- package/_Sprintpilot/scripts/scan.js +109 -13
- package/_Sprintpilot/scripts/stack-snapshot.js +128 -0
- package/_Sprintpilot/scripts/state-shard.js +8 -1
- package/_Sprintpilot/scripts/summarize-timings.js +30 -12
- package/_Sprintpilot/scripts/with-retry.js +17 -5
- package/_Sprintpilot/skills/sprint-autopilot-on/SKILL.md +23 -1
- package/_Sprintpilot/skills/sprint-autopilot-on/workflow.orchestrator.md +148 -0
- package/_Sprintpilot/skills/sprintpilot-codebase-map/agents/architecture-mapper.md +9 -0
- package/_Sprintpilot/skills/sprintpilot-codebase-map/agents/concerns-hunter.md +9 -0
- package/_Sprintpilot/skills/sprintpilot-codebase-map/agents/integration-mapper.md +9 -0
- package/_Sprintpilot/skills/sprintpilot-codebase-map/agents/quality-assessor.md +9 -0
- package/_Sprintpilot/skills/sprintpilot-codebase-map/agents/stack-analyzer.md +10 -0
- package/_Sprintpilot/skills/sprintpilot-codebase-map/workflow.md +2 -0
- package/_Sprintpilot/skills/sprintpilot-reverse-architect/agents/component-mapper.md +7 -0
- package/_Sprintpilot/skills/sprintpilot-reverse-architect/agents/data-flow-tracer.md +7 -0
- package/_Sprintpilot/skills/sprintpilot-reverse-architect/agents/pattern-extractor.md +7 -0
- package/lib/core/update-check.js +11 -1
- package/package.json +1 -1
- package/_Sprintpilot/skills/sprint-autopilot-on/workflow.md +0 -1388
package/README.md
CHANGED
|
@@ -12,6 +12,8 @@ Sprintpilot drives [BMad Method](https://github.com/bmad-code-org/BMAD-METHOD) v
|
|
|
12
12
|
|
|
13
13
|
BMad Method's manual flow is dozens of skills, menus, and git operations per story. Sprintpilot drives all of it for you — one command per sprint.
|
|
14
14
|
|
|
15
|
+
Flow control is owned by a deterministic Node.js state machine (`_Sprintpilot/bin/autopilot.js`) that enforces the BMad 7-step sequence. The LLM keeps in-skill execution, diagnosis, triage, and small-judgment decisions; the orchestrator owns sequencing and BMad-step enforcement. BMad skills are invoked verbatim — Sprintpilot never invents workflows or templates of its own.
|
|
16
|
+
|
|
15
17
|
> **Independent project.** Sprintpilot is not affiliated with or endorsed by BMad Code, LLC. See [TRADEMARK.md](TRADEMARK.md).
|
|
16
18
|
>
|
|
17
19
|
> **Migrating from `bmad-autopilot-addon` v1?** See [MIGRATION.md](MIGRATION.md). `sprintpilot install` auto-detects v1 and cleanly replaces it.
|
|
@@ -57,12 +59,14 @@ When you run `/sprint-autopilot-on`, the autopilot drives your entire sprint to
|
|
|
57
59
|
|
|
58
60
|
The autopilot handles everything that normally requires you to be present:
|
|
59
61
|
|
|
62
|
+
- **Deterministic state machine** — `_Sprintpilot/bin/autopilot.js` emits typed Actions (`invoke_skill`, `run_script`, `git_op`, `parallel_batch`, `user_prompt`, `halt`) and consumes typed Signals (`success`, `failure`, `blocked`, `propose_alternative`, `user_input`, `verify_override`). The LLM executes one BMad skill at a time per action — it doesn't pick the next step.
|
|
63
|
+
- **BMad bookkeeping enforced** — `verify.js` checks more than artifact existence: acceptance-criteria bullets exist, `[ ]` task boxes are flipped to `[x]`, `commit_sha` + `branch` are reported, and `git_steps_completed: true` only after every step in the orchestrator's inlined git plan (including `git push`) exits 0. Skipping any of these produces a `verify_rejected` ledger entry and the orchestrator re-emits the same action.
|
|
64
|
+
- **Decision audit channel** — small judgment calls (architecture, test-strategy, dependency, review-triage, scope, workaround) attach as `decisions[]` on any signal. The orchestrator stamps id + timestamp + story and appends to `decision-log.yaml` — no separate skill round-trip required.
|
|
65
|
+
- **LLM-as-peer protocol** — when the orchestrator emits an action the LLM disagrees with, it can return a `propose_alternative` signal carrying a full alternative Action + reason; the orchestrator decides whether to route. When `verify.js` rejects a `success` signal the LLM knows is correct (e.g., a test file was renamed per a logged decision), the LLM can return `verify_override` with `evidence.expected_paths` + `decision_log_ref` and verification re-runs with augmented expectations. The state machine owns sequencing; the LLM owns judgment.
|
|
60
66
|
- **Auto-inferred story DAG** — after `bmad-sprint-planning`, the autopilot infers inter-story dependencies once and writes `_Sprintpilot/sprints/dependencies.yaml`. Parallel dispatch works out of the box; no hand-authored deps file required. Hand-authored sidecars are detected and respected silently.
|
|
61
67
|
- **Menu navigation** — BMad skills present menus and confirmations. The autopilot auto-selects "Continue" / "Create Mode" and derives answers from your PRD and architecture docs.
|
|
62
|
-
- **
|
|
63
|
-
- **Session management** — checkpoints state to disk after N stories (configurable). Re-running `/sprint-autopilot-on` in a fresh session resumes exactly where it left off — no work repeated.
|
|
68
|
+
- **Session management** — checkpoints state every N stories, halts with a markdown handoff report, and resumes exactly where it left off in the next session — with fingerprint-based divergence detection if anything moved in between. See [Sessions and the Handoff Report](#sessions-and-the-handoff-report).
|
|
64
69
|
- **Crash recovery** — on boot, the autopilot detects orphaned worktrees from a crashed previous run, pushes any committed-but-unpushed work, and cleans up stale state. No lost commits, no manual cleanup.
|
|
65
|
-
- **Fresh-context finalize** — when the last story of a sprint completes, the autopilot writes a `sprint-finalize-pending` marker and stops. The next session runs sprint cleanup deterministically in fresh context, eliminating context-rot failures of the final step.
|
|
66
70
|
|
|
67
71
|
### When it stops (and only when)
|
|
68
72
|
|
|
@@ -78,9 +82,22 @@ Everything else — it decides, documents the decision in one sentence, and move
|
|
|
78
82
|
|
|
79
83
|
## The Git Workflow
|
|
80
84
|
|
|
81
|
-
Controlled by
|
|
85
|
+
Controlled by knobs in `_Sprintpilot/modules/git/config.yaml`. The orchestrator inlines every git op as an argv sequence (`git add`, `git commit`, `git push`, …) into the emitted action — the LLM executes the steps verbatim, never improvises. Concurrent git operations (parallel pushes, submodule updates, ref locks) are serialized and retry with jittered backoff — safe under parallel dispatch.
|
|
86
|
+
|
|
87
|
+
### Pick a mode
|
|
88
|
+
|
|
89
|
+
| Mode | Knobs | One PR per | Code reaches `main` | Best for |
|
|
90
|
+
|---|---|---|---|---|
|
|
91
|
+
| **Stacked PRs** *(default)* | `merge_strategy: stacked` | story (or epic, on nano) | After human PR approval & merge | Team workflows where every story needs review before it lands |
|
|
92
|
+
| **Land-as-you-go** | `merge_strategy: land_as_you_go` + `land_when` | story | Right after each story (CI/review gated) | Solo / fast-iteration sprints where waiting for stack approval is the bottleneck |
|
|
93
|
+
| **Direct merge** | `push.create_pr: false` | — *(no PR opened)* | Right after each story's push | Prototypes, hobby projects, internal tools without CI |
|
|
94
|
+
| **Reuse your branch** | `reuse_user_branch: true` | sprint (one PR for all stories) | After human PR approval & merge | Feature-branch workflows where you already have the branch you want |
|
|
95
|
+
|
|
96
|
+
All modes use isolated worktrees (`.worktrees/<story-key>/`) so `main` never has half-finished story code. The autopilot tracks git metadata in its own `git-status.yaml` — it never modifies BMad Method's `sprint-status.yaml`. After each story's push, the orchestrator syncs `_bmad-output/` planning and bookkeeping artifacts onto the base branch, so `git log <base>` is the canonical sprint audit trail regardless of merge strategy.
|
|
97
|
+
|
|
98
|
+
### Stacked PRs (default)
|
|
82
99
|
|
|
83
|
-
|
|
100
|
+
Stories are pushed and PRs are created. No auto-merge. Each story branches from the previous story's branch and targets it. Reviewers see each story's diff in isolation while the next story is already in progress. When a PR is merged on the platform, subsequent PRs automatically retarget.
|
|
84
101
|
|
|
85
102
|
```
|
|
86
103
|
main ─────────────────────────────────────────────────────────
|
|
@@ -95,20 +112,198 @@ main ─────────────────────────
|
|
|
95
112
|
→ "Ready to merge: PR #42, #43, #44"
|
|
96
113
|
```
|
|
97
114
|
|
|
98
|
-
|
|
115
|
+
Trade-off: zero waiting for review during the sprint, but you end up with a stack to merge afterward.
|
|
116
|
+
|
|
117
|
+
### Land-as-you-go
|
|
118
|
+
|
|
119
|
+
After every `STORY_DONE`, the orchestrator runs a new `STORY_LAND` state to merge that story's PR immediately instead of letting the stack grow. Each subsequent story branches from the already-merged base, so there is no stack to unwind at sprint-end.
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
main ── story/1-1 ──→ PR #42 ──→ ✓ CI / review ──→ merge ──→
|
|
123
|
+
│ ╲
|
|
124
|
+
├── story/1-2 ──→ PR #43 ──→ ✓ CI / review ──→ merge ──→ ╲
|
|
125
|
+
│ ╲
|
|
126
|
+
└── story/1-3 ──→ PR #44 ──→ ✓ CI / review ──→ merge ──→ done
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
| Knob | Default | What it does |
|
|
130
|
+
|---|---|---|
|
|
131
|
+
| `land_when` | `ci_pass` | `no_wait` = merge synchronously, no CI wait. `ci_pass` = wait for `gh pr checks` (or platform equivalent) to report all checks green. `ci_and_review` = also wait for an `approved` PR review. |
|
|
132
|
+
| `land_wait_minutes` | `30` | Max wait for CI / review before the orchestrator halts and prompts you. |
|
|
133
|
+
|
|
134
|
+
**Rebase recovery.** If `main` moves while the story is in flight, the orchestrator runs `git rebase origin/<base>` and re-pushes. On rebase conflicts it halts with a `user_prompt`; resume reads `state.land_pending` and retries the land step after you resolve.
|
|
135
|
+
|
|
136
|
+
Trade-off: cleaner history and no end-of-sprint merge marathon, but each story blocks on CI before the next one starts — slower wall-clock if your CI is slow or you set `ci_and_review`.
|
|
99
137
|
|
|
100
|
-
|
|
138
|
+
### Direct merge (no PR)
|
|
139
|
+
|
|
140
|
+
Stories are merged straight into the base branch after push — no PR opened, no human review gate.
|
|
101
141
|
|
|
102
142
|
```
|
|
103
143
|
main ── story/1-1 ──→ merge ── story/1-2 ──→ merge ── story/1-3 ──→ merge
|
|
104
144
|
```
|
|
105
145
|
|
|
106
|
-
|
|
146
|
+
Use only when you genuinely don't want PRs (prototypes, tutorials, dev branches where you'll squash later). No CI gate, no review gate, no rebase recovery.
|
|
147
|
+
|
|
148
|
+
### Reuse your own branch
|
|
149
|
+
|
|
150
|
+
You create the branch yourself, then run the autopilot. It detects the current non-base branch on boot and commits **every** story directly onto it. No `story/*` or `epic/*` branches are created. One PR opens against `base_branch` at sprint-end.
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
main ─────────────────────────────────────────────────
|
|
154
|
+
│
|
|
155
|
+
└── feature/payments-rewrite (your branch, you created it)
|
|
156
|
+
├── feat(1): story 1-1 ─→ commit
|
|
157
|
+
├── feat(1): story 1-2 ─→ commit
|
|
158
|
+
├── feat(2): story 2-1 ─→ commit
|
|
159
|
+
└── … ─→ push + PR (→ main, at sprint-end)
|
|
160
|
+
```
|
|
107
161
|
|
|
108
|
-
|
|
162
|
+
Useful for feature-branch workflows where you already have the branch you want to work on, or when you want a single end-of-sprint review.
|
|
163
|
+
|
|
164
|
+
### Branch naming
|
|
165
|
+
|
|
166
|
+
Branches created by the autopilot use the `branch_prefix` knob (default `story/`):
|
|
167
|
+
|
|
168
|
+
- Story granularity (default, all profiles except nano): `<branch_prefix><story-key>` → `story/1-3-add-auth`
|
|
169
|
+
- Epic granularity (nano profile): `<branch_prefix>epic-<epic-id>` → `story/epic-1`
|
|
170
|
+
- Reuse mode: no autopilot branches; your existing branch is used as-is.
|
|
171
|
+
|
|
172
|
+
The `_bmad-output/` sync after each story uses the argv sequence `git switch <base> → git checkout <branch> -- _bmad-output → git commit --allow-empty → git push origin <base> → git switch <branch>` — the orchestrator inlines those steps; the LLM runs them verbatim.
|
|
173
|
+
|
|
174
|
+
### Pre-commit safety
|
|
175
|
+
|
|
176
|
+
Before every commit the orchestrator runs deterministic checks against the staged files. None of these require LLM cooperation — they're enforced by Node.js scripts:
|
|
177
|
+
|
|
178
|
+
| Check | What it does |
|
|
179
|
+
|---|---|
|
|
180
|
+
| **Explicit staging** | Files are staged by name (`git add -- file1 file2`) — never `git add -A`, `git add .`, or `git add -u`. The set of staged files is cross-referenced against the story's `## File List`; unexpected or missing files are warned. |
|
|
181
|
+
| **Secrets scan** | Greps staged content for `API_KEY`, `SECRET`, `TOKEN`, `PASSWORD`, `aws_access`, `private_key`. WARN severity by default — surfaced in the log but does not block the commit. Allowlist patterns live in `.secrets-allowlist`. |
|
|
182
|
+
| **File size** | Rejects files larger than `staging.max_file_size_mb` (default `1`). |
|
|
183
|
+
| **Binary detection** | Warns on binary files detected via `file --mime-encoding`. |
|
|
184
|
+
| **Gitignore check** | Verifies `.gitignore` covers `.autopilot.lock` and `.claude/.addon-backups/`. |
|
|
185
|
+
|
|
186
|
+
For each story, every commit (the main story commit + each code-review patch commit) runs the full check chain.
|
|
109
187
|
|
|
110
188
|
See [`modules/git/branching-and-pr-strategy.md`](_Sprintpilot/modules/git/branching-and-pr-strategy.md) for the full decision matrix.
|
|
111
189
|
|
|
190
|
+
## Sessions and the Handoff Report
|
|
191
|
+
|
|
192
|
+
A sprint usually doesn't fit in one LLM session. Long contexts rot — the model starts dropping steps, forgetting decisions, and skipping cleanup. Sprintpilot pre-empts this by checkpointing every N stories, halting cleanly, and resuming exactly where it left off in a fresh session.
|
|
193
|
+
|
|
194
|
+
### When the autopilot halts
|
|
195
|
+
|
|
196
|
+
| Trigger | What happens | How you resume |
|
|
197
|
+
|---|---|---|
|
|
198
|
+
| `session_story_limit` reached *(default 3, nano: 5)* | Orchestrator writes state + ledger, prints the report, releases the lock | Run `/sprint-autopilot-on` again — picks up at the next story |
|
|
199
|
+
| `sprint_finalize_pending` *(last story done)* | Orchestrator stops **before** cleanup — keeps that for a fresh context | Run `/sprint-autopilot-on` once more; finalize runs deterministically |
|
|
200
|
+
| Sprint complete | State + ledger files deleted; final report printed | Nothing to resume — the sprint is done |
|
|
201
|
+
| One of the 5 [true blockers](#when-it-stops-and-only-when) | Orchestrator halts with `user_prompt` | Answer the prompt, then `/sprint-autopilot-on` |
|
|
202
|
+
| Verify-reject budget exhausted | Orchestrator halts with the verifier's issues | Inspect, fix the underlying problem, then resume |
|
|
203
|
+
|
|
204
|
+
In every case, the same handoff report is emitted so you (and the next session) know exactly where things stand.
|
|
205
|
+
|
|
206
|
+
### The handoff report
|
|
207
|
+
|
|
208
|
+
Generated by `_Sprintpilot/lib/orchestrator/report.js` from the persisted state and the append-only `ledger.jsonl`. It's printed automatically whenever the autopilot halts at a session boundary, and you can re-print it on demand:
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
node _Sprintpilot/bin/autopilot.js report
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
The report is a single markdown block with five sections:
|
|
215
|
+
|
|
216
|
+
```markdown
|
|
217
|
+
# Autopilot Session Report
|
|
218
|
+
|
|
219
|
+
**Current story:** 1-3-add-auth
|
|
220
|
+
**Current phase:** PATCH_RETEST
|
|
221
|
+
**Sprint complete:** false
|
|
222
|
+
**Last updated:** 2026-05-15T10:42:18.041Z
|
|
223
|
+
|
|
224
|
+
## Ledger summary
|
|
225
|
+
- action_emitted: 47
|
|
226
|
+
- signal_recorded: 47
|
|
227
|
+
- decisions_appended: 12
|
|
228
|
+
- halt: 1
|
|
229
|
+
|
|
230
|
+
## Last 10 actions
|
|
231
|
+
- [2026-05-15T10:41:50Z] DEV_GREEN → invoke_skill bmad-dev-story
|
|
232
|
+
- [2026-05-15T10:42:01Z] CODE_REVIEW → invoke_skill bmad-code-review
|
|
233
|
+
- [2026-05-15T10:42:14Z] PATCH_APPLY → run_script post-green-gates.js
|
|
234
|
+
- …
|
|
235
|
+
|
|
236
|
+
## Recent decisions (3)
|
|
237
|
+
- [2026-05-15T10:38Z] story=1-3-add-auth phase=dev-story:RED ids=d-117,d-118
|
|
238
|
+
- [2026-05-15T10:40Z] story=1-3-add-auth phase=code-review ids=d-119
|
|
239
|
+
- …
|
|
240
|
+
|
|
241
|
+
## Recent halts
|
|
242
|
+
- [2026-05-15T10:42:18Z] phase=PATCH_RETEST reason=session_story_limit
|
|
243
|
+
|
|
244
|
+
## Next action
|
|
245
|
+
|
|
246
|
+
Run `autopilot next` to emit the action for phase=PATCH_RETEST on profile=medium.
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
What each section is for:
|
|
250
|
+
|
|
251
|
+
- **Header** — current story, phase, sprint-complete flag, last write timestamp. Quick "where are we?" snapshot.
|
|
252
|
+
- **Ledger summary** — counts of every kind of event in `ledger.jsonl`. Spikes in `halt` or `failure` indicate trouble.
|
|
253
|
+
- **Last 10 actions** — the most recent `invoke_skill` / `run_script` / `git_op` actions with their phase. The trail of what just ran.
|
|
254
|
+
- **Recent decisions** — small judgment calls the LLM attached as `decisions[]` (architecture / test-strategy / dependency / review-triage / scope / workaround). The audit trail of the LLM's work.
|
|
255
|
+
- **Recent halts** — the last 3 reasons the autopilot stopped. Empty on a healthy session.
|
|
256
|
+
- **Next action** — explicit hint of what running `/sprint-autopilot-on` (or `autopilot next`) will do next, including the `sprint_finalize_pending` special case.
|
|
257
|
+
|
|
258
|
+
### Resuming with divergence detection
|
|
259
|
+
|
|
260
|
+
On the next `autopilot start`, the orchestrator fingerprints `_bmad-output/`, `sprint-status.yaml`, and per-story branch HEADs against the fingerprint recorded at the last halt. If anything moved between sessions (you edited a story file by hand, merged a PR on the platform, force-pushed a branch, …) the orchestrator surfaces it as a `resume_divergence` action with a diff of what changed:
|
|
261
|
+
|
|
262
|
+
```json
|
|
263
|
+
{
|
|
264
|
+
"type": "user_prompt",
|
|
265
|
+
"prompt": "Resume divergence detected. Differences: branch story/1-2 HEAD moved (a1b2c3 → d4e5f6). Choose: force_continue | override_decision",
|
|
266
|
+
"kind": "resume_divergence",
|
|
267
|
+
"differences": { ... }
|
|
268
|
+
}
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
You answer via a `user_input` signal (`force_continue` to accept and keep going, `override_decision` to reject with a reason) and the state machine resumes. Nothing is silently overwritten.
|
|
272
|
+
|
|
273
|
+
### Steering the autopilot mid-session
|
|
274
|
+
|
|
275
|
+
The autopilot isn't fire-and-forget. The orchestrator scans the host chat for user interjections every turn; if you say something while it's running, the LLM records it as a `user_input` signal and the state machine reacts on the next transition. Available commands (validated server-side by `user-commands.js` — malformed input is rejected with a clear message, never silently dropped):
|
|
276
|
+
|
|
277
|
+
| Command | What it does |
|
|
278
|
+
|---|---|
|
|
279
|
+
| `force_continue` | Accept a `resume_divergence` or `verify_rejected` finding and keep going |
|
|
280
|
+
| `override_decision` | Reject the orchestrator's last decision with a reason; entry appended to `decision-log.yaml` |
|
|
281
|
+
| `skip_story` | Mark the current story as skipped (BMad-side sprint-status change) |
|
|
282
|
+
| `halt` | Stop cleanly at the next safe checkpoint |
|
|
283
|
+
| `inject_decision` | Append a free-form decision entry without changing flow |
|
|
284
|
+
|
|
285
|
+
You don't have to learn these commands by name — phrase the intent naturally and the LLM maps your message to the right command + arguments before signalling.
|
|
286
|
+
|
|
287
|
+
### Crash recovery and orphaned worktrees
|
|
288
|
+
|
|
289
|
+
If a session crashes — process killed, machine rebooted, hook failed mid-commit — the next `/sprint-autopilot-on` runs a health check on `.worktrees/` *before* any new state-machine work. Each worktree is classified and handled deterministically:
|
|
290
|
+
|
|
291
|
+
| Classification | Condition | What happens |
|
|
292
|
+
|---|---|---|
|
|
293
|
+
| `COMMITTED` | Branch has commits beyond `base_branch` | Worktree is reactivated; committed-but-unpushed work is pushed + PR'd |
|
|
294
|
+
| `CLEAN_DONE` | Story marked `done` in sprint-status, worktree clean | Worktree removed |
|
|
295
|
+
| `STALE` | No commits beyond base; story not done | Work was lost; worktree removed |
|
|
296
|
+
| `DIRTY` | Uncommitted changes | You're prompted: stash, commit, or discard |
|
|
297
|
+
| `ORPHAN` | Worktree directory exists but branch was deleted | Worktree removed |
|
|
298
|
+
|
|
299
|
+
Stale locks (`.autopilot.lock` older than 30 minutes) are also auto-removed at this stage, so a crashed session never blocks the next one indefinitely.
|
|
300
|
+
|
|
301
|
+
### Fresh-context finalize
|
|
302
|
+
|
|
303
|
+
When the last story of the sprint hits `STORY_DONE`, the state machine transitions to `sprint_finalize_pending` — a terminal halt state — instead of running cleanup in the same session that just finished the last story. The next `/sprint-autopilot-on` reads the pending marker, jumps straight to the finalize state, and runs deterministic cleanup (mark-done-stories task checkboxes, worktree removal, artifact commits, retrospective, final report) with a clean context window.
|
|
304
|
+
|
|
305
|
+
This trades one short extra session (~60–100 turns, usually under $2) for reliable end-of-sprint hygiene. Without it, the tail of a long session regularly drops cleanup actions because the context is already full of story implementation work.
|
|
306
|
+
|
|
112
307
|
## Adaptive Process Scaling
|
|
113
308
|
|
|
114
309
|
The right amount of process for a 2-story bug-fix sprint is different from a 30-story green-field rebuild — running the heavy flow on a small change costs more LLM turns, more context rot, more time. One knob picks the right balance:
|
|
@@ -134,7 +329,43 @@ Each can be disabled independently per profile in `_Sprintpilot/modules/autopilo
|
|
|
134
329
|
- **State sharding** — non-critical writes accumulate in `.pending/` shards, flushed atomically at story boundaries / session checkpoints / sprint complete. Crash-recovery keys still write straight through. This is what makes parallel dispatch safe under contention.
|
|
135
330
|
- **Conditional boot work** — on clean repos (main worktree only, no in-progress stories), skips the slow health-check / branch-reconciliation block, saving 8–30s per session. Disabled on `large` and `legacy` profiles, which always run full reconciliation.
|
|
136
331
|
- **Cached reads** — TTL + source-mtime aware file cache for hot reads; any writer's mtime advance auto-invalidates without explicit calls.
|
|
137
|
-
- **Parallel story dispatch** — when the host supports it, layer-aware dispatch runs N stories concurrently in their own worktrees, then merges their state shards. Claude Code today; Gemini CLI experimentally.
|
|
332
|
+
- **Parallel story dispatch** — when the host supports it, layer-aware dispatch runs N stories concurrently in their own worktrees, then merges their state shards. Claude Code today; Gemini CLI experimentally. See [Parallel Story Dispatch](#parallel-story-dispatch).
|
|
333
|
+
|
|
334
|
+
## Parallel Story Dispatch
|
|
335
|
+
|
|
336
|
+
When the active profile allows parallelism (`large` by default; opt-in on `medium`), the host supports concurrent subagents (Claude Code today; Gemini CLI experimentally), and the inferred DAG has ≥ 2 independent stories in the next layer, the orchestrator runs them concurrently instead of one after another:
|
|
337
|
+
|
|
338
|
+
1. **Resolve the next layer** — `resolve-dag.js layers --epic <id>` returns the next batch of stories with no unfinished prerequisites.
|
|
339
|
+
2. **Pre-create worktrees** — `dispatch-layer.js` creates one worktree per story and writes `.layer-plan.json` so each sub-agent knows its scope.
|
|
340
|
+
3. **Spawn N sub-agents in a single message** — each runs the full per-story flow (`bmad-create-story` → `bmad-dev-story` RED/GREEN → `bmad-code-review` → patches → commit/push/PR) inside its assigned worktree.
|
|
341
|
+
4. **Merge shards on return** — per-story state lives in `.autopilot-state/<story>.yaml` and `.decision-log/<story>.yaml` shards. `merge-shards.js --archive` collapses them into the project YAMLs atomically; the merged shards are archived under `.archive/layer-<id>/` for debugging.
|
|
342
|
+
5. **Loop to the next layer** — `parallel_batch` is a resolver in the state machine, not a one-shot. The orchestrator loops back to step 1 until the DAG is exhausted.
|
|
343
|
+
|
|
344
|
+
Per-story shards make this safe under contention: each sub-agent is the only writer of its shard, so concurrent YAML writes never corrupt each other. The coordinator (parent autopilot) is the only process that ever merges, and only at layer boundaries.
|
|
345
|
+
|
|
346
|
+
### Steering the DAG
|
|
347
|
+
|
|
348
|
+
After `bmad-sprint-planning`, the autopilot writes `_Sprintpilot/sprints/dependencies.yaml` with one inferred edge set per epic. Each story entry has a one-sentence `rationale` — review them once before parallel dispatch begins, because over-serialization (a spurious dependency the LLM inferred) silently slows the sprint instead of breaking it.
|
|
349
|
+
|
|
350
|
+
If detection got something wrong, edit the `overrides:` block:
|
|
351
|
+
|
|
352
|
+
```yaml
|
|
353
|
+
overrides:
|
|
354
|
+
- epic: 2
|
|
355
|
+
force_independent: ["2-1", "2-2"] # detection was over-cautious
|
|
356
|
+
force_sequential: ["2-3", "2-4"] # detection missed a known conflict
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
The next planning cycle regenerates only the `stories:` block; `overrides:` and `epics:` are preserved verbatim. Hand-authored sidecars (no `# AUTO-INFERRED` marker) are detected and respected silently — no inference runs on top of them.
|
|
360
|
+
|
|
361
|
+
### Failure handling
|
|
362
|
+
|
|
363
|
+
| Failure | Response |
|
|
364
|
+
|---|---|
|
|
365
|
+
| One parallel story's tests fail | That story is isolated; siblings in the layer continue; downstream stories that depend on the failed one are blocked; reported at layer boundary |
|
|
366
|
+
| Merge conflict at layer boundary | Retry once after rebase; on second failure, abort that story and force sequential for the rest of the epic |
|
|
367
|
+
| `max_consecutive_conflicts` reached *(default 2)* | Parallelism auto-disables for the rest of the session, logged to `decision-log.yaml` |
|
|
368
|
+
| Worktree disk / permission failure | `parallel_batch` resolver downgrades to sequential per-profile |
|
|
138
369
|
|
|
139
370
|
## Multi-Agent Intelligence
|
|
140
371
|
|
|
@@ -292,7 +523,11 @@ All settings live in YAML files under `_Sprintpilot/modules/`. Most projects onl
|
|
|
292
523
|
| Setting | File | Default | What it controls |
|
|
293
524
|
|---------|------|---------|------------------|
|
|
294
525
|
| `complexity_profile` | `autopilot/config.yaml` | `medium` | One of `nano`/`small`/`medium`/`large`/`legacy` — picks the per-story flow + which v2 layers are enabled |
|
|
526
|
+
| `autopilot.implementation_flow` | `autopilot/config.yaml` | `full` (nano: `quick`) | `full` runs the 7-step BMad cycle; `quick` routes every story through `bmad-quick-dev` and boots fresh sessions directly at `NANO_QUICK_DEV` |
|
|
295
527
|
| `git.push.create_pr` | `git/config.yaml` | `true` | `true` = push + PR (no auto-merge), `false` = direct merge to base branch |
|
|
528
|
+
| `git.merge_strategy` | `git/config.yaml` | `stacked` | `stacked` keeps every story branch open until sprint-end; `land_as_you_go` merges each PR right after `STORY_DONE` (gated by `land_when` / `land_wait_minutes`) |
|
|
529
|
+
| `git.reuse_user_branch` | `git/config.yaml` | `false` | When `true`, autopilot commits every story onto the user's current branch instead of creating per-story / per-epic branches; one PR opens at sprint-end |
|
|
530
|
+
| `git.branch_prefix` | `git/config.yaml` | `story/` | Prefix for autopilot-created branches (e.g., `story/1-3-add-auth`, `story/epic-1`) |
|
|
296
531
|
| `git.lint.blocking` | `git/config.yaml` | `false` | `true` = lint errors halt the autopilot |
|
|
297
532
|
| `autopilot.session_story_limit` | `autopilot/config.yaml` | `3` (nano: `5`) | Stories per session before checkpoint. `0` = unlimited |
|
|
298
533
|
| `multi_agent.enabled` | `ma/config.yaml` | `true` | Enable parallel agent skills |
|
|
@@ -52,7 +52,7 @@ This unblocks parallel story dispatch (`parallel_stories: true` + `dispatch-laye
|
|
|
52
52
|
|
|
53
53
|
Independent of `session_story_limit`, the autopilot forces an extra session at end-of-sprint. When step 2 detects all stories are done, it writes `current_bmad_step = sprint-finalize-pending` to the state file and halts — it does **not** run step 10 (cleanup) in that session. The next `/sprint-autopilot-on` invocation reads the marker in step 1 and jumps directly to step 10 with a clean context window, where seven CRITICAL deterministic script calls run the cleanup (checkbox marking, worktree removal, lock release, artifact commit, sprint-complete state, verification, state-file delete).
|
|
54
54
|
|
|
55
|
-
This behavior is not configurable: it's a mitigation for late-session instruction decay that was reliably dropping cleanup actions in long single-session runs. The extra session is short (typically ~60-100 turns, under $2).
|
|
55
|
+
This behavior is not configurable: it's a mitigation for late-session instruction decay that was reliably dropping cleanup actions in long single-session runs. The extra session is short (typically ~60-100 turns, under $2). Enforced by the `sprint_finalize_pending` terminal state in `_Sprintpilot/lib/orchestrator/state-machine.js`.
|
|
56
56
|
|
|
57
57
|
---
|
|
58
58
|
|