@gobing-ai/spur 0.3.66 → 0.3.68

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 (82) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/config/corpus-baseline.json +463 -10507
  3. package/config/templates/docs/99_PROJECT_CONSTITUTION.md +21 -16
  4. package/config/workflow-composition-baseline.json +109 -59
  5. package/config/workflows/docs-pipeline.yaml +98 -22
  6. package/config/workflows/idea-pipeline.yaml +20 -22
  7. package/config/workflows/task-pipeline.yaml +207 -108
  8. package/package.json +9 -9
  9. package/plugins/sp/README.md +6 -7
  10. package/plugins/sp/agents/expert-spur.md +61 -88
  11. package/plugins/sp/commands/dev-idea.md +5 -3
  12. package/plugins/sp/commands/dev-plan.md +3 -1
  13. package/plugins/sp/commands/dev-review-session.md +2 -1
  14. package/plugins/sp/hooks/context-post-tool.ts +101 -2
  15. package/plugins/sp/hooks/context-session-start.ts +22 -1
  16. package/plugins/sp/plugin.json +1 -1
  17. package/plugins/sp/scripts/stage-registry-adapter.ts +144 -2
  18. package/plugins/sp/skills/session-review/SKILL.md +16 -0
  19. package/plugins/sp/skills/spur-cli/SKILL.md +38 -13
  20. package/plugins/sp/skills/spur-cli/references/agent.md +7 -4
  21. package/plugins/sp/skills/spur-cli/references/history.md +69 -0
  22. package/plugins/sp/skills/spur-cli/references/message.md +2 -2
  23. package/plugins/sp/skills/spur-cli/references/projects.md +59 -0
  24. package/plugins/sp/skills/spur-cli/references/tasks/verbs.md +28 -0
  25. package/plugins/sp/skills/spur-cli/references/team.md +1 -1
  26. package/plugins/sp/skills/spur-cli/references/workflows.md +6 -0
  27. package/plugins/sp/skills/spur-dev/references/cross-cutting.md +40 -16
  28. package/plugins/sp/skills/spur-dev/references/dev-operations.md +6 -6
  29. package/plugins/sp/skills/spur-dev/references/execution-batch.md +80 -11
  30. package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +18 -13
  31. package/spur.js +2099 -650
  32. package/web/_astro/{BoardApp.BEtcJqde.js → BoardApp.BQFbkeqq.js} +15 -15
  33. package/web/_astro/BoardApp.CTkqrhWd.js +1 -0
  34. package/web/_astro/{TaskDetail.ClAbCXom.js → TaskDetail.Dl2Eaj1w.js} +1 -1
  35. package/web/_astro/{arc.CCvf51_y.js → arc.uG14rp8A.js} +1 -1
  36. package/web/_astro/{architectureDiagram-3BPJPVTR.C0cb0J5M.js → architectureDiagram-3BPJPVTR.Dye6uD_x.js} +1 -1
  37. package/web/_astro/{blockDiagram-GPEHLZMM.CIyjqoCE.js → blockDiagram-GPEHLZMM.B9Pkh7Hb.js} +1 -1
  38. package/web/_astro/{c4Diagram-AAUBKEIU.fs14IuFs.js → c4Diagram-AAUBKEIU.C2x7SC_X.js} +1 -1
  39. package/web/_astro/channel.Dsvulp7W.js +1 -0
  40. package/web/_astro/{chunk-2J33WTMH.CaBKv4ZO.js → chunk-2J33WTMH.D2p4-nWk.js} +1 -1
  41. package/web/_astro/{chunk-4BX2VUAB.BOllTPto.js → chunk-4BX2VUAB.S-6jf33o.js} +1 -1
  42. package/web/_astro/{chunk-55IACEB6.ChEof0O4.js → chunk-55IACEB6.DVXj4Fdh.js} +1 -1
  43. package/web/_astro/{chunk-727SXJPM.Co2kdjD8.js → chunk-727SXJPM.Dz689FMN.js} +1 -1
  44. package/web/_astro/{chunk-AQP2D5EJ.SWmfcnog.js → chunk-AQP2D5EJ.KxYj5TnI.js} +1 -1
  45. package/web/_astro/{chunk-FMBD7UC4.rDAFifF3.js → chunk-FMBD7UC4.itTQyHQB.js} +1 -1
  46. package/web/_astro/{chunk-ND2GUHAM.BCnoXKCw.js → chunk-ND2GUHAM.euSrbJf5.js} +1 -1
  47. package/web/_astro/{chunk-QZHKN3VN.RSmy2hDO.js → chunk-QZHKN3VN.OWASJRQy.js} +1 -1
  48. package/web/_astro/{classDiagram-4FO5ZUOK.Be7PEfrX.js → classDiagram-4FO5ZUOK.BLvrlpNO.js} +1 -1
  49. package/web/_astro/{classDiagram-v2-Q7XG4LA2.Be7PEfrX.js → classDiagram-v2-Q7XG4LA2.BLvrlpNO.js} +1 -1
  50. package/web/_astro/{cose-bilkent-S5V4N54A.BkUp2aSK.js → cose-bilkent-S5V4N54A.XBF-rmyD.js} +1 -1
  51. package/web/_astro/{cynefin-OW5HDTMX.BegGGlUV.js → cynefin-OW5HDTMX.DlCx762Z.js} +1 -1
  52. package/web/_astro/{dagre-BM42HDAG.BkUdjsaC.js → dagre-BM42HDAG.D17Rshxv.js} +1 -1
  53. package/web/_astro/{diagram-2AECGRRQ.E9vugt3-.js → diagram-2AECGRRQ.AhBIVJC8.js} +1 -1
  54. package/web/_astro/{diagram-5GNKFQAL.Dj4yeHXB.js → diagram-5GNKFQAL.C9ximjyC.js} +1 -1
  55. package/web/_astro/{diagram-KO2AKTUF.Buaquwli.js → diagram-KO2AKTUF.CZb7Ru_9.js} +1 -1
  56. package/web/_astro/{diagram-LMA3HP47.BV3dgGgm.js → diagram-LMA3HP47.BW7LwqoS.js} +1 -1
  57. package/web/_astro/{diagram-OG6HWLK6.Cnx3s-tc.js → diagram-OG6HWLK6.XC025W0V.js} +1 -1
  58. package/web/_astro/{erDiagram-TEJ5UH35.DKK_abu4.js → erDiagram-TEJ5UH35.CpMXmBDP.js} +1 -1
  59. package/web/_astro/{flowDiagram-I6XJVG4X.BNuu9fbm.js → flowDiagram-I6XJVG4X.D2ednJWg.js} +1 -1
  60. package/web/_astro/{ganttDiagram-6RSMTGT7.b16KUMjy.js → ganttDiagram-6RSMTGT7.BjL9FGKO.js} +1 -1
  61. package/web/_astro/{gitGraphDiagram-PVQCEYII.Kh41lbG5.js → gitGraphDiagram-PVQCEYII.B90g1VGk.js} +1 -1
  62. package/web/_astro/{infoDiagram-5YYISTIA.DEWBXkp-.js → infoDiagram-5YYISTIA.RqgycKtQ.js} +1 -1
  63. package/web/_astro/{ishikawaDiagram-YF4QCWOH.DiAdmcL6.js → ishikawaDiagram-YF4QCWOH.Ctn-zt6a.js} +1 -1
  64. package/web/_astro/{journeyDiagram-JHISSGLW.D1Ki7IRm.js → journeyDiagram-JHISSGLW.DJhT8Ctp.js} +1 -1
  65. package/web/_astro/{kanban-definition-UN3LZRKU.CWUhrQpc.js → kanban-definition-UN3LZRKU.BY1QdejI.js} +1 -1
  66. package/web/_astro/{linear.BaFsgcCe.js → linear.Di7YObSt.js} +1 -1
  67. package/web/_astro/{mermaid.core.CHw_AsGy.js → mermaid.core.CbxtJS3Q.js} +4 -4
  68. package/web/_astro/{mindmap-definition-RKZ34NQL.UIhghgmN.js → mindmap-definition-RKZ34NQL.CxvR4g_J.js} +1 -1
  69. package/web/_astro/{pieDiagram-4H26LBE5.D05l3JUA.js → pieDiagram-4H26LBE5.jNWqnBHH.js} +1 -1
  70. package/web/_astro/{quadrantDiagram-W4KKPZXB.BcWIhIcE.js → quadrantDiagram-W4KKPZXB.BCp12MbA.js} +1 -1
  71. package/web/_astro/{requirementDiagram-4Y6WPE33.B1rYvKGn.js → requirementDiagram-4Y6WPE33.Dxhm4TyR.js} +1 -1
  72. package/web/_astro/{sankeyDiagram-5OEKKPKP.CKylVRC4.js → sankeyDiagram-5OEKKPKP.BtQXp4J9.js} +1 -1
  73. package/web/_astro/{sequenceDiagram-3UESZ5HK.Dm3uA_s4.js → sequenceDiagram-3UESZ5HK.BWEM1R_Q.js} +1 -1
  74. package/web/_astro/{stateDiagram-AJRCARHV.Bgca_BLe.js → stateDiagram-AJRCARHV.BG3wUkWB.js} +1 -1
  75. package/web/_astro/{stateDiagram-v2-BHNVJYJU.C1T7YFrG.js → stateDiagram-v2-BHNVJYJU.BLtMeFVP.js} +1 -1
  76. package/web/_astro/{timeline-definition-PNZ67QCA.ZOHJn3Sn.js → timeline-definition-PNZ67QCA.D5fHo0az.js} +1 -1
  77. package/web/_astro/{vennDiagram-CIIHVFJN.DegZitjD.js → vennDiagram-CIIHVFJN.0DcuMluU.js} +1 -1
  78. package/web/_astro/{wardleyDiagram-YWT4CUSO.BDsC115d.js → wardleyDiagram-YWT4CUSO.BZ-dxgHm.js} +1 -1
  79. package/web/_astro/{xychartDiagram-2RQKCTM6.D0MO70ea.js → xychartDiagram-2RQKCTM6.Bg-XWF7z.js} +1 -1
  80. package/web/index.html +1 -1
  81. package/web/_astro/BoardApp.DBEin4N5.js +0 -1
  82. package/web/_astro/channel.BGn_DUCD.js +0 -1
