@ikunin/sprintpilot 2.0.10 → 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.
Files changed (42) hide show
  1. package/README.md +245 -10
  2. package/_Sprintpilot/Sprintpilot.md +1 -1
  3. package/_Sprintpilot/bin/autopilot.js +581 -0
  4. package/_Sprintpilot/lib/orchestrator/action-ledger.js +148 -0
  5. package/_Sprintpilot/lib/orchestrator/adapt.js +502 -0
  6. package/_Sprintpilot/lib/orchestrator/decision-log.js +224 -0
  7. package/_Sprintpilot/lib/orchestrator/divergence.js +201 -0
  8. package/_Sprintpilot/lib/orchestrator/git-plan.js +259 -0
  9. package/_Sprintpilot/lib/orchestrator/impact-classifier.js +108 -0
  10. package/_Sprintpilot/lib/orchestrator/land.js +155 -0
  11. package/_Sprintpilot/lib/orchestrator/parallel-batch.js +99 -0
  12. package/_Sprintpilot/lib/orchestrator/profile-rules.js +167 -0
  13. package/_Sprintpilot/lib/orchestrator/report.js +95 -0
  14. package/_Sprintpilot/lib/orchestrator/state-machine.js +402 -0
  15. package/_Sprintpilot/lib/orchestrator/state-store.js +260 -0
  16. package/_Sprintpilot/lib/orchestrator/user-command-applier.js +157 -0
  17. package/_Sprintpilot/lib/orchestrator/user-commands.js +115 -0
  18. package/_Sprintpilot/lib/orchestrator/verify.js +397 -0
  19. package/_Sprintpilot/manifest.yaml +1 -1
  20. package/_Sprintpilot/modules/git/config.yaml +26 -0
  21. package/_Sprintpilot/scripts/agent-adapter.js +4 -5
  22. package/_Sprintpilot/scripts/auto-merge-bmad-docs.js +112 -0
  23. package/_Sprintpilot/scripts/dispatch-layer.js +12 -8
  24. package/_Sprintpilot/scripts/infer-dependencies.js +78 -21
  25. package/_Sprintpilot/scripts/inject-tasks-section.js +4 -3
  26. package/_Sprintpilot/scripts/land-this-pr.js +110 -0
  27. package/_Sprintpilot/scripts/lint-test-pitfalls.js +133 -0
  28. package/_Sprintpilot/scripts/list-remaining-stories.js +1 -1
  29. package/_Sprintpilot/scripts/log-timing.js +12 -3
  30. package/_Sprintpilot/scripts/merge-shards.js +32 -12
  31. package/_Sprintpilot/scripts/post-green-gates.js +187 -0
  32. package/_Sprintpilot/scripts/preflight-merge.js +2 -1
  33. package/_Sprintpilot/scripts/resolve-dag.js +3 -1
  34. package/_Sprintpilot/scripts/stack-snapshot.js +128 -0
  35. package/_Sprintpilot/scripts/state-shard.js +8 -1
  36. package/_Sprintpilot/scripts/summarize-timings.js +30 -12
  37. package/_Sprintpilot/scripts/with-retry.js +17 -5
  38. package/_Sprintpilot/skills/sprint-autopilot-on/SKILL.md +23 -1
  39. package/_Sprintpilot/skills/sprint-autopilot-on/workflow.orchestrator.md +148 -0
  40. package/lib/core/update-check.js +11 -1
  41. package/package.json +1 -1
  42. package/_Sprintpilot/skills/sprint-autopilot-on/workflow.md +0 -1388
