@ikunin/sprintpilot 2.2.31 → 2.3.1
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 +228 -415
- package/_Sprintpilot/Sprintpilot.md +76 -8
- package/_Sprintpilot/bin/autopilot.js +734 -68
- package/_Sprintpilot/lib/orchestrator/action-ledger.js +208 -0
- package/_Sprintpilot/lib/orchestrator/adapt.js +93 -15
- package/_Sprintpilot/lib/orchestrator/profile-rules.js +7 -16
- package/_Sprintpilot/lib/orchestrator/sprint-plan.js +488 -0
- package/_Sprintpilot/lib/orchestrator/state-store.js +9 -5
- package/_Sprintpilot/lib/orchestrator/user-command-applier.js +78 -0
- package/_Sprintpilot/lib/orchestrator/user-commands.js +114 -0
- package/_Sprintpilot/lib/orchestrator/verify.js +10 -17
- package/_Sprintpilot/manifest.yaml +4 -3
- package/_Sprintpilot/modules/autopilot/profiles/_base.yaml +18 -4
- package/_Sprintpilot/modules/git/config.yaml +15 -9
- package/_Sprintpilot/modules/ma/config.yaml +29 -27
- package/_Sprintpilot/scripts/dispatch-layer.js +12 -15
- package/_Sprintpilot/scripts/infer-dependencies.js +706 -254
- package/_Sprintpilot/scripts/log-timing.js +6 -10
- package/_Sprintpilot/scripts/merge-shards.js +21 -23
- package/_Sprintpilot/scripts/post-green-gates.js +3 -1
- package/_Sprintpilot/scripts/resolve-dag.js +452 -280
- package/_Sprintpilot/scripts/sprint-plan.js +1068 -0
- package/_Sprintpilot/scripts/state-shard.js +13 -5
- package/_Sprintpilot/scripts/summarize-timings.js +2 -3
- package/_Sprintpilot/skills/sprint-autopilot-on/SKILL.md +30 -2
- package/_Sprintpilot/skills/sprint-autopilot-on/workflow.orchestrator.md +36 -10
- package/_Sprintpilot/skills/sprintpilot-codebase-map/agents/architecture-mapper.md +10 -8
- package/_Sprintpilot/skills/sprintpilot-codebase-map/agents/concerns-hunter.md +11 -9
- package/_Sprintpilot/skills/sprintpilot-codebase-map/agents/integration-mapper.md +11 -9
- package/_Sprintpilot/skills/sprintpilot-codebase-map/agents/quality-assessor.md +10 -8
- package/_Sprintpilot/skills/sprintpilot-codebase-map/agents/stack-analyzer.md +11 -9
- package/_Sprintpilot/skills/sprintpilot-codebase-map/workflow.md +1 -1
- package/_Sprintpilot/skills/sprintpilot-dependency-graph/SKILL.md +63 -0
- package/_Sprintpilot/skills/sprintpilot-dependency-graph/workflow.md +227 -0
- package/_Sprintpilot/skills/sprintpilot-plan-sprint/SKILL.md +67 -0
- package/_Sprintpilot/skills/sprintpilot-plan-sprint/workflow.md +435 -0
- package/_Sprintpilot/skills/sprintpilot-sprint-progress/SKILL.md +53 -0
- package/_Sprintpilot/skills/sprintpilot-sprint-progress/workflow.md +169 -0
- package/lib/commands/install.js +186 -12
- package/package.json +1 -1
- package/_Sprintpilot/skills/sprintpilot-code-review/SKILL.md +0 -6
- package/_Sprintpilot/skills/sprintpilot-code-review/agents/acceptance-auditor.md +0 -51
- package/_Sprintpilot/skills/sprintpilot-code-review/agents/blind-hunter.md +0 -39
- package/_Sprintpilot/skills/sprintpilot-code-review/agents/edge-case-hunter.md +0 -46
- package/_Sprintpilot/skills/sprintpilot-code-review/workflow.md +0 -111
- package/_Sprintpilot/skills/sprintpilot-party-mode/SKILL.md +0 -6
- package/_Sprintpilot/skills/sprintpilot-party-mode/workflow.md +0 -138
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sprintpilot-plan-sprint
|
|
3
|
+
description: 'Build (or refresh) the Sprintpilot sprint plan at _bmad-output/implementation-artifacts/sprint-plan.yaml. Infers per-epic + cross-epic dependencies from epics.md + architecture.md + sprint-status.yaml, presents the DAG, lets the user curate which stories belong in the active plan, and persists the result. Triggered by /sprintpilot-plan-sprint, by the autopilot when a stale plan is detected, or by `replan_sprint` mid-flight. Replaces the manual `infer-dependencies.js` workflow for end users.'
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## STOP — read this entire file before doing anything
|
|
7
|
+
|
|
8
|
+
This skill writes the authoritative sprint plan at
|
|
9
|
+
`_bmad-output/implementation-artifacts/sprint-plan.yaml`. The plan
|
|
10
|
+
controls which story Sprintpilot runs next and in what order, with
|
|
11
|
+
dependency-aware priorities and optional external-tracker links.
|
|
12
|
+
|
|
13
|
+
Follow **`./workflow.md`** verbatim. The 14 steps it lists are not
|
|
14
|
+
suggestions — each one shells out to a primitive (`infer-dependencies.js`,
|
|
15
|
+
`resolve-dag.js`, `sprint-plan.js`) that validates inputs and updates
|
|
16
|
+
the plan atomically. Skipping a step or reordering them produces an
|
|
17
|
+
inconsistent plan that downstream phases (autopilot queue resolver,
|
|
18
|
+
reorder validator) will reject.
|
|
19
|
+
|
|
20
|
+
### Never improvise
|
|
21
|
+
|
|
22
|
+
- Never infer dependencies in chat — always pipe LLM JSON through
|
|
23
|
+
`node _Sprintpilot/scripts/infer-dependencies.js dry-run --epic <id>`
|
|
24
|
+
(or `--cross-epic`) first. The script enforces schema, unknown-key,
|
|
25
|
+
self-dep, cross-epic-isolation, missing-rationale, and cycle checks.
|
|
26
|
+
Hand-edited envelopes that bypass dry-run leave a plan that fails
|
|
27
|
+
validation on the next read.
|
|
28
|
+
- Never write directly to `sprint-plan.yaml` — route every mutation
|
|
29
|
+
through `node _Sprintpilot/scripts/sprint-plan.js` so atomic write,
|
|
30
|
+
schema validation, and `generated`/`auto_inferred_at` stamping happen.
|
|
31
|
+
- Never call an LLM "to plan the sprint" outside this skill. The skill
|
|
32
|
+
IS the LLM-driving layer; scripts never call models.
|
|
33
|
+
|
|
34
|
+
### Invocation modes
|
|
35
|
+
|
|
36
|
+
The skill responds to three callers:
|
|
37
|
+
|
|
38
|
+
1. **User-direct:** `/sprintpilot-plan-sprint` with no arguments.
|
|
39
|
+
Build a plan from scratch (or refresh existing one).
|
|
40
|
+
2. **Auto-derive:** the autopilot emits
|
|
41
|
+
`invoke_skill: sprintpilot-plan-sprint` with
|
|
42
|
+
`template_slots: { auto: true, reason, missing_keys?, removed_keys? }`
|
|
43
|
+
when a plan is missing/stale and the user opted in via
|
|
44
|
+
`autopilot.auto_plan_on_start: true`.
|
|
45
|
+
3. **Replan:** the autopilot emits the same action with
|
|
46
|
+
`template_slots: { replan: true, reason }` after the user issued
|
|
47
|
+
`user_input { kind: 'replan_sprint' }` mid-flight.
|
|
48
|
+
|
|
49
|
+
In every mode the skill follows the same 14-step workflow — only the
|
|
50
|
+
"present results" tone differs (auto/replan modes assume the user wants
|
|
51
|
+
a brief summary; user-direct mode is more conversational).
|
|
52
|
+
|
|
53
|
+
### When NOT to invoke
|
|
54
|
+
|
|
55
|
+
- BMad's `sprint-status.yaml` is missing → run `bmad-sprint-planning`
|
|
56
|
+
first; this skill has no work to do.
|
|
57
|
+
- `epics.md` or `architecture.md` missing in
|
|
58
|
+
`_bmad-output/planning-artifacts/` → halt with a clear message
|
|
59
|
+
asking the user to run `bmad-create-epics-and-stories` and
|
|
60
|
+
`bmad-create-architecture` first.
|
|
61
|
+
- The user only wants to see the existing DAG without editing →
|
|
62
|
+
use `node _Sprintpilot/scripts/resolve-dag.js render` directly;
|
|
63
|
+
no need to invoke this full skill.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
Follow the instructions in ./workflow.md.
|
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
# Sprintpilot — Sprint Plan Generation
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Build (or refresh) `_bmad-output/implementation-artifacts/sprint-plan.yaml`
|
|
6
|
+
— the authoritative sprint plan that drives autopilot story selection,
|
|
7
|
+
DAG-aware reordering, and external-tracker integration. Infers per-epic
|
|
8
|
+
+ cross-epic dependencies via piped LLM envelopes (validated server-side
|
|
9
|
+
by `infer-dependencies.js`), lets the user curate which stories belong
|
|
10
|
+
in the active plan, and persists everything atomically.
|
|
11
|
+
|
|
12
|
+
## Prerequisites
|
|
13
|
+
|
|
14
|
+
| Artifact | Path | Required |
|
|
15
|
+
|---|---|---|
|
|
16
|
+
| BMad sprint-status | `_bmad-output/implementation-artifacts/sprint-status.yaml` | yes |
|
|
17
|
+
| BMad epics | `_bmad-output/planning-artifacts/epics.md` | yes |
|
|
18
|
+
| BMad architecture | `_bmad-output/planning-artifacts/architecture.md` | yes |
|
|
19
|
+
|
|
20
|
+
If any required prerequisite is missing, halt with a `user_prompt`
|
|
21
|
+
naming the missing file and the BMad skill that produces it
|
|
22
|
+
(`bmad-sprint-planning`, `bmad-create-epics-and-stories`,
|
|
23
|
+
`bmad-create-architecture`). Do NOT attempt the workflow without them.
|
|
24
|
+
|
|
25
|
+
## Outputs
|
|
26
|
+
|
|
27
|
+
| File | Location | Purpose |
|
|
28
|
+
|------|----------|---------|
|
|
29
|
+
| `sprint-plan.yaml` | `_bmad-output/implementation-artifacts/` | Authoritative plan (read by autopilot + resolve-dag) |
|
|
30
|
+
| `sprint-plan-dag.mmd` | `_bmad-output/implementation-artifacts/` | Rendered mermaid DAG (refreshed on every plan write) |
|
|
31
|
+
| Archived legacy | `.archive/dependencies.yaml.migrated` | If a pre-v2.3.0 `_Sprintpilot/sprints/dependencies.yaml` existed |
|
|
32
|
+
|
|
33
|
+
## Conventions used below
|
|
34
|
+
|
|
35
|
+
- `<root>` = the project root passed via `--project-root` (or `cwd`).
|
|
36
|
+
- All scripts live under `_Sprintpilot/scripts/` — invoke via `node <path>`.
|
|
37
|
+
- LLM envelopes are JSON; you produce them, the script validates them.
|
|
38
|
+
- On any 3-iteration validation failure (per-epic OR cross-epic), the
|
|
39
|
+
skill writes `_bmad-output/implementation-artifacts/sprint-plan.yaml.partial`
|
|
40
|
+
with the last attempted envelope + errors header, writes the sentinel
|
|
41
|
+
`.sprint-plan-validation-failed`, and halts with a `user_prompt`
|
|
42
|
+
asking the user to inspect the partial.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Step 1 — Load Inputs
|
|
47
|
+
|
|
48
|
+
<action>Verify the three required artifacts exist:
|
|
49
|
+
- `_bmad-output/implementation-artifacts/sprint-status.yaml`
|
|
50
|
+
- `_bmad-output/planning-artifacts/epics.md`
|
|
51
|
+
- `_bmad-output/planning-artifacts/architecture.md`
|
|
52
|
+
|
|
53
|
+
If any is missing, halt with a `user_prompt` naming what's missing.</action>
|
|
54
|
+
|
|
55
|
+
<action>Read each into memory. Parse epics.md for the list of epic IDs.
|
|
56
|
+
Parse sprint-status.yaml for the list of story keys under
|
|
57
|
+
`development_status:` (or `stories:` for the alternate shape).</action>
|
|
58
|
+
|
|
59
|
+
<action>Read the existing plan if present:
|
|
60
|
+
```
|
|
61
|
+
node _Sprintpilot/scripts/sprint-plan.js read --project-root <root>
|
|
62
|
+
```
|
|
63
|
+
Note: `exists: true/false` + the full plan body when present. Used by
|
|
64
|
+
Step 3 to compute staleness and decide which epics need re-inference.</action>
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Step 2 — Migrate Legacy Dependencies (One-Shot)
|
|
69
|
+
|
|
70
|
+
<action>Check whether a pre-v2.3.0 sidecar exists at
|
|
71
|
+
`_Sprintpilot/sprints/dependencies.yaml`. If it does AND `sprint-plan.yaml`
|
|
72
|
+
is absent OR has an empty `dependencies.stories` block, run the
|
|
73
|
+
one-shot migration:
|
|
74
|
+
```
|
|
75
|
+
node _Sprintpilot/scripts/infer-dependencies.js migrate --project-root <root>
|
|
76
|
+
```
|
|
77
|
+
The migrate command imports the legacy `stories:` + `overrides:` blocks
|
|
78
|
+
into the new plan, drops the legacy `epics:` block with a warning,
|
|
79
|
+
and moves the old file to `.archive/dependencies.yaml.migrated`.
|
|
80
|
+
|
|
81
|
+
If `migrated: false` and `reason: 'no_legacy_file'` — proceed silently.
|
|
82
|
+
If `migrated: false` for any other reason — surface the message in a
|
|
83
|
+
`user_prompt` and ask whether to continue with a fresh plan.</action>
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Step 3 — Staleness Check
|
|
88
|
+
|
|
89
|
+
<action>Compute which epics need re-inference. The cheap way is to
|
|
90
|
+
ask the orchestrator helper:
|
|
91
|
+
```
|
|
92
|
+
node -e "
|
|
93
|
+
const m = require('./_Sprintpilot/lib/orchestrator/sprint-plan.js');
|
|
94
|
+
console.log(JSON.stringify(m.planStaleness({projectRoot: process.cwd()})));
|
|
95
|
+
"
|
|
96
|
+
```
|
|
97
|
+
Returns `{ stale: bool, reason, missing_keys?, removed_keys? }`.
|
|
98
|
+
|
|
99
|
+
Decision matrix:
|
|
100
|
+
|
|
101
|
+
| stale | reason | action |
|
|
102
|
+
|---|---|---|
|
|
103
|
+
| false | — | Skip Step 4 entirely (plan is fresh). Go to Step 5 unless invoked via /sprintpilot-plan-sprint with a "rebuild from scratch" intent. |
|
|
104
|
+
| true | `missing` | Run Step 4 for EVERY epic in epics.md. |
|
|
105
|
+
| true | `migration_needed` | Step 2 should have handled this — re-check; if still missing, run Step 4 for every epic. |
|
|
106
|
+
| true | `added_stories` | Run Step 4 only for the epics whose stories appear in `missing_keys`. |
|
|
107
|
+
| true | `removed_stories` | Run Step 4 for the epics affected (a missing story means the per-epic graph for that epic is stale). |
|
|
108
|
+
| true | `corrupt` | Halt with a `user_prompt` showing the corruption error + offering archive+regenerate. |
|
|
109
|
+
|
|
110
|
+
For hand-authored plans (no AUTO-INFERRED marker AND user-direct invocation
|
|
111
|
+
of /sprintpilot-plan-sprint without explicit "rebuild" intent), confirm
|
|
112
|
+
with a `user_prompt` before regenerating: "An existing plan has hand
|
|
113
|
+
edits in the `dependencies` block. Proceed with regeneration (loses the
|
|
114
|
+
edits) or skip per-epic inference and just refresh DAG render?"</action>
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Step 4 — Per-Epic Inference
|
|
119
|
+
|
|
120
|
+
<action>For each epic that needs (re-)inference, run a tight loop:
|
|
121
|
+
|
|
122
|
+
1. Generate the prompt:
|
|
123
|
+
```
|
|
124
|
+
node _Sprintpilot/scripts/infer-dependencies.js scaffold-prompt --epic <id> --project-root <root>
|
|
125
|
+
```
|
|
126
|
+
Stdout is the literal prompt — feed it back to yourself in chat as
|
|
127
|
+
the "next user message" to infer the dependencies. Read the four
|
|
128
|
+
files the prompt names; do not improvise based on memory.
|
|
129
|
+
|
|
130
|
+
2. Produce a JSON envelope of the EXACT shape:
|
|
131
|
+
```json
|
|
132
|
+
{
|
|
133
|
+
"version": 1,
|
|
134
|
+
"epic": "<id>",
|
|
135
|
+
"dependencies": { "<story-key>": ["<dep-key>", ...] },
|
|
136
|
+
"rationale": { "<story-key>": "1 sentence quoting the AC/file/architecture line" }
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
Stories with NO inbound deps are omitted from `dependencies`. Every
|
|
140
|
+
listed key needs a non-empty rationale. Cross-epic edges go through
|
|
141
|
+
Step 5 — don't put them here.
|
|
142
|
+
|
|
143
|
+
3. Validate via dry-run:
|
|
144
|
+
```
|
|
145
|
+
echo '<envelope>' | node _Sprintpilot/scripts/infer-dependencies.js dry-run --epic <id> --project-root <root>
|
|
146
|
+
```
|
|
147
|
+
On `valid: true`, proceed. On `valid: false`, the response carries
|
|
148
|
+
an `errors[]` array — fix the envelope and retry. Max 3 iterations
|
|
149
|
+
per epic. On 3rd failure, save the partial + sentinel and halt
|
|
150
|
+
(see "Conventions" above).
|
|
151
|
+
|
|
152
|
+
4. Commit the envelope:
|
|
153
|
+
```
|
|
154
|
+
echo '<envelope>' | node _Sprintpilot/scripts/infer-dependencies.js write --epic <id> --project-root <root>
|
|
155
|
+
```
|
|
156
|
+
`wrote: true, edges_inferred, edges_added, edges_removed` confirms
|
|
157
|
+
success. The script writes into `plan.dependencies.stories.*` while
|
|
158
|
+
preserving entries for other epics and the `overrides:` block.</action>
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Step 5 — Cross-Epic Detection
|
|
163
|
+
|
|
164
|
+
<action>Now that per-epic edges are in place, ask the LLM whether
|
|
165
|
+
any edges cross epic boundaries:
|
|
166
|
+
|
|
167
|
+
1. Generate the cross-epic prompt:
|
|
168
|
+
```
|
|
169
|
+
node _Sprintpilot/scripts/infer-dependencies.js scaffold-prompt --cross-epic --project-root <root>
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
2. Produce a JSON envelope:
|
|
173
|
+
```json
|
|
174
|
+
{
|
|
175
|
+
"version": 1,
|
|
176
|
+
"cross_epic_deps": [
|
|
177
|
+
{ "from_story": "<key>", "to_story": "<key>", "rationale": "<≤200 chars>" }
|
|
178
|
+
]
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
`from_story` depends on `to_story`. Both keys must belong to
|
|
182
|
+
DIFFERENT epics. If no cross-epic deps detected, send
|
|
183
|
+
`cross_epic_deps: []`.
|
|
184
|
+
|
|
185
|
+
3. Validate via dry-run:
|
|
186
|
+
```
|
|
187
|
+
echo '<envelope>' | node _Sprintpilot/scripts/infer-dependencies.js dry-run --cross-epic --project-root <root>
|
|
188
|
+
```
|
|
189
|
+
Validator checks: keys exist in sprint-status, from/to epics differ,
|
|
190
|
+
rationale present (≤200 chars), no duplicate of per-epic edges,
|
|
191
|
+
no cycle in the combined graph. Max 3 iterations.
|
|
192
|
+
|
|
193
|
+
4. Present each surviving edge to the user with its rationale:
|
|
194
|
+
```
|
|
195
|
+
Cross-epic edge detected:
|
|
196
|
+
2-1-foo depends on 1-3-add-auth
|
|
197
|
+
Rationale: needs auth context from 1-3 before integration
|
|
198
|
+
[a] accept [r] reject [s] skip remaining edges
|
|
199
|
+
```
|
|
200
|
+
Accept-all, reject-all, or per-edge. Rejected edges drop out;
|
|
201
|
+
accepted edges go through to write.
|
|
202
|
+
|
|
203
|
+
5. Commit accepted edges:
|
|
204
|
+
```
|
|
205
|
+
echo '<accepted envelope>' | node _Sprintpilot/scripts/infer-dependencies.js write-cross-epic --project-root <root>
|
|
206
|
+
```</action>
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## Step 6 — Issue Tracker Setup (Optional)
|
|
211
|
+
|
|
212
|
+
<action>Ask the user (single user_prompt):
|
|
213
|
+
> "Do you want to link stories to an external issue tracker
|
|
214
|
+
> (Jira / Linear / GitHub / GitLab)? [y/N]"
|
|
215
|
+
|
|
216
|
+
On `n` or skip — proceed to Step 7 without writing the `issue_tracker:`
|
|
217
|
+
block.
|
|
218
|
+
|
|
219
|
+
On `y` — collect:
|
|
220
|
+
- `provider`: one of `jira`, `linear`, `github`, `gitlab`
|
|
221
|
+
- `base_url`: full URL prefix (e.g., `https://co.atlassian.net`)
|
|
222
|
+
- `project_key`: the tracker's project key (e.g., `PROJ` for Jira)
|
|
223
|
+
|
|
224
|
+
Then call the sprint-plan primitive. Currently the simplest path is
|
|
225
|
+
to read the plan, set `plan.issue_tracker = { provider, base_url, project_key }`,
|
|
226
|
+
and write the whole plan back via `node _Sprintpilot/scripts/sprint-plan.js write`
|
|
227
|
+
(piping the modified plan to stdin). The script validates schema and writes
|
|
228
|
+
atomically.</action>
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
## Step 7 — Issue ID Capture (Optional)
|
|
233
|
+
|
|
234
|
+
<action>Ask the user (single user_prompt):
|
|
235
|
+
> "Capture external issue IDs for each epic/story? [Y]es / [n]o
|
|
236
|
+
> / [s]kip remaining for this epic / [p]attern (sequential IDs)"
|
|
237
|
+
|
|
238
|
+
On `n` — proceed to Step 8 without setting any `issue_id` fields.
|
|
239
|
+
|
|
240
|
+
On `Y` — loop through epics and stories. For each entity:
|
|
241
|
+
> "Issue ID for epic 1 (or skip)?"
|
|
242
|
+
> "Issue ID for story 1-3-add-auth (or skip)?"
|
|
243
|
+
|
|
244
|
+
`p` mode prompts once for a prefix (e.g., `PROJ-`) + starting number;
|
|
245
|
+
the skill assigns sequential IDs (`PROJ-100`, `PROJ-101`, …).
|
|
246
|
+
|
|
247
|
+
**Validation rules** — `setIssueId` rejects these inputs (re-prompt if
|
|
248
|
+
they appear; don't retry the same value):
|
|
249
|
+
- Any of: `[ ] < > | ; & \n \r` or ASCII control characters
|
|
250
|
+
- Any Unicode RTL/LTR override marks (``–``, ``–``)
|
|
251
|
+
- Length > 200 chars
|
|
252
|
+
|
|
253
|
+
Legitimate tracker IDs from Jira (`PROJ-101`), Linear (`LIN-42`),
|
|
254
|
+
GitHub (`org/repo#123`), and GitLab don't contain any of these. If a
|
|
255
|
+
user enters something like `PROJ;101` or pastes a URL with embedded
|
|
256
|
+
brackets, the validator throws — show the error and ask for a clean
|
|
257
|
+
ID. Don't loop on the same broken input.
|
|
258
|
+
|
|
259
|
+
For each captured ID, update the plan via read → mutate → write. The
|
|
260
|
+
relevant primitive is `setIssueId(entity_key, issue_id, { projectRoot })`
|
|
261
|
+
in `sprint-plan.js`; from this skill the simplest path is to bulk-edit
|
|
262
|
+
the plan in memory and write it once at the end of the loop.
|
|
263
|
+
|
|
264
|
+
Bulk skip options ensure this step doesn't become tedious on sprints
|
|
265
|
+
with many stories.</action>
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## Step 8 — Finalize Dependencies in Plan
|
|
270
|
+
|
|
271
|
+
<action>By this point Steps 4 + 5 have written `plan.dependencies.stories`
|
|
272
|
+
and `plan.cross_epic_deps`. Step 6/7 may have edited `issue_tracker`
|
|
273
|
+
and per-entity `issue_id`. Re-read the plan once to confirm:
|
|
274
|
+
```
|
|
275
|
+
node _Sprintpilot/scripts/sprint-plan.js read --project-root <root>
|
|
276
|
+
```
|
|
277
|
+
The plan should validate cleanly. If `exists: true, error: ...` →
|
|
278
|
+
something went wrong; halt with the error.</action>
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
## Step 9 — Build the Sprint-Wide DAG
|
|
283
|
+
|
|
284
|
+
<action>Compute the topological layering for presentation:
|
|
285
|
+
```
|
|
286
|
+
node _Sprintpilot/scripts/resolve-dag.js graph --project-root <root>
|
|
287
|
+
```
|
|
288
|
+
Returns `{ nodes, edges, layers, width, cycle }`. If `cycle.length > 0`,
|
|
289
|
+
the combined intra + cross-epic graph has a cycle (validator should
|
|
290
|
+
have caught this earlier; if reached, halt with the offending nodes
|
|
291
|
+
and ask the user to remove the bad edge).</action>
|
|
292
|
+
|
|
293
|
+
---
|
|
294
|
+
|
|
295
|
+
## Step 10 — Present the DAG
|
|
296
|
+
|
|
297
|
+
<action>Render a text-mode topological tree to the user:
|
|
298
|
+
```
|
|
299
|
+
Layer 1 (parallel-eligible width: <N>):
|
|
300
|
+
- 1-1-bootstrap
|
|
301
|
+
- 2-1-foo ← cross-epic upstream of 1-3
|
|
302
|
+
Layer 2:
|
|
303
|
+
- 1-2-models
|
|
304
|
+
Layer 3:
|
|
305
|
+
- 1-3-add-auth (depends on: 1-1, 1-2, 2-1)
|
|
306
|
+
...
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
Highlight cross-epic edges with `←` or `cross-epic →` annotations.
|
|
310
|
+
Show summary stats: total stories, total epics, max layer width
|
|
311
|
+
(indicates parallel potential for v2.4.0), count of missing issue IDs.</action>
|
|
312
|
+
|
|
313
|
+
<action>Also write the mermaid DAG file for visual review:
|
|
314
|
+
```
|
|
315
|
+
node _Sprintpilot/scripts/resolve-dag.js render --format mermaid --project-root <root>
|
|
316
|
+
```
|
|
317
|
+
Report the path to the user:
|
|
318
|
+
> "DAG rendered to `_bmad-output/implementation-artifacts/sprint-plan-dag.mmd`
|
|
319
|
+
> — preview in any markdown viewer (GitHub, VS Code with Mermaid Preview, etc.)."</action>
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
323
|
+
## Step 11 — Curation
|
|
324
|
+
|
|
325
|
+
<action>Ask the user which stories belong in this sprint plan:
|
|
326
|
+
> "Which stories do you want to run in this sprint?
|
|
327
|
+
> Default: ALL non-done stories.
|
|
328
|
+
> [Enter] accept default [e] edit selection [a:KEY] add [r:KEY] remove"
|
|
329
|
+
|
|
330
|
+
`Default: ALL non-done` means every story in sprint-status whose
|
|
331
|
+
status is not `done`. Excluded stories carry `plan_status: excluded`
|
|
332
|
+
in the plan — they remain visible in the file for context (e.g., as
|
|
333
|
+
upstreams of included stories) but are NOT picked by the queue resolver.</action>
|
|
334
|
+
|
|
335
|
+
<action>On `e` (edit), present a numbered list with `[x]` for included
|
|
336
|
+
and `[ ]` for excluded; the user toggles entries by number.</action>
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
## Step 12 — Validate Selection
|
|
341
|
+
|
|
342
|
+
<action>For each story marked included, every transitive upstream
|
|
343
|
+
(intra-epic AND cross-epic) must be either ALSO included OR already
|
|
344
|
+
done in sprint-status. Compute via the orchestrator helper:
|
|
345
|
+
```
|
|
346
|
+
node -e "
|
|
347
|
+
const m = require('./_Sprintpilot/lib/orchestrator/sprint-plan.js');
|
|
348
|
+
const plan = require('./_Sprintpilot/scripts/sprint-plan.js').read({projectRoot: process.cwd()});
|
|
349
|
+
const proposed = [/* user-selected keys */];
|
|
350
|
+
console.log(JSON.stringify(m.validateOrdering(proposed, plan, {projectRoot: process.cwd()})));
|
|
351
|
+
"
|
|
352
|
+
```
|
|
353
|
+
Returns `{ valid, violations: [{story, upstream, suggestion}] }`.
|
|
354
|
+
|
|
355
|
+
On `valid: false`, present each violation:
|
|
356
|
+
> "Story `1-3-add-auth` (included) depends on `1-1-bootstrap` which is
|
|
357
|
+
> not in the plan and not done. Options:
|
|
358
|
+
> [a] add `1-1-bootstrap` to the plan
|
|
359
|
+
> [r] remove `1-3-add-auth` from the plan
|
|
360
|
+
> [x] exclude `1-3-add-auth` (keeps it visible but won't run)"
|
|
361
|
+
|
|
362
|
+
Loop until `valid: true`. Excluded stories carry `plan_status: excluded`
|
|
363
|
+
and the validator treats them as terminal.</action>
|
|
364
|
+
|
|
365
|
+
---
|
|
366
|
+
|
|
367
|
+
## Step 13 — Write Plan
|
|
368
|
+
|
|
369
|
+
<action>Build the final plan object in memory:
|
|
370
|
+
- `schema_version: 1`
|
|
371
|
+
- `source: 'skill' | 'auto' | 'cli'` (use `auto` when invoked via
|
|
372
|
+
`template_slots.auto: true`, `skill` otherwise)
|
|
373
|
+
- `plan_id`: keep existing if re-running; generate fresh on first
|
|
374
|
+
curation
|
|
375
|
+
- `epics: []` — per-epic metadata captured in Step 1 (id, title)
|
|
376
|
+
- `stories: []` — per-story entries with `key`, `epic`, `title`,
|
|
377
|
+
`plan_status` (`pending` for included, `excluded` for excluded),
|
|
378
|
+
`issue_id` (from Step 7), `priority` (1-indexed in topological order),
|
|
379
|
+
`upstream` (denormalized from `plan.dependencies.stories.<key>.depends_on`),
|
|
380
|
+
`cross_epic_upstream` (denormalized from `plan.cross_epic_deps`),
|
|
381
|
+
`added_by: 'skill'`, `added_at`
|
|
382
|
+
- `dependencies`, `cross_epic_deps`, `overrides`, `notes` — preserved
|
|
383
|
+
from Steps 4-7
|
|
384
|
+
- `status.last_run_outcome: 'success'`, `status.last_run_at: <now>`,
|
|
385
|
+
`status.last_error: null`
|
|
386
|
+
|
|
387
|
+
Pipe to write:
|
|
388
|
+
```
|
|
389
|
+
echo '<plan-json>' | node _Sprintpilot/scripts/sprint-plan.js write --project-root <root>
|
|
390
|
+
```
|
|
391
|
+
The script validates schema, stamps `generated`, and atomically writes
|
|
392
|
+
via tmp+rename.</action>
|
|
393
|
+
|
|
394
|
+
<action>Re-render the DAG to reflect any curation changes:
|
|
395
|
+
```
|
|
396
|
+
node _Sprintpilot/scripts/resolve-dag.js render --format mermaid --project-root <root>
|
|
397
|
+
```</action>
|
|
398
|
+
|
|
399
|
+
---
|
|
400
|
+
|
|
401
|
+
## Step 14 — Report
|
|
402
|
+
|
|
403
|
+
<action>Summarize what was written:
|
|
404
|
+
> "Sprint plan written to
|
|
405
|
+
> `_bmad-output/implementation-artifacts/sprint-plan.yaml`.
|
|
406
|
+
>
|
|
407
|
+
> - **N** stories planned (M epics)
|
|
408
|
+
> - **X** cross-epic edges
|
|
409
|
+
> - **Y** stories excluded (kept for context)
|
|
410
|
+
> - **Z** stories without issue IDs
|
|
411
|
+
>
|
|
412
|
+
> First 5 in execution order:
|
|
413
|
+
> 1. 1-1-bootstrap
|
|
414
|
+
> 2. 1-2-models
|
|
415
|
+
> 3. ...
|
|
416
|
+
>
|
|
417
|
+
> Run `/sprint-autopilot-on` to begin execution, or
|
|
418
|
+
> `/sprintpilot-plan-sprint` again to refine."</action>
|
|
419
|
+
|
|
420
|
+
<action>If invoked via `template_slots.auto: true` or `replan: true`,
|
|
421
|
+
keep the summary shorter (1-2 sentences) and return cleanly so the
|
|
422
|
+
autopilot session resumes; do not block on confirmation.</action>
|
|
423
|
+
|
|
424
|
+
---
|
|
425
|
+
|
|
426
|
+
## Failure modes
|
|
427
|
+
|
|
428
|
+
| Symptom | Recovery |
|
|
429
|
+
|---|---|
|
|
430
|
+
| Prerequisite artifact missing | Halt with `user_prompt` naming the missing file + the BMad skill that produces it. |
|
|
431
|
+
| 3 consecutive validation failures (per-epic OR cross-epic) | Save `sprint-plan.yaml.partial` + `.sprint-plan-validation-failed` sentinel; halt asking the user to inspect. |
|
|
432
|
+
| Cycle in combined intra+cross graph | Halt with the offending nodes; ask the user to remove or re-rationalize the bad edge. |
|
|
433
|
+
| Plan write fails (disk full, permission) | The atomic tmp+rename is all-or-nothing — no torn state. Halt with the error message. |
|
|
434
|
+
| `sprint-plan.yaml` corrupt on entry to Step 3 | Offer archive+regenerate via `user_prompt`. |
|
|
435
|
+
| Skill invoked but `sprint-status.yaml` is empty | No stories to plan; halt and ask the user to run `bmad-sprint-planning` first. |
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sprintpilot-sprint-progress
|
|
3
|
+
description: 'Synthesize current sprint execution progress with LLM-layered judgment. Reads sprint-plan.yaml, sprint-status.yaml, and the autopilot ledger via `autopilot progress`; highlights stalls, repeated verify failures, retry loops, and stuck phases; suggests the next action (continue, narrow to a specific story, reorder, replan, abort). Use when you want a quick health check between autopilot sessions without scrolling through the raw ledger.'
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## STOP — read this entire file before doing anything
|
|
7
|
+
|
|
8
|
+
This skill is a **read-only diagnostic**. It does not change sprint-plan.yaml,
|
|
9
|
+
sprint-status.yaml, or any persisted autopilot state. The goal is to produce
|
|
10
|
+
a concise human-readable summary of where execution stands and what (if
|
|
11
|
+
anything) the user should do about it.
|
|
12
|
+
|
|
13
|
+
Follow **`./workflow.md`** verbatim. The three steps it lists are:
|
|
14
|
+
|
|
15
|
+
1. Collect the structured snapshot via `autopilot progress --json`.
|
|
16
|
+
2. Pull recent ledger entries for halt / verify / step context.
|
|
17
|
+
3. Synthesize a brief progress report with LLM judgment + one
|
|
18
|
+
recommended next action.
|
|
19
|
+
|
|
20
|
+
### Never improvise
|
|
21
|
+
|
|
22
|
+
- **No file writes.** This skill is observational. If the user wants to
|
|
23
|
+
reorder, add stories, mark something skipped, or replan — point them
|
|
24
|
+
at the appropriate user_input command or `/sprintpilot-plan-sprint`.
|
|
25
|
+
Don't try to fix things from this skill.
|
|
26
|
+
- **No state interpretation beyond what's in the ledger.** Don't
|
|
27
|
+
speculate about why a verify failed — just report what the ledger
|
|
28
|
+
says and recommend the user look at the relevant file.
|
|
29
|
+
- **No long-form output by default.** Default mode is ≤15 lines. If
|
|
30
|
+
the user asks for more detail, narrow to a story and read its
|
|
31
|
+
recent step events.
|
|
32
|
+
|
|
33
|
+
### When to invoke
|
|
34
|
+
|
|
35
|
+
- Between autopilot sessions to check whether anything halted that
|
|
36
|
+
needs intervention.
|
|
37
|
+
- When you (the LLM) just finished a long batch of stories and want
|
|
38
|
+
to know if anything's stuck before suggesting next moves.
|
|
39
|
+
- When the user asks "how's the sprint going?" / "where are we?" /
|
|
40
|
+
"is autopilot stuck?".
|
|
41
|
+
|
|
42
|
+
### When NOT to invoke
|
|
43
|
+
|
|
44
|
+
- For machine-readable output: call
|
|
45
|
+
`node _Sprintpilot/bin/autopilot.js progress --json` directly. This
|
|
46
|
+
skill adds LLM synthesis on top — pure JSON consumers don't need it.
|
|
47
|
+
- For full sprint reports: that's `bmad-sprint-status` (BMad-native,
|
|
48
|
+
reads sprint-status.yaml only).
|
|
49
|
+
- For build / deploy / CI status: not this skill's domain.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
Follow the instructions in ./workflow.md.
|