@@ -421,6 +421,23 @@ written for a batch with nothing to run. The early-exit report carries zero per-
421
421
  terminal action runs. A contract test pins this
422
422
  (`plugins/sp/tests/dogfood-testing/execution-batch-contract.test.ts`).
423
423
 
424
+ **Evidence persistence (worktree batches — task 0720 R3).** A worktree batch's Step 5 report and
425
+ verdict artifacts live in the worktree's own `.spur/run/` while the batch runs — exactly the tree
426
+ create-mode WT-4 deletes. Before any WT-4 removal, persist them into the **invoking** tree, which
427
+ survives removal:
428
+
429
+ - Write the emitted batch report to `.spur/run/worktree-<marker-id>-batch-report.md`.
430
+ - Copy each attempted task's `.spur/run/<wbs>-verdict.json` from the worktree to
431
+ `.spur/run/worktree-<marker-id>-verdicts/<wbs>-verdict.json`.
432
+ - Make the report's per-task verdict references use those persisted invoking-tree paths, not the
433
+ worktree-local paths that removal deletes.
434
+
435
+ Evidence persistence precedes destructive cleanup: a persistence failure (unreadable verdict file,
436
+ disk-full, missing directory) routes to **WT-5** — the worktree and branch are retained so a green
437
+ batch can never destroy its own evidence. Reuse mode retains its operator-owned tree but still
438
+ persists the Step 5 report under the invoking tree; the reused tree's `.spur/run/` remains the live
439
+ copy while that tree lives on.
440
+
424
441
  ## Worktree isolation (`--worktree [<name>]`)
425
442
 
426
443
  When a batch command (`dev-runall`, `dev-refineall`, `dev-verifyall`) is invoked with
@@ -671,14 +688,52 @@ git checkout "$BASE_REF"
671
688
  [ "$(git rev-list --count "$BASE_SHA..$BRANCH")" -gt 0 ] \
672
689
  || { echo "halt: branch carries no commits - nothing to merge" >&2; false; } # -> WT-5
673
690
  git merge --ff-only "$BRANCH" # FF-only: never rebase, merge-commit, or resolve conflicts
674
- # if FF succeeded:
691
+ # if FF succeeded — WT-4a evidence persistence (Step 5, task 0720 R3) runs FIRST:
692
+ # persist the batch report + verdict artifacts into the invoking tree's .spur/run/
693
+ # before anything below touches the worktree. Persistence failure routes to WT-5.
694
+ #
695
+ # WT-4b — bounded CWD-holder cleanup (task 0720 R1). Resolve the EXACT absolute
696
+ # worktree path; a relative path or a stale entry matches the wrong processes.
697
+ WT_PATH="$(cd "../<worktree-dir>" && pwd)"
698
+ # Holders = processes with any open fd under the worktree tree (lsof +D walks the
699
+ # tree; CWD holders are the common case but +D also catches open-file holders —
700
+ # over-match errs toward removal success; a plain -t <dir> matches only the
701
+ # directory itself). Orphaned `serve` proof daemons (PPID 1) are exactly this
702
+ # class: they defeat `git worktree remove` (ENOTEMPTY), defeat rm -rf, while
703
+ # `git worktree prune` still deregisters the tree. Note +D is a full-tree walk,
704
+ # so the wait loop below bounds ITERATIONS (6 × 1s ticks + walk cost), not
705
+ # wall-clock.
706
+ HOLDERS="$(lsof -t +D "$WT_PATH" 2>/dev/null | sort -u)"
707
+ if [ -n "$HOLDERS" ]; then
708
+ kill -TERM $HOLDERS 2>/dev/null # 1) TERM first, all holders (unquoted — word-split PID list)
709
+ for _ in 1 2 3 4 5 6; do # 2) bounded wait: 6 × 1s ticks
710
+ sleep 1
711
+ [ -z "$(lsof -t +D "$WT_PATH" 2>/dev/null)" ] && break
712
+ done
713
+ SURVIVORS="$(lsof -t +D "$WT_PATH" 2>/dev/null | sort -u)"
714
+ if [ -n "$SURVIVORS" ]; then
715
+ kill -KILL $SURVIVORS 2>/dev/null # 3) KILL only the survivors (unquoted — one arg per PID)
716
+ sleep 1
717
+ fi
718
+ fi
719
+ # 4) Re-query: only an EMPTY holder set may proceed to remove/prune/branch delete.
720
+ FINAL="$(lsof -t +D "$WT_PATH" 2>/dev/null | sort -u)"
721
+ if [ -n "$FINAL" ]; then
722
+ PORTS="$(lsof -nP -a -p "$(echo "$FINAL" | paste -sd, -)" -iTCP -sTCP:LISTEN 2>/dev/null \
723
+ | awk 'NR>1 {print $9}' | sort -u | paste -sd' ' -)"
724
+ echo "halt: worktree still held by PID(s): $FINAL ${PORTS:+listening: $PORTS}" >&2
725
+ exit 1 # -> WT-5: retain worktree + branch,
726
+ fi # NO prune/remove/branch delete
675
727
  git worktree remove "../<worktree-dir>"