@@ -0,0 +1,148 @@
1
+ # Sprintpilot — ON (Orchestrator Mode)
2
+
3
+ You are running under the **orchestrator-driven** autopilot. Flow control is
4
+ owned by `_Sprintpilot/bin/autopilot.js` — a deterministic Node.js
5
+ state machine that enforces the BMad 7-step sequence. You own the
6
+ *in-skill execution, diagnosis, triage, and small-judgment decisions* —
7
+ not the flow.
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.
11
+
12
+ ## The loop
13
+
14
+ Repeat until the orchestrator emits `halt`:
15
+
16
+ 1. `node _Sprintpilot/bin/autopilot.js next` → JSON Action.
17
+ 2. Execute the Action per the dispatch table below.
18
+ 3. While executing, scan the host chat for user interjections. If
19
+ present, record them via a `user_input` signal (step 4) and re-loop.
20
+ 4. `node _Sprintpilot/bin/autopilot.js record --signal <json>` → JSON
21
+ `{ action, verdict, phase, profile }`. Use the new action.
22
+ 5. If `verdict: prompted` → ask the user the question in `action.prompt`.
23
+ Apply their answer as a `user_input` signal and re-loop.
24
+ 6. If `action.type: halt` → STOP. The orchestrator already wrote
25
+ resume state and (when relevant) the fresh-context handoff flag.
26
+
27
+ Never improvise. Never skip a step. Never invent a next action: the
28
+ orchestrator emits it.
29
+
30
+ ## Action dispatch
31
+
32
+ | `action.type` | What you do |
33
+ |-------------------|--------------------------------------------------------------------------------------------------|
34
+ | `invoke_skill` | Run the named BMad skill **verbatim from its own body** (e.g. `bmad-create-story`, `bmad-quick-dev`, `bmad-code-review`). `action.template_slots` is a parameter bag (story_key, prior_diagnosis, relevant_decisions, prior_signals_summary, …) — it's input context for BMad's skill, NOT a replacement for the skill's instructions. When `implementation_flow=quick`, you'll receive `invoke_skill: bmad-quick-dev` per story — follow BMad's `step-oneshot.md`. |
35
+ | `run_script` | Execute `action.command` via the host's shell-equivalent. Argv-only — no shell interpolation. |
36
+ | `git_op` | Execute `action.steps` in order. The orchestrator pre-plans every git op (commit_and_push_story, merge_epic, push, fetch, create_branch) via `git-plan.js` and inlines the resulting argv sequence — each step has `args: [cmd, ...argv]`, a `description`, and an optional `retry` policy. Run each step's argv verbatim (NO shell interpolation), halt on first non-retryable failure. Never improvise the git commands or skip a step — `git push` lives in `steps`, not in `op`. |
37
+ | `parallel_batch` | Dispatch each child action concurrently (M6+ hosts only — fall back to sequential otherwise). |
38
+ | `user_prompt` | Ask the user `action.prompt`. Pass the answer back via `user_input` signal. |
39
+ | `halt` | Stop. Honor `action.handoff: 'sprint_finalize_pending'` by ending the session cleanly. |
40
+ | `noop` | Re-loop (state machine advancing without an external effect). |
41
+
42
+ ## Signals you emit
43
+
44
+ Wrap everything in `{ "status": "...", ... }` and pass to
45
+ `autopilot record --signal '<json>'`. Optional `decisions[]` on any signal.
46
+
47
+ | `status` | Required fields |
48
+ |-----------------------|--------------------------------------------------------------------------------------------------|
49
+ | `success` | `output?: object` (for `bmad-code-review` MUST include `findings[]` with `action: 'block'\|'patch'\|'defer'`); `next_skill_hint?` |
50
+ | `failure` | `reason`, `diagnosis` (first-class — fed back into next retry), `recoverable: boolean` |
51
+ | `blocked` | `blocker_kind` (one of the 5 TRUE BLOCKERS or recoverable kinds), `details`, `user_input_needed`, `consecutive_count?` |
52
+ | `propose_alternative` | `reason`, `alternative` (full Action object), `urgency_hint?` (raises impact only) |
53
+ | `user_input` | `commands: UserCommand[]` (validated server-side; see user-commands.js) |
54
+ | `verify_override` | `evidence: { decision_log_ref?, explanation, expected_paths? }` — used when verify.js is wrong |
55
+
56
+ ## TRUE BLOCKER kinds (per AGENTS.md)
57
+
58
+ `creative_user_input_required`, `new_external_dependency`,
59
+ `consecutive_test_failures` (carry `consecutive_count`),
60
+ `security_architectural_decision`, `contradictory_acceptance_criteria`.
61
+
62
+ Plus recoverable kinds the orchestrator handles deterministically:
63
+ `missing_dependency`, `failed_invariant`, `external_service`, `unknown`.
64
+
65
+ ## Decision audit channel
66
+
67
+ Include `decisions[]` on ANY signal to log small judgment calls without
68
+ round-tripping through `propose_alternative`. Each entry has
69
+ `category` (one of: architecture, test-strategy, dependency,
70
+ review-triage, review-accept, halt-recovery, scope, workaround), `impact`
71
+ (low/medium/high), `phase` (e.g. `dev-story:RED`), `decision`, and
72
+ `rationale`. The orchestrator stamps id + timestamp + story
73
+ automatically and appends to `decision-log.yaml`.
74
+
75
+ ## Code-review triage
76
+
77
+ When `bmad-code-review` completes, `success.output.findings[]` MUST
78
+ classify each finding:
79
+
80
+ - `action: 'block'` → orchestrator pauses the autopilot. Manual decision required.
81
+ - `action: 'patch'` → orchestrator enters PATCH_APPLY (step 6a) then PATCH_RETEST (step 6b).
82
+ - `action: 'defer'` → recorded but not blocking; story proceeds.
83
+
84
+ This is LLM intelligence the orchestrator routes on — you own the triage.
85
+
86
+ ## BMad bookkeeping is enforced
87
+
88
+ `verify.js` checks more than artifact existence — it enforces the BMad
89
+ bookkeeping you'd otherwise be tempted to skip:
90
+
91
+ | Phase | Bookkeeping that MUST be true before you signal `success` |
92
+ |---|---|
93
+ | `create_story` | Story file has `## Acceptance Criteria` (≥1 bullet) AND a `## Tasks` (or `## Tasks/Subtasks`) section with at least one `[ ]` or `[x]` checkbox. |
94
+ | `dev_red` / `dev_green` | Test files exist on disk; runner exit codes match the phase contract; `tests_run` matches the runner's count. |
95
+ | `code_review` | `_bmad-output/reviews/<story_key>.md` exists; `findings[]` carries `{id, severity, category, action: 'block'\|'patch'\|'defer', rationale}` for every finding. |
96
+ | `patch_apply` | Every `patch_finding` id present in `state.patch_findings` is included in `applied_finding_ids`. |
97
+ | `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. Skipping `git push` and reporting success leaves the branch unpushed and trips this check. |
98
+ | `retrospective` | `_bmad-output/retrospectives/<epic>.md` exists. |
99
+
100
+ Skipping any of these — even when the code is "obviously done" — produces
101
+ `verify_rejected` in the ledger and the orchestrator re-emits the same
102
+ action with the verifier's issues threaded into the template slot. After
103
+ the per-profile `verify_reject_budget` is exhausted, the session pauses
104
+ for the user.
105
+
106
+ If you're confident verify is wrong (e.g. you renamed a test file per a
107
+ logged decision), emit `verify_override` with `evidence.expected_paths`
108
+ and a `decision_log_ref`. The orchestrator re-runs verify with augmented
109
+ expectations.
110
+
111
+ After N consecutive verify rejections on the same state (profile-
112
+ configured budget), the orchestrator escalates to `user_prompt`.
113
+
114
+ ## Git workflow knobs
115
+
116
+ These knobs in `_Sprintpilot/modules/git/config.yaml` change what the
117
+ orchestrator emits as `git_op` / `run_script` actions. Always read them
118
+ from the action payload — do NOT improvise.
119
+
120
+ | Knob | Values | Behavior |
121
+ |---|---|---|
122
+ | `granularity` | `story` (default) / `epic` | Per-unit branch creation (default). Suppressed when `reuse_user_branch=true`. |
123
+ | `reuse_user_branch` | `false` (default) / `true` | If `true`, autopilot detects the current non-base branch on boot and commits **every** story onto it. No `story/*` or `epic/*` branches are created. PR is opened from this branch at sprint-end. |
124
+ | `merge_strategy` | `stacked` (default) / `land_as_you_go` | `stacked` keeps every story-branch open until sprint-end. `land_as_you_go` runs the new `STORY_LAND` state right after STORY_DONE to merge the PR immediately. |
125
+ | `land_when` | `no_wait` / `ci_pass` (default) / `ci_and_review` | Under `land_as_you_go`, when to merge: synchronously, after CI is green, or after CI + an approved review. |
126
+ | `land_wait_minutes` | int (default 30) | Max wait for CI / review under `land_as_you_go`. After this the orchestrator halts and prompts. |
127
+
128
+ On `STORY_LAND` rebase conflicts (base moved during the story), the
129
+ orchestrator auto-rebases the story branch onto latest base. If the
130
+ rebase has conflicts, the orchestrator halts with a `user_prompt`. You
131
+ resolve conflicts manually, then resume autopilot — it retries the
132
+ land step from `state.land_pending`.
133
+
134
+ ## Resume
135
+
136
+ On the next `autopilot start`, the orchestrator fingerprints
137
+ `_bmad-output/`, sprint-status.yaml, and per-story branch HEADs against
138
+ the fingerprint recorded at the last halt. Any divergence is emitted as
139
+ `{ kind: 'resume_divergence', differences: ... }`. Forward the diff to
140
+ the user; let them resolve via `user_input` (`force_continue` or
141
+ `override_decision`).
142
+
143
+ ## What you must NEVER do
144
+
145
+ - Decide the next BMad step yourself; skip step-6 patch loop; auto-accept
146
+ your own `propose_alternative`; write `autopilot-state.yaml` /
147
+ `ledger.jsonl` directly; commit secrets; use `git push --no-verify`;
148
+ drift from the typed Signal schema.
@@ -5,7 +5,17 @@ const PACKAGE_NAME = '@ikunin/sprintpilot';
5
5
 
6
6
  function spawnCapture(cmd, args, { timeoutMs = 7000 } = {}) {
7
7
  return new Promise((resolve) => {
8
- const child = execFile(cmd, args, { timeout: timeoutMs, windowsHide: true }, (err, stdout) => {
8
+ // On Windows, npm ships as `npm.cmd` (a batch shim). Node's `execFile`
9
+ // doesn't resolve `.cmd` / `.bat` extensions through PATHEXT — pass
10
+ // `shell: true` so cmd.exe handles the lookup. Args are hardcoded
11
+ // here so there's no injection risk. (Linux/macOS execFile is fine
12
+ // as-is.)
13
+ const opts = {
14
+ timeout: timeoutMs,
15
+ windowsHide: true,
16
+ shell: process.platform === 'win32',
17
+ };
18
+ const child = execFile(cmd, args, opts, (err, stdout) => {
9
19
  if (err) return resolve(null);
10
20
  resolve(String(stdout || '').trim());
11
21
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ikunin/sprintpilot",
3
- "version": "2.0.10",
3
+ "version": "2.1.0",
4
4
  "description": "Sprintpilot — autopilot and multi-agent addon for BMad Method v6: git workflow, parallel agents, autonomous story execution",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {