@gobing-ai/spur 0.3.92 → 0.3.93

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 (56) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/config/pipeline-budgets.json +0 -7
  3. package/config/plugin-scripts.json +10 -0
  4. package/config/templates/AGENTS.md +4 -0
  5. package/config/templates/docs/02_ROADMAP.md +2 -0
  6. package/config/templates/docs/03_ARCHITECTURE.md +3 -1
  7. package/config/templates/docs/04_DESIGN.md +2 -0
  8. package/config/templates/docs/99_PROJECT_CONSTITUTION.md +10 -2
  9. package/config/workflow-candidates.json +72 -1
  10. package/config/workflows/feature-verification.yaml +1 -0
  11. package/config/workflows/history-anatomy.yaml +2 -0
  12. package/config/workflows/idea-pipeline.yaml +67 -18
  13. package/config/workflows/pr-review.yaml +8 -0
  14. package/config/workflows/task-pipeline.yaml +180 -39
  15. package/config/workflows/wayfinder-resolution.yaml +5 -0
  16. package/config/workflows/wrapup-pipeline.yaml +55 -14
  17. package/package.json +9 -9
  18. package/plugins/sp/README.md +7 -2
  19. package/plugins/sp/commands/dev-run.md +2 -2
  20. package/plugins/sp/commands/dev-runall.md +2 -2
  21. package/plugins/sp/lib/idea-handoff.generated.mjs +8 -4
  22. package/plugins/sp/lib/inline-run.generated.d.mts +1 -0
  23. package/plugins/sp/lib/inline-run.generated.mjs +24 -16
  24. package/plugins/sp/plugin.json +1 -1
  25. package/plugins/sp/scripts/inline-pipeline-parity-check.ts +1 -1
  26. package/plugins/sp/scripts/inline-run-setup.mjs +75 -3
  27. package/plugins/sp/scripts/inline-run-setup.ts +133 -3
  28. package/plugins/sp/scripts/quality-gate.mjs +248 -6
  29. package/plugins/sp/scripts/quality-gate.ts +410 -9
  30. package/plugins/sp/scripts/residual-scan.mjs +12 -4
  31. package/plugins/sp/scripts/residual-scan.ts +32 -6
  32. package/plugins/sp/scripts/task-diffstat.mjs +156 -0
  33. package/plugins/sp/scripts/task-diffstat.ts +229 -0
  34. package/plugins/sp/scripts/wrapup-drift-probe.mjs +181 -0
  35. package/plugins/sp/scripts/wrapup-drift-probe.ts +258 -0
  36. package/plugins/sp/scripts/wrapup-steps.mjs +60 -1
  37. package/plugins/sp/scripts/wrapup-steps.ts +89 -4
  38. package/plugins/sp/skills/brainstorm/SKILL.md +2 -0
  39. package/plugins/sp/skills/brainstorm/references/workflows.md +17 -2
  40. package/plugins/sp/skills/code-verification/SKILL.md +2 -2
  41. package/plugins/sp/skills/code-verification/references/secu-review.md +3 -2
  42. package/plugins/sp/skills/spur-check/SKILL.md +112 -0
  43. package/plugins/sp/skills/spur-dev/SKILL.md +2 -1
  44. package/plugins/sp/skills/spur-dev/references/cross-cutting.md +14 -2
  45. package/plugins/sp/skills/spur-dev/references/document-authoring.md +85 -0
  46. package/plugins/sp/skills/spur-dev/references/execution-batch.md +1 -1
  47. package/plugins/sp/skills/spur-dev/references/flag-glossary.md +8 -0
  48. package/plugins/sp/skills/spur-dev/references/gate-checklists.md +3 -2
  49. package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +19 -1
  50. package/plugins/sp/skills/spur-dev/references/planning-workflow.md +5 -5
  51. package/plugins/sp/skills/spur-dev/templates/design.md +31 -0
  52. package/plugins/sp/skills/spur-dev/templates/plan.md +32 -0
  53. package/plugins/sp/skills/spur-doctor/SKILL.md +60 -14
  54. package/schemas/state-machine-workflow.schema.json +4 -0
  55. package/spur.js +1117 -472
  56. package/config/workflows/decision-routing-example.yaml +0 -134