676
728
  git branch -d "$BRANCH"
677
729
  # update marker: status = "merged"
678
730
  ```
679
731
 
680
- On the zero-commit guard firing, fall through to **WT-5** with the halt cause *"branch carries no
681
- commits nothing to merge"*: the worktree and branch are retained, never removed (task 0701 R1).
732
+ On either guard firing — zero-commit branch (task 0701 R1), or surviving CWD holders (task 0720 R1)
733
+ fall through to **WT-5**: the worktree and branch are retained, never removed. While any holder
734
+ remains, do **not** run `git worktree prune`, `git worktree remove`, or branch deletion. The holder
735
+ halt report names every surviving PID; the listening port is best-effort — a CWD holder may own no
736
+ socket, and `lsof` port discovery failing must not hide the PIDs.
682
737
 
683
738
  #### Reuse mode — merge, retain
684
739
 
@@ -711,14 +766,28 @@ risk losing work); WT-5 retains the worktree and branch whenever FF is impossibl
711
766
  Reuse mode is **narrower** than the carve-out (it merges but does not delete the branch), so the
712
767
  carve-out text needs no widening.
713
768
 
714
- **Lifecycle-DB disposition (task 0701 R2d).** The worktree has its own `.spur` lifecycle DB, and
715
- WT-4/WT-5 remove or retain that tree — the DB state does **not** travel with the merge. The
716
- **committed task file is authoritative**: after a green merge the branch's task files read
717
- `done`/`testing` while the invoking tree's DB still reports the pre-batch statuses. Re-sync
718
- explicitly by replaying the recorded terminal transitions in the invoking tree (`spur task update
719
- <wbs> <status>` per task, then `spur task record <wbs>`), or treat the batch report's per-task
720
- table as the source of truth. This is a deliberate choice over auto-migrating DB state: the DB is
721
- per-tree by design and the committed corpus files are the durable record.
769
+ **Lifecycle-DB disposition (task 0701 R2d, amended by 0720).** The worktree has its own `.spur`
770
+ lifecycle DB, and WT-4/WT-5 remove or retain that tree — the DB state does **not** travel with the
771
+ merge. One contract, no alternatives:
772
+
773
+ - **Committed task files own lifecycle state.** The **committed task file is authoritative**: after
774
+ a green merge the branch's task files already read `done`/`testing` in the invoking tree; no
775
+ `spur task update` or `spur task record` replay runs post-merge. Replay is not "one of two
776
+ options" it is removed: it writes `updated_at`-only churn and can never restore worktree-only
777
+ DB rows.
778
+ - **The persisted invoking-tree artifacts own evidence.** The Step 5 batch report at
779
+ `.spur/run/worktree-<marker-id>-batch-report.md` and the copied verdict JSONs under
780
+ `.spur/run/worktree-<marker-id>-verdicts/` (written before WT-4 removal) are the batch/verdict
781
+ record.
782
+ - **Per-worktree lifecycle DB rows intentionally do not travel.** No `task_run_links` import, no
783
+ cross-database provenance synthesis — the DB is per-tree by design.
784
+ - **No timestamp-only corpus churn.** Post-merge the invoking tree's DB statuses may read stale
785
+ relative to the committed files; that divergence is accepted, not repaired. Do not run
786
+ `task update`/`task record` to "catch up" the DB, and do not repair churn with
787
+ `git checkout -- docs/tasks*/`.
788
+
789
+ This is a deliberate choice over auto-migrating DB state: the committed corpus files are the durable
790
+ record and the persisted run artifacts are the evidence record.
722
791
 
723
792
  ### WT-5 — Failure path: retain and report (R5)
724
793
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: inline-pipeline-driver
3
- description: "Interactive host-session interpreter for task-pipeline.yaml: execute the existing FSM without a workflow agent subprocess while preserving actions, guards, artifacts, and provenance."
3
+ description: "Interactive host-session interpreter for Spur state-machine pipelines: execute the existing FSM without a workflow agent subprocess while preserving actions, guards, artifacts, and provenance."
4
4
  see_also:
5
5
  - spur-dev
6
6
  - execution-workflow
@@ -9,12 +9,13 @@ see_also:
9
9
 
10
10
  # Inline Pipeline Driver
11
11
 
12
- This driver is the interactive control-inversion path granted by ADR-047. It applies only when an
13
- interactive `/sp:dev-run --mode full` or sequential `/sp:dev-runall` invocation omits `--agent` (now
14
- the inline default, 0687 R1) or passes `--agent inline`. A named executor, `--agent auto`, parallel
15
- batch mode, `spur workflow run`, and `spur agent run` keep the existing subprocess path.
12
+ This driver is the interactive control-inversion path granted by ADR-047. It applies when an
13
+ interactive `/sp:dev-run --mode full`, sequential `/sp:dev-runall`, `/sp:dev-idea`, or
14
+ `/sp:dev-plan` invocation omits `--agent` or passes `--agent inline`. A named executor,
15
+ `--agent auto`, parallel batch mode, `spur workflow run`, and `spur agent run` keep the existing
16
+ subprocess path.
16
17
 
17
- The project runtime definition — `task-pipeline.yaml`, resolved through the two-tier
18
+ The selected project runtime definition — `task-pipeline.yaml` or `idea-pipeline.yaml`, resolved through the two-tier
18
19
  project→bundled model (task 0648/0650, never an unbundled runtime path) — remains the sole
19
20
  FSM definition. The driver MUST read that file
20
21
  at invocation time. It must not copy the state list, actions, guards, or transition order into a
@@ -22,9 +23,9 @@ command, skill, script, or second workflow.
22
23
 
23
24
  ## Run setup
24
25
 
25
- 1. Resolve `<wbs>`, `--auto`, and any explicit `--vars`; read the YAML and overlay its `vars` defaults
26
- with those invocation values. An explicit `vars.agent` / `vars.implementAgent` is an executor
27
- selection and therefore chooses the subprocess workflow path.
26
+ 1. Resolve the command inputs, `--auto`, and any explicit `--vars`; read the selected YAML and overlay
27
+ its `vars` defaults with those invocation values. An explicit non-inline executor selection
28
+ chooses the subprocess workflow path.
28
29
  2. Allocate a collision-resistant inline run id (`uuidgen`, with a timestamp/pid fallback), create
29
30
  `.spur/run/`, and use `.spur/run/<run-id>.log` as the run log.
30
31
  3. Resolve the host session id from `.spur/context/.session.json`, accepting the normalized hook key
@@ -42,13 +43,14 @@ command, skill, script, or second workflow.
42
43
  never per action.
43
44
  - **Source of truth** = the CLI projection for layer 1; the YAML parsed in step 1 for layer 2.
44
45
  Never hand-copy or hand-derive the state list into the driver, a command, a skill, or a script.
45
- 5. Record lifecycle provenance before entering the FSM:
46
+ 5. For task execution only, record lifecycle provenance before entering the FSM:
46
47
 
47
48
  ```bash
