@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.
Files changed (47) hide show
  1. package/README.md +228 -415
  2. package/_Sprintpilot/Sprintpilot.md +76 -8
  3. package/_Sprintpilot/bin/autopilot.js +734 -68
  4. package/_Sprintpilot/lib/orchestrator/action-ledger.js +208 -0
  5. package/_Sprintpilot/lib/orchestrator/adapt.js +93 -15
  6. package/_Sprintpilot/lib/orchestrator/profile-rules.js +7 -16
  7. package/_Sprintpilot/lib/orchestrator/sprint-plan.js +488 -0
  8. package/_Sprintpilot/lib/orchestrator/state-store.js +9 -5
  9. package/_Sprintpilot/lib/orchestrator/user-command-applier.js +78 -0
  10. package/_Sprintpilot/lib/orchestrator/user-commands.js +114 -0
  11. package/_Sprintpilot/lib/orchestrator/verify.js +10 -17
  12. package/_Sprintpilot/manifest.yaml +4 -3
  13. package/_Sprintpilot/modules/autopilot/profiles/_base.yaml +18 -4
  14. package/_Sprintpilot/modules/git/config.yaml +15 -9
  15. package/_Sprintpilot/modules/ma/config.yaml +29 -27
  16. package/_Sprintpilot/scripts/dispatch-layer.js +12 -15
  17. package/_Sprintpilot/scripts/infer-dependencies.js +706 -254
  18. package/_Sprintpilot/scripts/log-timing.js +6 -10
  19. package/_Sprintpilot/scripts/merge-shards.js +21 -23
  20. package/_Sprintpilot/scripts/post-green-gates.js +3 -1
  21. package/_Sprintpilot/scripts/resolve-dag.js +452 -280
  22. package/_Sprintpilot/scripts/sprint-plan.js +1068 -0
  23. package/_Sprintpilot/scripts/state-shard.js +13 -5
  24. package/_Sprintpilot/scripts/summarize-timings.js +2 -3
  25. package/_Sprintpilot/skills/sprint-autopilot-on/SKILL.md +30 -2
  26. package/_Sprintpilot/skills/sprint-autopilot-on/workflow.orchestrator.md +36 -10
  27. package/_Sprintpilot/skills/sprintpilot-codebase-map/agents/architecture-mapper.md +10 -8
  28. package/_Sprintpilot/skills/sprintpilot-codebase-map/agents/concerns-hunter.md +11 -9
  29. package/_Sprintpilot/skills/sprintpilot-codebase-map/agents/integration-mapper.md +11 -9
  30. package/_Sprintpilot/skills/sprintpilot-codebase-map/agents/quality-assessor.md +10 -8
  31. package/_Sprintpilot/skills/sprintpilot-codebase-map/agents/stack-analyzer.md +11 -9
  32. package/_Sprintpilot/skills/sprintpilot-codebase-map/workflow.md +1 -1
  33. package/_Sprintpilot/skills/sprintpilot-dependency-graph/SKILL.md +63 -0
  34. package/_Sprintpilot/skills/sprintpilot-dependency-graph/workflow.md +227 -0
  35. package/_Sprintpilot/skills/sprintpilot-plan-sprint/SKILL.md +67 -0
  36. package/_Sprintpilot/skills/sprintpilot-plan-sprint/workflow.md +435 -0
  37. package/_Sprintpilot/skills/sprintpilot-sprint-progress/SKILL.md +53 -0
  38. package/_Sprintpilot/skills/sprintpilot-sprint-progress/workflow.md +169 -0
  39. package/lib/commands/install.js +186 -12
  40. package/package.json +1 -1
  41. package/_Sprintpilot/skills/sprintpilot-code-review/SKILL.md +0 -6
  42. package/_Sprintpilot/skills/sprintpilot-code-review/agents/acceptance-auditor.md +0 -51
  43. package/_Sprintpilot/skills/sprintpilot-code-review/agents/blind-hunter.md +0 -39
  44. package/_Sprintpilot/skills/sprintpilot-code-review/agents/edge-case-hunter.md +0 -46
  45. package/_Sprintpilot/skills/sprintpilot-code-review/workflow.md +0 -111
  46. package/_Sprintpilot/skills/sprintpilot-party-mode/SKILL.md +0 -6
  47. package/_Sprintpilot/skills/sprintpilot-party-mode/workflow.md +0 -138
@@ -46,6 +46,16 @@ const CRITICAL_KEYS = new Set([
46
46
  'current_bmad_step',
47
47
  'in_worktree',
48
48
  'patch_commits',
49
+ // Pre-existing divergence with state-store.js — story_queue was added
50
+ // there for crash-resume of `--stories` / `--epic` queues but was
51
+ // never mirrored here. Added in v2.3.0 Round 4 for symmetry; without
52
+ // it, a process killed mid-queue would lose the queue head from the
53
+ // pending buffer that hadn't flushed yet.
54
+ 'story_queue',
55
+ // v2.3.0 — verify-loop trackers must persist across crashes; see
56
+ // _Sprintpilot/lib/orchestrator/state-store.js for full rationale.
57
+ 'last_verify_issues_signature',
58
+ 'consecutive_identical_rejections',
49
59
  ]);
50
60
 