@@ -120,6 +120,14 @@ This is **the same rule, not an exception**: `--agent` names who does the thinki
120
120
  the thinking happens in the stages. Selecting an executor for a loop that runs no prompts would be
121
121
  meaningless.
122
122
 
123
+ **Fleet executor (0942, ADR-126, opt-in).** A workflow run may opt its `agent.run` stages into the
124
+ agent fleet control plane by mapping the pipeline selector to `executor: 'fleet'` (dev-run /
125
+ dev-runall `--agent fleet`). The stage dispatches to a fleet member through the fleet coordination
126
+ surface instead of spawning a subprocess; a subprocess fallback happens only when the run declares
127
+ `executorFallback: 'traditional'`, and an unavailable fleet otherwise fails the stage explicitly
128
+ (0937 `failed-agent`). This is an additional `agent.run` transport — it does not change the
129
+ `--agent` selector semantics documented above, and the interactive driver never resolves to it.
130
+
123
131
  **Interactive task pipelines invert control into the host session (ADR-047 amendment).**
124
132
  `dev-run --mode full` and sequential `dev-runall` with omitted `--agent` or explicit `--agent
125
133
  inline` interpret the existing `task-pipeline.yaml` in the host session; they do not launch `spur
@@ -785,8 +793,12 @@ The Design Approval Gate is the taste gate between system design and decompositi
785
793
  **The `needs_design` signal routing:**
786
794
 
787
795
  The signal is emitted by the `discovery` state's brainstorm dispatch and written to
788
- `.spur/run/idea-needs-design.json`. The `feature-check` state's transition guards read it to
789
- determine routing:
796
+ `.spur/run/idea-needs-design.json`. A deterministic shell action at the end of the `ac-generate`
797
+ and `feature-check` onEnter lists (0945 R2) folds `design` × `needs_design` once into
798
+ `.spur/run/<runId>-idea-design-route.txt` (`design` | `skip`; missing/corrupt JSON fails safe to
799
+ `design`) and the two recorded check statuses into `.spur/run/<runId>-idea-ac-ready.status`
800
+ (`PASS` only when both are PASS). The transition guards read those derived files to determine
801
+ routing — they never re-derive the signal inline (0769):
790
802
 
791
803
  | `design` var | `needs_design` signal | Route |
792
804
  | --- | --- | --- |
@@ -0,0 +1,85 @@
1
+ ---
2
+ name: document-authoring
3
+ description: Light Markdown contracts for plan records and non-UI design satellites.
4
+ see_also:
5
+ - spur-dev
6
+ - planning-workflow
7
+ - doc-evolve
8
+ ---
9
+
10
+ # Plan and design document authoring
11
+
12
+ Use [plan.md](../templates/plan.md) for a new `docs/plans/*.md` working record and
13
+ [design.md](../templates/design.md) for a new `docs/design/*.md` non-UI contract satellite.
14
+ The project constitution owns their authority and maintenance; these templates are writing aids,
15
+ not parser schemas. Keep Markdown readable even when frontmatter is absent in a legacy file.
16
+
17
+ | Document | Job | Authority |
18
+ | --- | --- | --- |
19
+ | `docs/plans/` | Ordered work: intended outcome, premises, dependencies, execution sequence, verification, and follow-up. Older proposals and investigations remain working records. | Working record. Accepted conclusions take effect in their owner, such as an ADR, feature, roadmap, or design satellite. |
20
+ | `docs/design/` | Issue, context, solution, and its observable non-UI contract | Governed satellite of `docs/04_DESIGN.md`; label proposals and current behavior separately. |
21
+
22
+ ## Compose a new file
23
+
24
+ 1. Choose the owner before writing. Reuse an existing satellite when it already owns the surface.
25
+ Keep root `DESIGN.md` for UI rules and `03_ARCHITECTURE.md` for current system topology.
26
+ 2. Copy the relevant template. Replace placeholders. Keep `kind`, a descriptive `title`, a
27
+ truthful `status`, `created_at`, `updated_at`, `related` links, and `tags` for categorization.
28
+ Use ISO dates; leave `related` or `tags` empty when none apply. Keep one H1 matching the title.
29
+ 3. Use headings for the reader's question. The template's prompts are a starting shape: remove
30
+ inapplicable sections and keep specialized sections required by the producing workflow, such as
31
+ a brainstorm's `## Design Summary`. Number new sections in reading order. Plans make the
32
+ execution sequence and its premises usable; designs explain the issue, context, solution, and
33
+ observable contract. Never fill empty boilerplate.
34
+ 4. For a design satellite, write detail first, then add its pointer to `04_DESIGN.md` if missing.
35
+ Update an existing index row only when its indexed facts change. Do not put task receipts there.
36
+
37
+ ## Frontmatter vocabulary
38
+
39
+ Soft conventions for consistency and tag filtering, not a validator. Unknown values stay readable.
40
+
41
+ | Field | Values |
42
+ | --- | --- |
43
+ | `kind` | `plan` for any `docs/plans/` record, `design` for any `docs/design/` satellite. Nothing else. |
44
+ | `status` (plan) | `draft`, `proposed`, `approved`, `in-progress`, `done`, `superseded` |
45
+ | `status` (design) | `proposed`, `accepted`, `implemented`, `superseded` |
46
+ | `tags` | Ordered: one record-type tag, then owning feature ids (for example `H14`), then at most two area tags. |
47
+ | `related` | Repo-relative paths or feature/task ids; no prose. |
48
+
49
+ Record-type tags — plan: `brainstorm`, `proposal`, `investigation`, `audit`, `map`, `execution`,
50
+ `evidence`; design: `contract` (observable surface) or `system` (internal mechanism). Area tags:
51
+ `cli`, `server`, `web`, `workflow`, `planning`, `history`, `observability`, `agent`, `plugin`,
52
+ `docs`, `config`. A project may extend the area list; reuse a tag already in the corpus
53
+ (`rg -n '^tags:' docs/plans docs/design`) before adding one.
54
+
55
+ A producing workflow may keep its own keys beside these, such as a brainstorm's `needs_design` and
56
+ `run_id`, and its own section shape. The shared fields still apply.
57
+
58
+ ## Revise an existing file
59
+
60
+ Read the whole file and its inbound links first. Preserve the filename, meaningful headings,
61
+ anchors, dates, decisions, and historical status. Add missing metadata from evidence; label
62
+ unknowns instead of guessing. Restructure only where clarity improves, and keep a forwarding
63
+ heading when an anchor cannot be migrated safely. Update `updated_at` only for a substantive edit.
64
+ Do not turn an old proposal into a claim about current behavior without checking the owning source.
65
+
66
+ Legacy metadata upgrade:
67
+
68
+ - **Map** `date` → `created_at` and `feature`/`feature_id`/`task_wbs`/`parent_task` → `related`.
69
+ `title` is the H1 text; `topic` maps to `title` only when the file has no H1, otherwise drop it.
70
+ - **Owners:** when no owner key exists, a feature or task record that links the file
71
+ (`rg -l <filename> docs/features <task dir>`) is evidence for `related`. Ids found only in body
72
+ prose are not; requirement and priority labels look like feature ids.
73
+ - **Keep** workflow and provenance keys unchanged (`needs_design`, `run_id`, `doc`, `authority`,
74
+ `owns`, `read_before`, `edit_rules`, `version`, `derived_from`).
75
+ - **Dates:** `created_at` comes from a legacy `date`, else the filename date prefix, else the first commit
76
+ (`git log --follow --diff-filter=A --format=%as -- <file> | tail -1`), else leave it out and flag it.
77
+ `updated_at` is the existing value or the last commit date; do not bump it for a metadata-only edit.
78
+ - **Status:** use the vocabulary value only when the legacy value or body states it unambiguously
79
+ (`shipped`/`implemented`/`built …` → `implemented`; `approved-with-feedback` → `approved`).
80
+ Otherwise keep the legacy value and flag it for the operator. No status is better than a guessed one.
81
+ - **Headings:** never renumber or rename legacy headings; numbering applies to new files only.
82
+
83
+ For a bounded, read-only review of legacy files, use `sp:spur-doctor`. Apply accepted document
84
+ proposals in place using this guide, then use `sp:doc-evolve` to check affected key-document sync.
85
+ No bulk conversion or strict format check is required to read or maintain existing documents.
@@ -270,7 +270,7 @@ Only two flags cross the orchestrator→pipeline boundary; both are merged into
270
270
  | Flag | Effect on per-task `--vars` |
271
271
  | --- | --- |
272
272
  | `--auto` | sets `"profile":"auto"` (skips the HITL approve gate). Omitting it forwards nothing, so the pipeline uses its default profile (standard — HITL pause surfaces to the operator). (R4.2) |
273
- | `--agent <value>` | omit/`inline` in interactive sequential mode selects the host driver and is not forwarded. `auto` or a name sets **both** `"agent":"<value>"` and `"implementAgent":"<value>"` so every workflow `agent.run` step — including implement — spawns that executor. Headless omit/inline falls through the executor precedence chain. To pin ONLY implement, pass `--vars '{"implementAgent":"..."}'` separately; that explicit var selects the subprocess path. (R4.3, tasks 0483/0503) |
273
+ | `--agent <value>` | omit/`inline` in interactive sequential mode selects the host driver and is not forwarded. `auto` or a name sets **both** `"agent":"<value>"` and `"implementAgent":"<value>"` so every workflow `agent.run` step — including implement — spawns that executor. Headless omit/inline falls through the executor precedence chain. To pin ONLY implement, pass `--vars '{"implementAgent":"..."}'` separately; that explicit var selects the subprocess path. (R4.3, tasks 0483/0503) The opt-in `fleet` value instead maps the run to `"executor":"fleet"`: every `agent.run` stage dispatches through the agent fleet control plane (0942/ADR-126) and neither `agent` nor `implementAgent` is pinned. |
274
274
 
275
275
  The host session remains the orchestrator for interactive sequential omit/inline. `sp:super-planner`
276
276
  owns explicit-executor and parallel paths; there the flag pins the per-task step executor, not the
@@ -69,6 +69,14 @@ inline is the default selector and omitted/explicit `inline` resolve identically
69
69
  the concrete coding-agent tool; `executor` remains the domain-layer role and is not a command flag.
70
70
  `inline` and `auto` are reserved values — config validation rejects an executor claiming either.
71
71
 
72
+ **Fleet executor (0942, ADR-126, opt-in).** On the pipeline selectors (`dev-run`, `dev-runall`),
73
+ `--agent fleet` maps the workflow run to the executor var `executor: 'fleet'`: every `agent.run`
74
+ stage dispatches through the agent fleet control plane instead of spawning a subprocess, with a
75
+ subprocess fallback only when the run declares `executorFallback: 'traditional'`; otherwise an
76
+ unavailable fleet fails the stage loudly (0937 `failed-agent`). `fleet` is deliberately not part of
77
+ the `<inline|auto|name>` selector grammar above — the value table and the executor precedence chain
78
+ are unchanged. Contract: [fleet-config-declaration.md](../../../../../docs/design/fleet-config-declaration.md).
79
+
72
80
  #### `--inline` (removed — collapsed into `--agent`)
73
81
 
74
82
  **Anchor:** `#flag-inline` (stub retained to avoid dangling external links).
@@ -89,8 +89,9 @@ Entered before `task-pipeline.yaml` `review` state dispatches `sp:code-verificat
89
89
 
90
90
  - [ ] The implementation matches the task's `## Plan` checklist (every checked item maps to a code/test/doc change).
91
91
  - [ ] `git status` shows only changes traceable to this task's Plan (no drive-by edits).
92
- - [ ] Lint and typecheck pass (`bun run lint`).
93
- - [ ] Tests pass (`bun run test`) — no `.skip`, `xfail`, or commented-out tests.
92
+ - [ ] Check receipt current: `quality-gate.ts status` reports `reuse: true` for
93
+ `.spur/run/<wbs>-check-receipt.json` at the current digest; run `bun run spur-check` only
94
+ when it reports stale or missing (0940 — never re-run the full chain on a reusable receipt).
94
95
  - [ ] New `biome-ignore` / `eslint-disable` suppressions: none, or each is justified inline.
95
96
  - [ ] No new `console.*` in scripts (use a project logger if one exists).
96
97
  - [ ] The `## Solution` section records the file:line change map and rationale.
@@ -23,7 +23,7 @@ the resolved actions and guards of every `.spur/workflows/*.yaml`; any element p
23
23
  in one and absent in the other fails the check. Add a new kind here when the driver
24
24
  implements it; remove the entry when the corresponding kind is dropped from the YAML.
25
25
 
26
- **Actions:** `shell` · `note` · `doctor.probe` · `file.read.into-var` · `hitl.confirm` · `hitl.input` · `hitl.select` · `agent.run` · `proof.fingerprint` · `run.artifact` · `command.gate`
26
+ **Actions:** `shell` · `note` · `doctor.probe` · `file.read.into-var` · `hitl.confirm` · `hitl.input` · `agent.run` · `proof.fingerprint` · `run.artifact` · `command.gate` · `decide`
27
27
 
28
28
  **Guards (transitions):** `always` · `shell` · `action-ok` · `contract-violation`
29
29
 
@@ -497,6 +497,24 @@ The driver reaches it through the existing run delegate (`$SETUP_SCRIPT`,
497
497
  (0887 R8), so `completed_at − started_at == duration_ms` exactly; a back-date failure is
498
498
  recorded (`action.backdate`) and never affects the run.
499
499
 
500
+ - **A `decide` action (0941)** — the driver never executes the DecisionMaker itself; it delegates
501
+ to the same app runner the engine registers, which writes the resultFile row (schemaVersion 1)
502
+ and returns the decision, then the delegate records the `action_runs` row (`kind=decide`)
503
+ through the same writer as every other action:
504
+
505
+ ```bash
506
+ bun "$SETUP_SCRIPT" --decide --run-id "$RUN_ID" --node <state-id> --options-json <options-file>
507
+ ```
508
+
509
+ The options JSON mirrors the YAML `decide` options (`id`, `method: choice|noul`, `question`,
510
+ `choices`/`default`, optional `evidence`, optional `minConfidence`, `resultFile`); paths resolve
511
+ against the project workdir. The decision never pauses and never fails the run for model
512
+ problems: a degraded outcome (feature switch off, no backend, error, timeout, low confidence)
513
+ prints `ok:true` with `degraded:true`, the declared `reason`, and `value = default`, and exits
514
+ `0` — route on the resultFile's `.value` with the declared file guards. Only an invalid options
515
+ schema exits `1` (fail closed), and usage errors exit `2`. The `action_runs` trace row is
516
+ best-effort exactly like `--action`.
517
+
500
518
  - **At the run's declared terminal state** — before the driver reports the run complete, close the
501
519
  row so a successful inline run is never left non-terminal for `spur workflow clean` to reap as
502
520
  stale:
@@ -198,11 +198,11 @@ task Design.
198
198
  order (§4.5 rule 5 / sync trigger **T9**):
199
199
 
200
200
  1. **Satellite first.** Write/update `docs/design/<slug>.md`. `<slug>` is the stable grep anchor —
201
- derive it from the feature name (kebab-case), and **reuse the existing slug** on re-runs. Capture
202
- the chosen approach + one-line reason, rejected alternatives, key interface/type **signatures**
203
- (not bodies), invariants, and the surface it touches. Do **not** restate the satellite file format
204
- here — follow the shape of existing satellites (`docs/design/server-side-adjustment-design.md`,
205
- `workflow-observability.md`).
201
+ derive it from the feature name (kebab-case), and **reuse the existing slug** on re-runs. For a
202
+ new file use [document-authoring.md](document-authoring.md) and its design template; for an
203
+ existing file preserve its headings and anchors. Capture the chosen approach + one-line reason,
204
+ rejected alternatives, key interface/type **signatures** (not bodies), invariants, and the
205
+ surface it touches.
206
206
  2. **Index second.** Add or update the satellite's row in `docs/04_DESIGN.md §0` (the `| Satellite |
207
207
  Area | Status |` table) — pointer + one-line area + status only, never a restatement of the body.
208
208
 
@@ -0,0 +1,31 @@
1
+ ---
2
+ kind: design
3
+ title: <specific non-UI contract or system design>
4
+ status: proposed
5
+ created_at: YYYY-MM-DD
6
+ updated_at: YYYY-MM-DD
7
+ related: []
8
+ tags: []
9
+ ---
10
+
11
+ # <Specific non-UI contract or system design>
12
+
13
+ ## 1. Issue and scope
14
+
15
+ <Specific issue or tasks this design addresses, observed impact, boundaries, and whether the solution is proposed or current. Link the owning records.>
16
+
17
+ ## 2. Context and constraints
18
+
19
+ <Relevant current behavior, evidence for the issue, and constraints the solution must respect. Link to 03 for wider architecture.>
20
+
21
+ ## 3. Solution
22
+
23
+ <Chosen approach and how it resolves the issue. Show ownership, boundaries, and flow; distinguish proposed behavior from implemented behavior.>
24
+
25
+ ## 4. Contract and compatibility
26
+
27
+ <Observable inputs, outputs, defaults, errors, invariants, edge cases, and migration behavior needed to implement or use the solution. Omit inapplicable parts.>
28
+
29
+ ## 5. Tradeoffs and open questions
30
+
31
+ <Why this solution was chosen, material costs or alternatives, and unresolved questions or follow-up. Link ADR decisions instead of restating them.>
@@ -0,0 +1,32 @@
1
+ ---
2
+ kind: plan
3
+ title: <specific title>
4
+ status: draft
5
+ created_at: YYYY-MM-DD
6
+ updated_at: YYYY-MM-DD
7
+ related: []
8
+ tags: []
9
+ ---
10
+
11
+ # <Specific title>
12
+
13
+ ## 1. Objective and outcome
14
+
15
+ <Issue or tasks this plan addresses, intended result, scope, and how completion will be recognized. Link the owning feature or tasks.>
16
+
17
+ ## 2. Premises and dependencies
18
+
19
+ <Facts, assumptions, prerequisites, decisions, and blockers that affect the sequence. Link evidence; mark unverified premises.>
20
+
21
+ ## 3. Execution sequence
22
+
23
+ 1. <Action, prerequisite, and tangible output or checkpoint. Name an owner when coordination matters.>
24
+ 2. <Next action. Show dependencies and safe parallel work explicitly.>
25
+
26
+ ## 4. Risks and verification
27
+
28
+ <What could change the sequence, the fallback or decision point, and how the intended result will be verified.>
29
+
30
+ ## 5. Follow-up
31
+
32
+ <Handoff, remaining actions, and deferred work with owners or links when known. Omit if none.>
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: spur-doctor
3
- description: "Evaluate spur artifacts from read-only CLI evidence — tasks, features, rules, workflows, agent specs — reflect over sp:history-anatomy findings, and return a proposal table. Diagnoses spur artifacts, not runtime environments (that is spur agent doctor). Triggers: check artifact health, propose evolution, reflect over history findings."
3
+ description: "Evaluate spur artifacts and plan/design Markdown from read-only evidence, reflect over sp:history-anatomy findings, and return a proposal table. Diagnoses artifacts, not runtime environments (that is spur agent doctor). Triggers: check artifact health, propose evolution, review legacy documents."
4
4
  license: Apache-2.0
5
5
  version: 1.0.0
6
6
  metadata:
@@ -26,16 +26,19 @@ see_also:
26
26
  # sp:spur-doctor — evaluate spur artifacts and propose changes
27
27
 
28
28
  One cross-noun method (ADR-114, [spur artifact evolution](../../../../docs/design/spur-artifact-evolution.md)
29
- §2): gather **read-only CLI evidence** about tasks, features, rules, workflows and agent specs,
30
- **reflect** over `sp:history-anatomy` findings, and return a **proposal table**. It diagnoses spur
31
- **artifacts** — definitions, rules, corpus records — not runtime environments: whether an agent
29
+ §2): gather **read-only evidence** about tasks, features, rules, workflows, agent specs, and
30
+ plan/design Markdown; **reflect** over `sp:history-anatomy` findings; and return a
31
+ **proposal table**. It diagnoses spur artifacts — definitions, rules, corpus records and documents —
32
+ not runtime environments: whether an agent
32
33
  binary, host session or tool install is healthy is `spur agent doctor`'s job, not this skill's.
33
34
 
34
35
  ## Read-only invariant
35
36
 
36
- The doctor **writes nothing and names no mutating verb**. It performs no task, feature, rule or
37
- workflow write — the operator accepts rows and `sp:spur-composer`
38
- ([../spur-composer/SKILL.md](../spur-composer/SKILL.md)) applies them. A caller that wants a
37
+ The doctor **writes nothing and names no mutating verb**. It performs no task, feature, rule,
38
+ workflow or document write. The operator accepts rows; `sp:spur-composer`
39
+ ([../spur-composer/SKILL.md](../spur-composer/SKILL.md)) applies corpus rows, while a document
40
+ author applies plan/design rows using the
41
+ [spur-dev authoring guide](../spur-dev/references/document-authoring.md). A caller that wants a
39
42
  record saves the returned table under `docs/reports/`; the doctor creates no artifact store.
40
43
 
41
44
  - **History enters only through `sp:history-anatomy` findings.** Raw history records stay out
@@ -55,9 +58,51 @@ record saves the returned table under `docs/reports/`; the doctor creates no art
55
58
  | workflow | `spur workflow validate --json` (findings by `level`), `node "$(superskill script path sp workflow-step-profile.mjs)" <workflow> --json` |
56
59
  | agent spec | `spur agent list --specs --json` |
57
60
  | history | A `sp:history-anatomy` report ([../history-anatomy/SKILL.md](../history-anatomy/SKILL.md)), never raw history records |
61
+ | plan/design Markdown | The file itself, the project constitution, the relevant spur-dev template, and inbound index/links; no new CLI needed |
58
62
 
59
63
  Every row of a proposal cites the evidence it rests on. No anchor, no proposal.
60
64
 
65
+ ## Legacy plan and design review
66
+
67
+ Enumerate `docs/plans/*.md` and `docs/design/*.md` with `rg --files` and sort the paths. Include
68
+ every Markdown path in the review; JSON and other files are outside this contract. For a large set,
69
+ freeze the list and split it into named path groups by record type (for example
70
+ `docs/plans/*-brainstorm.md`, other plans, designs), at most ~40 files each, and combine their
71
+ coverage lists. Read each file and the project constitution before judging it. Report scanned paths
72
+ and counts of proposals and no-ops, so an omitted file is visible.
73
+
74
+ Compare each plan with the [plan template](../spur-dev/templates/plan.md) and each design with the
75
+ [design template](../spur-dev/templates/design.md), using the
76
+ [authoring guide](../spur-dev/references/document-authoring.md) for meaning. Look for missing or
77
+ unsupported `kind`, title, status, dates, material related links or useful tags; unclear objective,
78
+ premises, execution sequence or follow-up in a plan; unclear issue, context, solution, contract or
79
+ compatibility in a design; and a missing `04_DESIGN.md` pointer for a design satellite.
80
+ These are **review prompts**, not format errors. Keep specialized sections required by a producing workflow.
81
+
82
+ Judge metadata against the authoring guide's **frontmatter vocabulary** and **legacy metadata
83
+ upgrade** rules, so every row in a batch makes the same choice: the same key mapping, `title` from
84
+ the H1, `related` from owner keys or linking feature/task records, `created_at` source order
85
+ (legacy `date`, filename prefix, first commit, else flag), status mapping only when unambiguous,
86
+ and tags in record-type → feature → area order from the shared list. A row whose status or tag needs
87
+ judgment says so in `change` instead of picking a value. Never propose renumbering or renaming a
88
+ legacy heading.
89
+
90
+ Propose only evidence-backed, useful edits. A proposal names the exact file and heading or
91
+ frontmatter field, cites a line and the governing rule, and says what can be inferred and what
92
+ needs an operator answer. Preserve filenames, anchors, original dates, decisions and historical
93
+ status. Do not silently promote a proposal to current behavior, invent metadata, or rewrite a
94
+ whole file to fit a template. A conforming or intentionally specialized file is a no-op.
95
+
96
+ The `apply` cell for a document row points to the spur-dev authoring guide; the author edits an
97
+ accepted row in place, then runs `sp:doc-evolve` sync-check for affected key documents and verifies
98
+ links, headings, frontmatter and the `04` index when applicable. No bulk conversion or strict
99
+ validator is required for old files.
100
+
101
+ For a batch, the caller saves each group's table as
102
+ `docs/reports/YYYY-MM-DD-<group>-doc-upgrade-review.md`. After the operator accepts rows, the author
103
+ applies one group's metadata-only rows together and commits them as one change; body restructuring
104
+ rows stay per file. Flagged rows wait for the operator's answer.
105
+
61
106
  ## Workflow step profile and cache-window flags
62
107
 
63
108
  The step profile (`plugins/sp/scripts/workflow-step-profile`, ADR-065 plugin entrypoint) reads
@@ -114,25 +159,26 @@ Return one row per actionable finding, with exactly these columns:
114
159
  | Column | Content |
115
160
  | --- | --- |
116
161
  | `key` | The finding key, or `<noun>:<id>:<check>` for an artifact finding |
117
- | `evidence` | The CLI output or report section the row rests on |
162
+ | `evidence` | CLI output, report section, or document path and line the row rests on |
118
163
  | `action` | One action class from the reflection map (or the per-noun evaluation) |
119
164
  | `change` | The proposed change, in one line |
120
- | `apply` | The `spur` verb or composer procedure that lands it |
165
+ | `apply` | The `spur`/composer route for corpus rows or the spur-dev authoring guide for document rows |
121
166
  | `verify` | The evidence to re-run after applying |
122
167
 
123
168
  Rules:
124
169
 
125
- - The `apply` route is always a `spur` verb or a gated composer step — never a raw file edit this
126
- skill performs. Shared-workflow rows route through the composition ladder's shared step.
170
+ - Corpus `apply` routes use a `spur` verb or gated composer step; document rows use the spur-dev
171
+ authoring guide. The doctor itself never edits either surface. Shared-workflow rows route
172
+ through the composition ladder's shared step.
127
173
  - A `task` row carries the finding `key` in the task body (the history-anatomy handoff route).
128
174
  - Rows are proposals only. No applied change, diff, or command output claimed as run.
129
175
 
130
176
  ## What this skill is not
131
177
 
132
- - **Not the applier.** `sp:spur-composer` applies accepted rows; this skill performs no
133
- task/feature/rule/workflow write.
178
+ - **Not the applier.** `sp:spur-composer` applies accepted corpus rows and document authors apply
179
+ accepted document rows; this skill performs no write.
134
180
  - **Not a runtime doctor.** Environment, binary and session readiness belong to
135
- `spur agent doctor`; this skill diagnoses spur artifacts from CLI evidence.
181
+ `spur agent doctor`; this skill diagnoses artifacts from read-only evidence.
136
182
  - **Not a history interpreter.** Findings come from `sp:history-anatomy` reports, never from raw
137
183
  history records.
138
184
  - **Not a loop.** Recurring evolution passes belong to `sp:super-planner` or a workflow.
@@ -135,6 +135,10 @@
135
135
  "type": "string",
136
136
  "minLength": 1
137
137
  },
138
+ "terminalReason": {
139
+ "type": "string",
140
+ "description": "Closed terminal-reason enum declared when this edge finalizes the run (0937 R3; required for edges into failureStates)."
141
+ },
138
142
  "description": {
139
143
  "type": "string"
140
144
  },