48
49
  spur task run-link <wbs> --source inline-full --run-id <run-id> --json
49
50
  ```
50
51
 
51
- This is required for the normal `testing → done` provenance guard. It is not a guard bypass.
52
+ This is required for the normal `testing → done` provenance guard. Planning pipelines have no
53
+ task lifecycle link and skip this task-specific action.
52
54
 
53
55
  ## YAML interpreter
54
56
 
@@ -61,12 +63,15 @@ Action semantics come from the YAML and the workflow action contract:
61
63
  - `shell` — run the expanded command in the project working tree with resolved vars exported as
62
64
  environment variables. A non-zero result follows the action's existing failure policy.
63
65
  - `note` — append the expanded message to the inline run log.
66
+ - `doctor.probe` — run the declared Spur doctor once, persist its status file, and apply any
67
+ `setVars` result (including a resolved executor) before the next action or state.
64
68
  - `file.read.into-var` — read the declared file into the declared run variable before subsequent
65
69
  actions/guards.
66
70
  - `hitl.confirm` — under `profile=auto`, follow the YAML's auto-skip transition. Otherwise pause,
67
71
  surface the prompt, and resume from the same state with the operator's answer.
68
- - `agent.run` — execute the action's slash command, native-subagent-first (task 0508). Do not call
69
- `spur agent run` and do not re-enter `/sp:dev-run --mode full`. Preserve the YAML options: capture
72
+ - `agent.run` — execute the action's input in the host session. Task execution may use the native
73
+ subagent eligibility below; idea/plan never dispatch a native subagent unless the operator
74
+ explicitly requested delegation. Do not call `spur agent run` or re-enter a full pipeline. Preserve the YAML options: capture
70
75
  `answerFile`; assert `expectFile`; enforce `requireDiff` against a pre-action git snapshot,
71
76
  including the task-scope guard; honor declared error policy. `timeoutMs` is recorded as not
72
77
  applicable because the host session has no independent kill boundary.