51
61
  const KIND_DIR = {
@@ -88,11 +98,9 @@ function validateKind(k) {
88
98
  }
89
99
 
90
100
  // Read BMad's `output_folder` config so a project that customized its
91
- // output location doesn't end up with shards split between
92
- // `_bmad-output/` (writer hardcoded) and `<output_folder>/` (reader
93
- // honoring config). Pre-2.0.8 this script ignored output_folder
94
- // entirely, contradicting sibling scripts (mark-done-stories-tasks.js)
95
- // that did read it.
101
+ // output location keeps shards in the configured directory. Sibling
102
+ // scripts (mark-done-stories-tasks.js) read the same config, so all
103
+ // writers stay consistent.
96
104
  function readOutputFolder(projectRoot) {
97
105
  const cfg = path.join(projectRoot, '_bmad', 'bmm', 'config.yaml');
98
106
  if (!fs.existsSync(cfg)) return null;
@@ -139,9 +139,8 @@ function pairEvents(events) {
139
139
  // mark-API records arrive already paired. Anomalous records
140
140
  // (clock_skew / over_threshold) are tallied separately and never
141
141
  // contribute to p50/p95/max — otherwise a single backstep or
142
- // stale marker poisons aggregates the way the v2.0.4 raw clamp
143
- // did before the split. duration_ms must be a finite non-negative
144
- // number; defensive against hand-edited shards.
142
+ // stale marker would poison the aggregates. duration_ms must be
143
+ // a finite non-negative number; defensive against hand-edited shards.
145
144
  //
146
145
  // Truthy comparison (not `=== true`) so a hand-edited shard with
147
146
  // `clock_skew: 1` or any other truthy value is still recognized
@@ -27,10 +27,38 @@ Follow **`./workflow.orchestrator.md`** verbatim. Flow control lives in
27
27
  is a HUMAN command. The autopilot's purpose is to drive without
28
28
  stopping until `session_story_limit`, a TRUE BLOCKER, retry-budget
29
29
  exhaustion, or `sprint_is_complete`. Heuristics like "PR opened,
30
- time for review" / "natural breakpoint" / "let CI catch up" are NOT
31
- valid reasons to pause see `workflow.orchestrator.md` § "Pause is
30
+ time for review" / "natural breakpoint" / "let CI catch up" /
31
+ "context budget" / "clean checkpoint" / "merge cadence" / any
32
+ meta-reasoning about session length, story count, or your own
33
+ resource usage are NOT valid reasons to pause. Phrases like
34
+ "User-initiated checkpoint to control session length / context" in
35
+ a `details` string are LLM self-narration even when the wrapper
36
+ claims user intent — see `workflow.orchestrator.md` § "Pause is
32
37
  human-only."
33
38
 
39
+ ### Don't over-defend signals
40
+
41
+ The verifier handles structural recovery for several common omission
42
+ patterns — so you don't need to over-echo fields that the runner /
43
+ git already prove:
44
+
45
+ - `dev_red`: if you omit `test_files`, the verifier auto-detects test
46
+ files from `git diff` + untracked files (per-language regex). If you
47
+ provide them but with repo-relative paths, the verifier resolves
48
+ them against `projectRoot`.
49
+ - `dev_green` / `patch_retest` / `nano_quick_dev`: if you omit
50
+ `tests_run`, the verifier accepts the runner's count.
51
+ - `story_done`: if you omit `git_steps_completed: true`, the verifier
52
+ probes `git cat-file -e <commit_sha>` + `git ls-remote --heads
53
+ origin <branch>` and accepts the signal when both succeed.
54
+ - `code_review`: findings recorded as a `### Review Findings` section
55
+ in the story file (the `bmad-code-review` convention) are accepted
56
+ alongside the legacy `_bmad-output/reviews/<key>.md` location.
57
+
58
+ Provide the canonical fields when you have them — they're the audit
59
+ trail. The recovery paths are for when the work is correct but the
60
+ signal echo is incomplete.
61
+
34
62
  `workflow.orchestrator.md` is the **sole authority** for the rest of the
35
63
  session.
36
64
 
@@ -6,8 +6,7 @@ state machine that enforces the BMad 7-step sequence. You own the
6
6
  *in-skill execution, diagnosis, triage, and small-judgment decisions* —
7
7
  not the flow.
8
8
 
9
- This file is the **≤150-line** authoritative workflow. It is the only
10
- workflow shipped — the v2.0.x prose `workflow.md` is gone.
9
+ This file is the **≤150-line** authoritative workflow.
11
10
 
12
11
  ## The loop
13
12
 
@@ -83,7 +82,7 @@ Wrap everything in `{ "status": "...", ... }` and pass to
83
82
  | `failure` | `reason`, `diagnosis` (first-class — fed back into next retry), `recoverable: boolean` |
84
83
  | `blocked` | `blocker_kind` (one of the 5 TRUE BLOCKERS or recoverable kinds), `details`, `user_input_needed`, `consecutive_count?` |
85
84
  | `propose_alternative` | `reason`, `alternative` (full Action object), `urgency_hint?` (raises impact only). Low impact → auto-accepted; medium / high → orchestrator stores the alternative in `state.pending_alternative` and emits `user_prompt`. The user accepts via `user_input` `{ kind: 'accept_alternative' }` or rejects via `force_continue` (both clear `pending_alternative`). |
86
- | `user_input` | `commands: UserCommand[]` (validated server-side; see user-commands.js). Kinds: `skip_story`, `abort_sprint`, `force_continue`, `override_decision`, `change_profile`, `pause` (cleanly halts THIS session; next `/sprint-autopilot-on` resumes), `accept_alternative` (dispatches the stored `pending_alternative`), `trigger_retrospective` (v2.2.31+ — force-routes to RETROSPECTIVE for the current epic regardless of `remaining_stories_in_epic`; use when the user explicitly says "close out epic N with retro" while non-terminal stories remain). **NEVER send `pause` on your own initiative** — see "Pause is human-only" below. |
85
+ | `user_input` | `commands: UserCommand[]` (validated server-side; see user-commands.js). Kinds: `skip_story`, `abort_sprint`, `force_continue`, `override_decision`, `change_profile`, `pause` (cleanly halts THIS session; next `/sprint-autopilot-on` resumes), `accept_alternative` (dispatches the stored `pending_alternative`), `trigger_retrospective` (force-routes to RETROSPECTIVE for the current epic regardless of `remaining_stories_in_epic`; use when the user explicitly says "close out epic N with retro" while non-terminal stories remain). **NEVER send `pause` on your own initiative** — see "Pause is human-only" below. |
87
86
  | `verify_override` | `evidence: { decision_log_ref?, explanation, expected_paths? }` — used when verify.js is wrong |
88
87
 
89
88
  ## Pause is human-only
@@ -148,11 +147,11 @@ bookkeeping you'd otherwise be tempted to skip:
148
147
  | Phase | Bookkeeping that MUST be true before you signal `success` |
149
148
  |---|---|
150
149
  | `prepare_story_branch` | Every step in `action.steps` exited 0 — HEAD is on `action.branch` (verify with `git rev-parse --abbrev-ref HEAD`). Emitted only when `git.granularity ∈ {story, epic}` AND `git.reuse_user_branch=false`. Under `reuse_user_branch=true` this phase is skipped — the user-locked branch is detected at cmdStart instead. |
151
- | `create_story` | Story file has an Acceptance Criteria section (heading level 2-4: `##`/`###`/`####`; title `Acceptance Criteria` or `AC`) with at least one list entry (`-`, `*`, or numbered `1.` / `1)`) AND a `## Tasks` (or `## Tasks/Subtasks`) section with at least one `[ ]` or `[x]` checkbox. v2.2.25+ relaxed cosmetic variants. |
152
- | `dev_red` / `dev_green` | Test files exist on disk; runner exit codes match the phase contract; `tests_run` matches the runner's count. If `test_files` is omitted (v2.2.17+), the verifier auto-detects them from `git diff` + untracked files filtered by language convention. If `tests_run` is omitted (v2.2.21/22+), the runner's count is accepted. Relative paths are resolved against `projectRoot` (v2.2.18+). |
153
- | `code_review` | Findings recorded in any of: (a) `### Review Findings` section in the story file (what `bmad-code-review` actually writes), (b) `_bmad-output/reviews/<story_key>.md` (legacy), or (c) `_bmad-output/implementation-artifacts/code-review-<story_key>.md` (older repos). `findings[]` carries `{id, severity, category, action: 'block'\|'patch'\|'defer', rationale}` for every finding. v2.2.17+ accepts all three locations. |
150
+ | `create_story` | Story file has an Acceptance Criteria section (heading level 2-4: `##`/`###`/`####`; title `Acceptance Criteria` or `AC`) with at least one list entry (`-`, `*`, or numbered `1.` / `1)`) AND a `## Tasks` (or `## Tasks/Subtasks`) section with at least one `[ ]` or `[x]` checkbox. |
151
+ | `dev_red` / `dev_green` | Test files exist on disk; runner exit codes match the phase contract; `tests_run` matches the runner's count. Relative `test_files` paths resolve against `projectRoot`. The verifier auto-detects `test_files` from `git diff` + untracked files (language-shape filter) when the LLM omits the array, and accepts the runner's `tests_run` when the LLM omits the count — so signal echo of these two fields is optional when the underlying work is correct. |
152
+ | `code_review` | Findings recorded in any of: (a) `### Review Findings` section in the story file (what `bmad-code-review` writes), (b) `_bmad-output/reviews/<story_key>.md`, or (c) `_bmad-output/implementation-artifacts/code-review-<story_key>.md`. `findings[]` carries `{id, severity, category, action: 'block'\|'patch'\|'defer', rationale}` for every finding. |
154
153
  | `patch_apply` | Every `patch_finding` id present in `state.patch_findings` is included in `applied_finding_ids`. |
155
- | `story_done` (and `nano_quick_dev`) | sprint-status.yaml shows this story as `done` (under `development_status.<story_key>` or inline). Story file has zero remaining `[ ]` task boxes — dev-story is responsible for flipping them to `[x]`. `commit_sha` and `branch` reported; `story_key` matches. **`git_steps_completed: true` in success output** — set this ONLY after every step in `action.steps` (the orchestrator's decorated git plan: `git add`, `git commit`, `git push -u origin <branch>`) has exited 0. If the flag is omitted, v2.2.17+ verifies the underlying git state directly: probes `git cat-file -e <commit_sha>` AND `git ls-remote --heads origin <branch>` — when both succeed and match, the signal is accepted. The flag remains the canonical signal; the probe is a recovery path. |
154
+ | `story_done` (and `nano_quick_dev`) | sprint-status.yaml shows this story as `done` (under `development_status.<story_key>` or inline). Story file has zero remaining `[ ]` task boxes — dev-story is responsible for flipping them to `[x]`. `commit_sha` and `branch` reported; `story_key` matches. **`git_steps_completed: true` in success output** — set this ONLY after every step in `action.steps` (the orchestrator's decorated git plan: `git add`, `git commit`, `git push -u origin <branch>`) has exited 0. The flag is the canonical signal; when omitted, the verifier probes `git cat-file -e <commit_sha>` AND `git ls-remote --heads origin <branch>` and accepts the signal when both succeed and the remote sha matches. |
156
155
  | `retrospective` | `_bmad-output/retrospectives/<epic>.md` exists. |
157
156
 
158
157
  Skipping any of these — even when the code is "obviously done" — produces
@@ -194,9 +193,36 @@ land step from `state.land_pending`.
194
193
  On the next `autopilot start`, the orchestrator fingerprints
195
194
  `_bmad-output/`, sprint-status.yaml, and per-story branch HEADs against
196
195
  the fingerprint recorded at the last halt. Any divergence is emitted as
197
- `{ kind: 'resume_divergence', differences: ... }`. Forward the diff to
198
- the user; let them resolve via `user_input` (`force_continue` or
199
- `override_decision`).
196
+ `{ kind: 'resume_divergence', differences: ... }`. Two escape paths
197
+ proceed despite a divergent fingerprint:
198
+
199
+ - **External-completion auto-acknowledge.** When the persisted
200
+ `current_story` is `done` in sprint-status (story merged outside the
201
+ autopilot — manual PR merge, hotfix, UI action), `autopilot start`
202
+ clears the stale story identity and proceeds. The next story is
203
+ picked from the queue or sprint-status as normal. Ledger records
204
+ `kind: resume, divergence: { kind: 'divergence_accepted', reason:
205
+ 'external_completion', story: <key> }`.
206
+ - **`--accept-divergence` flag** — catch-all for divergence patterns
207
+ the auto-acknowledge doesn't cover (multiple stories completed
208
+ externally, branch heads moved, etc.). Logged with
209
+ `reason: 'explicit_accept'`.
210
+
211
+ For divergences that fit neither path (genuine corruption, unexpected
212
+ state), forward the diff to the user and let them resolve via
213
+ `user_input` (`force_continue` or `override_decision`).
214
+
215
+ ## Post-GREEN lint gate
216
+
217
+ When `git.lint.enabled` is true, the verifier runs the composed
218
+ lint pipeline (`scripts/post-green-gates.js`: lint-changed +
219
+ lint-test-pitfalls + ci-parity scan) after the standard `dev_green`
220
+ checks pass. `git.lint.blocking` governs whether a failed gate halts
221
+ the autopilot for the LLM to fix-loop, or passes through with the
222
+ failure logged for visibility. `git.lint.output_limit` truncates each
223
+ gate's output; `git.lint.linters.<language>: [...]` overrides the
224
+ default per-language linter priority (empty list disables a language;
225
+ `javascript` + `typescript` keys merge into a single `js-ts` bucket).
200
226
 
201
227
  ## What you must NEVER do
202
228
 
@@ -6,18 +6,20 @@ You are analyzing a codebase to identify system design patterns, module boundari
6
6
 
7
7
  Scan the project at `{{project_root}}` and write your findings to `{{output_file}}`.
8
8
 
9
- ## Quality Bar
9
+ ## Output standard
10
10
 
11
- - **Patterns matter more than lists.** Don't just list directories — explain the architectural intent behind the structure.
12
- - **Be prescriptive, not descriptive.** Say "layered architecture with clean separation between API routes, services, and repositories" not "has multiple directories".
13
- - **Every finding needs a file path.** No claims without evidence.
11
+ - **Show structure, don't just enumerate it.** Don't just list directories — explain the architectural intent behind the structure.
12
+ - **Commit to a definite finding.** Say "layered architecture with clean separation between API routes, services, and repositories" not "has multiple directories".
13
+ - **Cite the file path for every claim.** No assertion without evidence.
14
14
  - **Focus on boundaries.** What talks to what? Where are the seams?
15
15
 
16
- ## Forbidden Files — NEVER Read
16
+ ## Off-limits files
17
17
 
18
- - `.env`, `.env.*` (secrets)
19
- - `*.key`, `*.pem`, `*.p12` (private keys)
20
- - `credentials.json`, `service-account.json`
18
+ Do not open these. Note their existence in the file inventory but never read or quote their contents:
19
+
20
+ - environment files (`.env`, `.env.<variant>`)
21
+ - private keys and certs (`*.key`, `*.pem`, `*.p12`)
22
+ - credential blobs (`credentials.json`, `service-account.json`)
21
23
 
22
24
  ## Ignore-file Awareness
23
25
 
@@ -6,19 +6,21 @@ You are scanning a codebase for tech debt, security issues, deprecated patterns,
6
6
 
7
7
  Scan the project at `{{project_root}}` and write your findings to `{{output_file}}`.
8
8
 
9
- ## Quality Bar
9
+ ## Output standard
10
10
 
11
- - **Patterns matter more than lists.** Don't just count TODOs — assess systemic debt patterns.
12
- - **Be prescriptive, not descriptive.** Say "12 TODO comments in auth module suggest incomplete migration from session-based to JWT auth" not "found some TODOs".
13
- - **Every finding needs a file path and line number.**
11
+ - **Look for systemic patterns, not isolated counts.** Don't just count TODOs — assess systemic debt patterns.
12
+ - **Commit to a definite finding.** Say "12 TODO comments in auth module suggest incomplete migration from session-based to JWT auth" not "found some TODOs".
13
+ - **Cite a file path and line number for every claim.**
14
14
  - **Severity must be justified.** CRITICAL = blocks features or security risk. HIGH = degrades reliability. MEDIUM = maintenance burden. LOW = cleanup opportunity.
15
15
 
16
- ## Forbidden Files — NEVER Read
16
+ ## Off-limits files
17
17
 
18
- - `.env`, `.env.*` (secrets)
19
- - `*.key`, `*.pem`, `*.p12` (private keys)
20
- - `credentials.json`, `service-account.json`
21
- - Files in `.git/` directory
18
+ Do not open these. Note their existence in the file inventory but never read or quote their contents:
19
+
20
+ - environment files (`.env`, `.env.<variant>`)
21
+ - private keys and certs (`*.key`, `*.pem`, `*.p12`)
22
+ - credential blobs (`credentials.json`, `service-account.json`)
23
+ - anything under `.git/`
22
24
 
23
25
  ## Ignore-file Awareness
24
26
 
@@ -6,20 +6,22 @@ You are mapping all external dependencies, APIs, services, and data stores that
6
6
 
7
7
  Scan the project at `{{project_root}}` and write your findings to `{{output_file}}`.
8
8
 
9
- ## Quality Bar
9
+ ## Output standard
10
10
 
11
- - **Patterns matter more than lists.** Don't just list env vars — explain the integration topology.
12
- - **Be prescriptive, not descriptive.** Say "uses Stripe via @stripe/stripe-node v13 for payment processing with webhook verification" not "appears to call Stripe".
13
- - **Every finding needs a file path.** No claims without evidence.
11
+ - **Describe the topology, not just the catalog.** Don't just list env vars — explain the integration topology.
12
+ - **Commit to a definite finding.** Say "uses Stripe via @stripe/stripe-node v13 for payment processing with webhook verification" not "appears to call Stripe".
13
+ - **Cite the file path for every claim.** No assertion without evidence.
14
14
  - **Redact actual secrets.** Show variable names and patterns only. NEVER output real tokens, keys, or passwords.
15
15
 
16
- ## Forbidden Files — NEVER Read Contents Of
16
+ ## Off-limits files
17
17
 
18
- - `.env`, `.env.local`, `.env.production` (actual secrets)
19
- - `*.key`, `*.pem`, `*.p12` (private keys)
20
- - `credentials.json`, `service-account.json`
18
+ Do not open these. Note their existence but never quote contents:
21
19
 
22
- **DO read**: `.env.example`, `.env.sample`, `.env.template` (safe — contain variable names only)
20
+ - environment files holding real values (`.env`, `.env.local`, `.env.production`)
21
+ - private keys and certs (`*.key`, `*.pem`, `*.p12`)
22
+ - credential blobs (`credentials.json`, `service-account.json`)
23
+
24
+ **OK to read**: `.env.example`, `.env.sample`, `.env.template` — these contain variable names only, no secrets.
23
25
 
24
26
  ## Ignore-file Awareness
25
27
 
@@ -6,18 +6,20 @@ You are analyzing a codebase to assess code quality, test coverage, CI/CD maturi
6
6
 
7
7
  Scan the project at `{{project_root}}` and write your findings to `{{output_file}}`.
8
8
 
9
- ## Quality Bar
9
+ ## Output standard
10
10
 
11
- - **Patterns matter more than lists.** Don't just count test files — assess whether the test strategy is sound.
12
- - **Be prescriptive, not descriptive.** Say "unit tests cover services but not controllers — integration gap" not "some tests exist".
13
- - **Every finding needs a file path.** No claims without evidence.
11
+ - **Assess strategy, don't just tally artifacts.** Don't just count test files — assess whether the test strategy is sound.
12
+ - **Commit to a definite finding.** Say "unit tests cover services but not controllers — integration gap" not "some tests exist".
13
+ - **Cite the file path for every claim.** No assertion without evidence.
14
14
  - **Ratios tell the story.** Test:source ratio, coverage gaps, CI stage completeness.
15
15
 
16
- ## Forbidden Files — NEVER Read
16
+ ## Off-limits files
17
17
 
18
- - `.env`, `.env.*` (secrets)
19
- - `*.key`, `*.pem`, `*.p12` (private keys)
20
- - `credentials.json`, `service-account.json`
18
+ Do not open these. Note their existence in the file inventory but never read or quote their contents:
19
+
20
+ - environment files (`.env`, `.env.<variant>`)
21
+ - private keys and certs (`*.key`, `*.pem`, `*.p12`)
22
+ - credential blobs (`credentials.json`, `service-account.json`)
21
23
 
22
24
  ## Ignore-file Awareness
23
25
 
@@ -6,19 +6,21 @@ You are analyzing a codebase to produce a complete technology inventory.
6
6
 
7
7
  Scan the project at `{{project_root}}` and write your findings to `{{output_file}}`.
8
8
 
9
- ## Quality Bar
9
+ ## Output standard
10
10
 
11
- - **Patterns matter more than lists.** Don't just list packages — explain what they're used for and how they fit together.
12
- - **Be prescriptive, not descriptive.** Say "uses React 18 with Server Components" not "appears to use React".
13
- - **Every finding needs a file path.** No claims without evidence (e.g., `package.json:15`).
11
+ - **Show how parts connect.** Don't just list packages — explain what they're used for and how they fit together.
12
+ - **Commit to a definite finding.** Say "uses React 18 with Server Components" not "appears to use React".
13
+ - **Cite the file path for every claim.** No assertion without evidence (e.g., `package.json:15`).
14
14
  - **Version numbers are critical.** Always include the exact version, not "latest" or "recent".
15
15
 
16
- ## Forbidden Files — NEVER Read
16
+ ## Off-limits files
17
17
 
18
- - `.env`, `.env.*` (secrets)
19
- - `*.key`, `*.pem`, `*.p12` (private keys)
20
- - `credentials.json`, `service-account.json`
21
- - `*.secret`, `*password*`, `*token*` (in filenames)
18
+ Do not open these. Note their existence in the file inventory but never read or quote their contents:
19
+
20
+ - environment files (`.env`, `.env.<variant>`)
21
+ - private keys and certs (`*.key`, `*.pem`, `*.p12`)
22
+ - credential blobs (`credentials.json`, `service-account.json`)
23
+ - anything whose filename contains `secret`, `password`, or `token`
22
24
 
23
25
  ## Ignore-file Awareness
24
26
 
@@ -1,6 +1,6 @@
1
1
  # Multi-Agent Codebase Map
2
2
 
3
- > Inspired by [GSD's map-codebase](https://github.com/gsd-build/get-shit-done). Adapted with distinct output format and enriched agent prompts.
3
+ > Inspired by [GSD's map-codebase](https://github.com/gsd-build/get-shit-done) (MIT, Copyright (c) 2025 Lex Christopherson). Adapted with distinct output format and rewritten agent prompts. Full attribution: [NOTICES.md](../../../NOTICES.md).
4
4
 
5
5
  ## Purpose
6
6
 
@@ -0,0 +1,63 @@
1
+ ---
2
+ name: sprintpilot-dependency-graph
3
+ description: 'Render the sprint dependency graph from sprint-plan.yaml in a chosen format. Accepts mermaid (default), graphviz, text (topological tree), layers (parallel-eligible groups), or json (raw nodes + edges). Use when you want to visualize or programmatically inspect the DAG without manually calling resolve-dag.js. Optionally narrow to a single epic with an epic argument.'
4
+ ---
5
+
6
+ ## STOP — read this entire file before doing anything
7
+
8
+ This skill is a **read-only renderer**. It does not modify `sprint-plan.yaml`,
9
+ trigger LLM inference, or change autopilot state. The goal is to produce a
10
+ visualization or structured dump of the existing dependency graph.
11
+
12
+ Follow **`./workflow.md`** verbatim. The 4-step flow:
13
+
14
+ 1. Parse the user's invocation for a format + optional epic scope.
15
+ 2. Resolve format ambiguity by asking the user (only when no argument
16
+ was supplied).
17
+ 3. Shell out to `resolve-dag.js` with the resolved flags.
18
+ 4. Render the output inline (mermaid block) or report the written
19
+ file path (graphviz / mermaid-to-file).
20
+
21
+ ### Never improvise
22
+
23
+ - **No file edits to `sprint-plan.yaml`.** If the plan is missing or
24
+ empty, point the user at `/sprintpilot-plan-sprint` — do NOT try to
25
+ build a plan from this skill.
26
+ - **No re-inference.** Dependency inference lives in
27
+ `/sprintpilot-plan-sprint`. This skill renders what's already there.
28
+ - **No format substitution.** If the user explicitly asks for graphviz
29
+ and `dot` isn't installed, the underlying script auto-falls-back to
30
+ mermaid with a stderr notice — surface that fallback clearly so the
31
+ user knows their requested format wasn't honored.
32
+
33
+ ### Invocation patterns
34
+
35
+ | User input | Behavior |
36
+ |---|---|
37
+ | `/sprintpilot-dependency-graph` | Ask: mermaid / graphviz / text / layers / json |
38
+ | `/sprintpilot-dependency-graph mermaid` | Render mermaid; inline the diagram in chat |
39
+ | `/sprintpilot-dependency-graph graphviz` | Write .dot file; report path |
40
+ | `/sprintpilot-dependency-graph text` | Topological-tree to chat, no file |
41
+ | `/sprintpilot-dependency-graph layers` | JSON [[layer1], [layer2], ...] to chat |
42
+ | `/sprintpilot-dependency-graph json` | JSON `{nodes, edges, epic}` to chat |
43
+ | `/sprintpilot-dependency-graph mermaid epic 1` | Per-epic scope (cross-epic edges excluded) |
44
+ | `/sprintpilot-dependency-graph mermaid --output dag.mmd` | Custom output path |
45
+
46
+ Natural-language synonyms (parse loosely):
47
+ - "show me the dependency graph" → ask for format
48
+ - "render the dag as mermaid" → mermaid
49
+ - "dot graph" / "graphviz output" → graphviz
50
+ - "layers" / "parallel groups" → layers
51
+ - "tree" / "text" / "plain" → text
52
+
53
+ ### When NOT to invoke
54
+
55
+ - You want to BUILD or RE-INFER the graph → `/sprintpilot-plan-sprint`.
56
+ - You want sprint progress / health → `/sprintpilot-sprint-progress`.
57
+ - You want the BMad-native sprint-status report → `bmad-sprint-status`.
58
+ - The plan file is absent → halt politely and point the user at the
59
+ planning skill instead of rendering an empty graph.
60
+
61
+ ---
62
+
63
+ Follow the instructions in ./workflow.md.
@@ -0,0 +1,227 @@
1
+ # Sprintpilot — Dependency Graph Renderer
2
+
3
+ ## Purpose
4
+
5
+ Render the sprint dependency graph from `sprint-plan.yaml` in a
6
+ user-chosen format without requiring shell commands. Wraps
7
+ `resolve-dag.js` (`render` / `graph` / `layers` / `width`) so the user
8
+ just types `/sprintpilot-dependency-graph mermaid` (or interactive
9
+ prompt) and the visualization lands in chat.
10
+
11
+ ## Outputs
12
+
13
+ - For **mermaid** + **text** + **layers** + **json** → rendered inline
14
+ in chat. Mermaid additionally writes a `.mmd` file (default
15
+ `_bmad-output/implementation-artifacts/sprint-plan-dag.mmd`) so the
16
+ user can preview in any markdown viewer.
17
+ - For **graphviz** → writes a `.dot` file (default
18
+ `_bmad-output/implementation-artifacts/sprint-plan-dag.dot`); reports
19
+ the path. No inline render (chat doesn't render dot directly).
20
+
21
+ No file mutations beyond the rendered output file.
22
+
23
+ ## Conventions
24
+
25
+ - `<root>` = project root.
26
+ - All formats accept an optional `--epic <id>` scope. When set,
27
+ cross-epic edges are filtered out; only intra-epic structure renders.
28
+ - All formats accept an optional `--output <path>` for the file modes
29
+ (mermaid / graphviz).
30
+ - Mermaid is the default when ambiguity needs to be resolved — it's
31
+ the most portable (GitHub-renderable, no system deps).
32
+
33
+ ---
34
+
35
+ ## Step 1 — Parse the User's Invocation
36
+
37
+ <action>The user invoked this skill with optional arguments. Parse:
38
+
39
+ 1. **Format** (one of `mermaid` / `graphviz` / `text` / `layers` / `json`).
40
+ Accept synonyms:
41
+ - "mermaid" / "mmd" → mermaid
42
+ - "graphviz" / "dot" → graphviz
43
+ - "text" / "tree" / "plain" → text
44
+ - "layers" / "parallel" / "topo" → layers
45
+ - "json" / "raw" → json
46
+
47
+ 2. **Epic scope** (optional). Match `epic <id>` / `--epic <id>` / `for epic <id>`.
48
+
49
+ 3. **Output path** (optional). Match `--output <path>` / `to <path>`.
50
+
51
+ If the user provided a format → skip Step 2.
52
+ If they didn't → proceed to Step 2.</action>
53
+
54
+ ---
55
+
56
+ ## Step 2 — Ask for Format (When Ambiguous)
57
+
58
+ <action>Only when the user invoked with no format argument, present a
59
+ single multi-choice prompt:
60
+
61
+ > Which format?
62
+ > [m] mermaid — visual flowchart (default; GitHub-renderable, no deps)
63
+ > [g] graphviz — .dot file for the dot toolchain (requires `dot` in PATH)
64
+ > [t] text — topological tree rendered inline
65
+ > [l] layers — JSON of parallel-eligible groups [[a], [b,c], ...]
66
+ > [j] json — raw graph {nodes, edges, epic}
67
+
68
+ Default to mermaid on empty input. If the user types something
69
+ ambiguous, ask once more; don't default silently — they explicitly
70
+ declined to pick a default.</action>
71
+
72
+ ---
73
+
74
+ ## Step 3 — Verify the Plan Exists
75
+
76
+ <action>Check that `sprint-plan.yaml` exists and is readable:
77
+ ```
78
+ node _Sprintpilot/scripts/sprint-plan.js read --project-root <root>
79
+ ```
80
+
81
+ Three branches:
82
+
83
+ - **`exists: false`** → halt politely:
84
+ > "No sprint plan found at `_bmad-output/implementation-artifacts/sprint-plan.yaml`.
85
+ > Run `/sprintpilot-plan-sprint` to build one, then re-invoke this
86
+ > skill to render the graph."
87
+ Do NOT attempt to render an empty graph.
88
+
89
+ - **`exists: true, error: ...`** → corrupt plan file. Surface the
90
+ error message and halt:
91
+ > "sprint-plan.yaml exists but is unreadable: `<error message>`.
92
+ > Inspect manually, or run `/sprintpilot-plan-sprint` to rebuild
93
+ > from scratch."
94
+
95
+ - **Valid plan** → proceed to Step 4.
96
+
97
+ Also note: if `plan.stories` is `[]` (skill curation not yet done),
98
+ the resolver still works — it falls back to sprint-status order. Mention
99
+ that in the output so the user knows the graph isn't yet curation-aware.</action>
100
+
101
+ ---
102
+
103
+ ## Step 4 — Render
104
+
105
+ <action>Pick the right `resolve-dag.js` subcommand based on the chosen
106
+ format. All commands accept `--project-root <root>` and optionally
107
+ `--epic <id>`.
108
+
109
+ ### Mermaid (default)
110
+
111
+ ```
112
+ node _Sprintpilot/scripts/resolve-dag.js render --format mermaid \
113
+ [--epic <id>] [--output <path>] --project-root <root>
114
+ ```
115
+
116
+ Returns JSON `{wrote, file, format, nodes, edges, fallback?}`. Then
117
+ read the rendered file and inline its contents in a ```mermaid fenced
118
+ code block so the chat client (Claude Code, etc.) renders the diagram
119
+ inline. Also report the file path so the user can preview elsewhere:
120
+
121
+ > Rendered to `<file>`. Below is the inline mermaid:
122
+ > ```mermaid
123
+ > flowchart LR
124
+ > subgraph epic_1 ["PROJ-100: Epic 1"]
125
+ > 1-1-bootstrap["PROJ-101: 1-1-bootstrap"]:::done
126
+ > 1-3-add-auth["1-3-add-auth"]:::pending ← no issue_id set
127
+ > end
128
+ > ...
129
+ > ```
130
+
131
+ When `plan.stories[*].issue_id` or `plan.epics[*].issue_id` is set, the
132
+ renderer prefixes the visual label with `<issue_id>: ` so the diagram
133
+ cross-references back to the user's tracker (Jira / Linear / GitHub /
134
+ GitLab). Stories/epics without an issue_id render with the bare key —
135
+ silence communicates "not tracked" rather than spamming `[no issue]`.
136
+
137
+ ### Graphviz
138
+
139
+ ```
140
+ node _Sprintpilot/scripts/resolve-dag.js render --format graphviz \
141
+ [--epic <id>] [--output <path>] --project-root <root>
142
+ ```
143
+
144
+ If the result envelope has `fallback: 'graphviz-missing'`, the script
145
+ silently rendered mermaid instead — surface that clearly to the user:
146
+
147
+ > Graphviz toolchain (`dot`) not found in PATH; fell back to mermaid.
148
+ > Output: `<mmd path>`. Install graphviz (e.g., `brew install graphviz`,
149
+ > `apt install graphviz`) to get .dot output.
150
+
151
+ Otherwise, report:
152
+
153
+ > Rendered to `<dot path>`. Render to PNG with:
154
+ > `dot -Tpng <dot path> -o dag.png`
155
+
156
+ ### Text (topological tree)
157
+
158
+ ```
159
+ node _Sprintpilot/scripts/resolve-dag.js layers \
160
+ [--epic <id>] --project-root <root>
161
+ ```
162
+
163
+ Returns JSON `[[layer1], [layer2], ...]`. Render in chat as a tree:
164
+
165
+ > Sprint DAG (topological layers — items in the same layer have no
166
+ > mutual dependency and could run in parallel):
167
+ >
168
+ > Layer 1: 1-1-bootstrap, 1-2-models
169
+ > Layer 2: 1-3-add-auth
170
+ > Layer 3: 2-1-foo
171
+ > ...
172
+ >
173
+ > Width: <N> (max parallel-eligible stories at any single layer)
174
+
175
+ ### Layers (raw JSON)
176
+
177
+ ```
178
+ node _Sprintpilot/scripts/resolve-dag.js layers \
179
+ [--epic <id>] --project-root <root>
180
+ ```
181
+
182
+ Pretty-print the JSON array directly:
183
+
184
+ > ```json
185
+ > [
186
+ > ["1-1-bootstrap", "1-2-models"],
187
+ > ["1-3-add-auth"],
188
+ > ["2-1-foo"]
189
+ > ]
190
+ > ```
191
+
192
+ ### JSON (full graph)
193
+
194
+ ```
195
+ node _Sprintpilot/scripts/resolve-dag.js graph \
196
+ [--epic <id>] --project-root <root>
197
+ ```
198
+
199
+ Pretty-print the JSON `{nodes, edges, epic}`:
200
+
201
+ > ```json
202
+ > {
203
+ > "nodes": ["1-1-bootstrap", "1-2-models", "1-3-add-auth", "2-1-foo"],
204
+ > "edges": [
205
+ > ["1-1-bootstrap", "1-3-add-auth"],
206
+ > ["1-2-models", "1-3-add-auth"],
207
+ > ["1-3-add-auth", "2-1-foo"]
208
+ > ],
209
+ > "epic": null
210
+ > }
211
+ > ```
212
+
213
+ In every mode, surface counts at the end: "N nodes, M edges,
214
+ K cross-epic" (compute cross-epic by counting edges whose endpoints
215
+ have different leading hyphen segments — leverage the JSON output).</action>
216
+
217
+ ---
218
+
219
+ ## Failure modes
220
+
221
+ | Symptom | Recovery |
222
+ |---|---|
223
+ | Plan file missing | Halt with pointer to `/sprintpilot-plan-sprint`. Do NOT auto-build. |
224
+ | Plan file corrupt | Surface the parse error from `sprint-plan.js read`; suggest re-running the planning skill. |
225
+ | Cycle detected (`resolve-dag.js` exits 1 with "cycle detected") | Report the cycling node list verbatim. Suggest reviewing `plan.dependencies.stories` for the named keys, or re-running `/sprintpilot-plan-sprint` to re-infer. |
226
+ | Graphviz binary missing | Note the fallback; tell the user how to install `dot`; do NOT silently retry with a different format. |
227
+ | Output file write fails (permission, disk full) | Surface the error from the resolve-dag stderr; chat-render the JSON output as a fallback so the user still gets something usable. |