@gobing-ai/spur 0.3.94 → 0.3.96
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/README.md +42 -0
- package/board/index.d.ts +38 -0
- package/config/plugin-scripts.json +3 -52
- package/config/rules/boundary/sp-script-placement.yaml +19 -0
- package/config/rules/strict/runtime-boundaries.yaml +5 -0
- package/config/rules/structure/test-location.yaml +2 -0
- package/config/rules/typescript/no-syscall-emulation-in-boundary-mock.yaml +1 -1
- package/config/rules/typescript/output-boundaries.yaml +15 -2
- package/config/script-placement-baseline.json +51 -0
- package/config/workflows/feature-verification.yaml +7 -4
- package/config/workflows/history-anatomy.yaml +23 -11
- package/config/workflows/idea-pipeline.yaml +87 -86
- package/config/workflows/pr-review.yaml +18 -9
- package/config/workflows/task-pipeline.yaml +84 -109
- package/config/workflows/wrapup-pipeline.yaml +173 -46
- package/package.json +15 -11
- package/plugins/sp/README.md +8 -10
- package/plugins/sp/agents/super-reviewer.md +43 -18
- package/plugins/sp/commands/dev-fixgha.md +83 -0
- package/plugins/sp/commands/dev-gitmsg.md +8 -6
- package/plugins/sp/commands/dev-gtd.md +2 -2
- package/plugins/sp/commands/dev-idea.md +22 -12
- package/plugins/sp/commands/dev-plan.md +8 -9
- package/plugins/sp/commands/dev-review.md +22 -13
- package/plugins/sp/commands/dev-verify.md +7 -4
- package/plugins/sp/commands/dev-verifyall.md +5 -4
- package/plugins/sp/commands/dev-wrap.md +1 -1
- package/plugins/sp/commands/spur-init.md +2 -2
- package/plugins/sp/hooks/context-post-tool.ts +2 -2
- package/plugins/sp/hooks/context-session-start.ts +2 -1
- package/plugins/sp/hooks/context-session-stop.ts +22 -14
- package/plugins/sp/hooks/pi/guard-extension.ts +109 -150
- package/plugins/sp/lib/history-anatomy.generated.d.mts +112 -0
- package/plugins/sp/lib/history-anatomy.generated.mjs +686 -0
- package/plugins/sp/lib/idea-handoff.generated.mjs +6 -5
- package/plugins/sp/lib/inline-run.generated.d.mts +13 -2
- package/plugins/sp/lib/inline-run.generated.mjs +33 -16
- package/plugins/sp/lib/quality-gate.generated.d.mts +104 -0
- package/plugins/sp/lib/quality-gate.generated.mjs +438 -0
- package/plugins/sp/lib/residual-scan.generated.d.mts +62 -0
- package/plugins/sp/lib/residual-scan.generated.mjs +210 -0
- package/plugins/sp/lib/spur-bin.ts +36 -0
- package/plugins/sp/lib/step-profile.generated.d.mts +71 -0
- package/plugins/sp/lib/step-profile.generated.mjs +174 -0
- package/plugins/sp/plugin.json +1 -1
- package/plugins/sp/references/roles.md +1 -1
- package/plugins/sp/scripts/daily-summary/daily-summary.mjs +3 -3
- package/plugins/sp/scripts/daily-summary/daily-summary.ts +3 -3
- package/plugins/sp/scripts/dogfood-testing/detect-pipeline-driving.mjs +2 -0
- package/plugins/sp/scripts/dogfood-testing/detect-pipeline-driving.ts +1 -0
- package/plugins/sp/scripts/dogfood-testing/validate-report.mjs +9 -7
- package/plugins/sp/scripts/dogfood-testing/validate-report.ts +8 -7
- package/plugins/sp/scripts/feature-verification-steps.ts +6 -6
- package/plugins/sp/scripts/history-anatomy-cache.mjs +23 -22
- package/plugins/sp/scripts/history-anatomy-cache.ts +23 -928
- package/plugins/sp/scripts/inline-run-setup.mjs +90 -315
- package/plugins/sp/scripts/inline-run-setup.ts +109 -639
- package/plugins/sp/scripts/pr-reviewing.mjs +2 -0
- package/plugins/sp/scripts/pr-reviewing.ts +1 -0
- package/plugins/sp/scripts/quality-gate.mjs +38 -21
- package/plugins/sp/scripts/quality-gate.ts +20 -660
- package/plugins/sp/scripts/residual-scan.mjs +138 -159
- package/plugins/sp/scripts/residual-scan.ts +102 -499
- package/plugins/sp/scripts/script-root.mjs +129 -0
- package/plugins/sp/scripts/script-root.ts +199 -0
- package/plugins/sp/scripts/workflow-step-profile.mjs +27 -16
- package/plugins/sp/scripts/workflow-step-profile.ts +22 -314
- package/plugins/sp/scripts/wrapup-drift-probe.mjs +12 -3
- package/plugins/sp/scripts/wrapup-drift-probe.ts +6 -3
- package/plugins/sp/scripts/wrapup-steps.mjs +42 -40
- package/plugins/sp/scripts/wrapup-steps.ts +64 -46
- package/plugins/sp/skills/code-improvement/SKILL.md +5 -4
- package/plugins/sp/skills/code-verification/SKILL.md +46 -16
- package/plugins/sp/skills/code-verification/references/verdict-schema.md +13 -2
- package/plugins/sp/skills/functional-review/SKILL.md +8 -5
- package/plugins/sp/skills/functional-review/references/verdict-schema.md +1 -1
- package/plugins/sp/skills/history-anatomy/references/modes.md +2 -1
- package/plugins/sp/skills/next-feature/references/handoff-routing.md +1 -1
- package/plugins/sp/skills/next-router/references/routing-table.md +2 -2
- package/plugins/sp/skills/spur-cli/SKILL.md +3 -3
- package/plugins/sp/skills/spur-cli/references/agent.md +10 -10
- package/plugins/sp/skills/spur-cli/references/features.md +17 -6
- package/plugins/sp/skills/spur-cli/references/init.md +17 -16
- package/plugins/sp/skills/spur-cli/references/self.md +3 -2
- package/plugins/sp/skills/spur-cli/references/serve.md +10 -10
- package/plugins/sp/skills/spur-cli/references/tasks/verbs.md +28 -5
- package/plugins/sp/skills/spur-cli/references/tasks.md +14 -8
- package/plugins/sp/skills/spur-dev/references/ac-style-guide.md +4 -3
- package/plugins/sp/skills/spur-dev/references/cross-cutting.md +11 -9
- package/plugins/sp/skills/spur-dev/references/decision-brief.md +1 -1
- package/plugins/sp/skills/spur-dev/references/dev-operations.md +86 -70
- package/plugins/sp/skills/spur-dev/references/done-housekeeping.md +3 -3
- package/plugins/sp/skills/spur-dev/references/execution-batch.md +107 -44
- package/plugins/sp/skills/spur-dev/references/execution-workflow.md +5 -9
- package/plugins/sp/skills/spur-dev/references/feature-link-helper.md +3 -3
- package/plugins/sp/skills/spur-dev/references/flag-glossary.md +31 -21
- package/plugins/sp/skills/spur-dev/references/gate-checklists.md +19 -19
- package/plugins/sp/skills/spur-dev/references/idea-evaluation.md +4 -3
- package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +35 -6
- package/plugins/sp/skills/spur-doctor/SKILL.md +1 -1
- package/plugins/sp/skills/sys-architecture/SKILL.md +3 -2
- package/plugins/sp/tsconfig.json +8 -0
- package/spur.js +6638 -4775
- package/web/_astro/BoardApp.BIjMatT1.js +1 -0
- package/web/_astro/{BoardApp.FTEs3-N8.js → BoardApp.GvjIe9Z6.js} +150 -153
- package/web/_astro/TaskDetail.BZM3EAFx.js +1 -0
- package/web/_astro/_commonjsHelpers.CqkleIqs.js +1 -0
- package/web/_astro/{arc.uuAf51IT.js → arc.HkRiZnoI.js} +1 -1
- package/web/_astro/architectureDiagram-3BPJPVTR.BDdK-tgZ.js +36 -0
- package/web/_astro/{blockDiagram-GPEHLZMM.D1mGCq3p.js → blockDiagram-GPEHLZMM.CZ9kOBxx.js} +1 -1
- package/web/_astro/board-facade-react-dom-client.B2U5wMvk.js +1 -0
- package/web/_astro/board-facade-react-dom.Cd2MuMhF.js +1 -0
- package/web/_astro/board-facade-react-jsx-dev-runtime.B_L3JzfC.js +1 -0
- package/web/_astro/board-facade-react-jsx-runtime.BY2yfHRi.js +1 -0
- package/web/_astro/board-facade-react-router-dom.Dy5pjzOw.js +1 -0
- package/web/_astro/board-facade-react-router.DjjqU27_.js +1 -0
- package/web/_astro/board-facade-react.Dgf4GRyj.js +1 -0
- package/web/_astro/{c4Diagram-AAUBKEIU.CMsolcde.js → c4Diagram-AAUBKEIU.DXK9qeRD.js} +1 -1
- package/web/_astro/channel.DlhX2MEt.js +1 -0
- package/web/_astro/{chunk-2J33WTMH.CrGA3fik.js → chunk-2J33WTMH.BTD2WeX5.js} +1 -1
- package/web/_astro/{chunk-4BX2VUAB.DsLVVla0.js → chunk-4BX2VUAB.Ci6Qbcvk.js} +1 -1
- package/web/_astro/{chunk-55IACEB6.Dxc59Tfi.js → chunk-55IACEB6.yl3zsj7p.js} +1 -1
- package/web/_astro/{chunk-727SXJPM.CaEVE2Wy.js → chunk-727SXJPM.ClXZsfyR.js} +1 -1
- package/web/_astro/{chunk-AQP2D5EJ.BiJ4HXeI.js → chunk-AQP2D5EJ.BmKWZBcP.js} +1 -1
- package/web/_astro/{chunk-FMBD7UC4.Mxf1fru5.js → chunk-FMBD7UC4.By30fcb7.js} +1 -1
- package/web/_astro/chunk-JMJ3UQ3L.BQJEJHu4.js +34 -0
- package/web/_astro/{chunk-ND2GUHAM.pyOWQixH.js → chunk-ND2GUHAM.24NmrD-k.js} +1 -1
- package/web/_astro/{chunk-QZHKN3VN.BmEsg4vr.js → chunk-QZHKN3VN.BN4sKdcS.js} +1 -1
- package/web/_astro/chunk-YNUBSHFH.CxeAygfi.js +7 -0
- package/web/_astro/{classDiagram-4FO5ZUOK.BHhhMFTO.js → classDiagram-4FO5ZUOK.CJpoMPb5.js} +1 -1
- package/web/_astro/{classDiagram-v2-Q7XG4LA2.BHhhMFTO.js → classDiagram-v2-Q7XG4LA2.CJpoMPb5.js} +1 -1
- package/web/_astro/client.BhluLQqe.js +1 -0
- package/web/_astro/client.DBpSRLnx.js +9 -0
- package/web/_astro/cose-bilkent-S5V4N54A.BraxQ2Nt.js +1 -0
- package/web/_astro/{cynefin-OW5HDTMX.C2j1_lKL.js → cynefin-OW5HDTMX.gzoU73oL.js} +1 -1
- package/web/_astro/{dagre-BM42HDAG.hZ2NCTdT.js → dagre-BM42HDAG.wyDfWySU.js} +1 -1
- package/web/_astro/{diagram-2AECGRRQ.Bfw5_EzK.js → diagram-2AECGRRQ.h2_EbMxV.js} +1 -1
- package/web/_astro/{diagram-5GNKFQAL.Bt1V_Tmk.js → diagram-5GNKFQAL.Db6dcs89.js} +1 -1
- package/web/_astro/{diagram-KO2AKTUF.DEk-YFwp.js → diagram-KO2AKTUF.NVwzxu_U.js} +1 -1
- package/web/_astro/{diagram-LMA3HP47.CDjndtQm.js → diagram-LMA3HP47.B-eNgDQk.js} +1 -1
- package/web/_astro/{diagram-OG6HWLK6.cFnUHScG.js → diagram-OG6HWLK6.Bsa8ZRbJ.js} +1 -1
- package/web/_astro/{erDiagram-TEJ5UH35.DlhYp7NV.js → erDiagram-TEJ5UH35.BospRE5Q.js} +1 -1
- package/web/_astro/{flowDiagram-I6XJVG4X.DNTpsxfx.js → flowDiagram-I6XJVG4X.DMzvHwAA.js} +1 -1
- package/web/_astro/ganttDiagram-6RSMTGT7.Dmdxgd-M.js +292 -0
- package/web/_astro/{gitGraphDiagram-PVQCEYII.DkEqNI0P.js → gitGraphDiagram-PVQCEYII.CaqdO0rL.js} +1 -1
- package/web/_astro/index.5dn-Zm-2.js +1 -0
- package/web/_astro/index.C-IqPpW2.js +1 -0
- package/web/_astro/index.Cyc_GA4f.js +1 -0
- package/web/_astro/index.EoZlzLK-.css +1 -0
- package/web/_astro/index.tZfqwSut.js +1 -0
- package/web/_astro/{infoDiagram-5YYISTIA.CrjioCTG.js → infoDiagram-5YYISTIA.DDVD9Wn7.js} +1 -1
- package/web/_astro/{ishikawaDiagram-YF4QCWOH.BcK0CN8n.js → ishikawaDiagram-YF4QCWOH.EKyCUFsL.js} +1 -1
- package/web/_astro/{journeyDiagram-JHISSGLW.p0CbBDX1.js → journeyDiagram-JHISSGLW.By2-RkYB.js} +1 -1
- package/web/_astro/jsx-runtime.DWOiEOII.js +1 -0
- package/web/_astro/{kanban-definition-UN3LZRKU.puHIFt6J.js → kanban-definition-UN3LZRKU.ar-WmlyR.js} +1 -1
- package/web/_astro/{linear.Bb-3a1d7.js → linear.BnzMBgo_.js} +1 -1
- package/web/_astro/{mermaid.core.CJDgXOJs.js → mermaid.core.DSqeFu2Y.js} +4 -4
- package/web/_astro/{mindmap-definition-RKZ34NQL.BoAZEI9t.js → mindmap-definition-RKZ34NQL.1XcF8Wh2.js} +1 -1
- package/web/_astro/{pieDiagram-4H26LBE5.CJNSdqY7.js → pieDiagram-4H26LBE5.DnItHOdK.js} +1 -1
- package/web/_astro/{quadrantDiagram-W4KKPZXB.DtTy7_0Z.js → quadrantDiagram-W4KKPZXB.BQQyrnBt.js} +1 -1
- package/web/_astro/{requirementDiagram-4Y6WPE33.BNYV98Xg.js → requirementDiagram-4Y6WPE33.Dmzxun82.js} +1 -1
- package/web/_astro/{sankeyDiagram-5OEKKPKP.DRq9DGHp.js → sankeyDiagram-5OEKKPKP.BBIeRKYB.js} +1 -1
- package/web/_astro/{sequenceDiagram-3UESZ5HK.B7KdBFCm.js → sequenceDiagram-3UESZ5HK.CUNVdBBf.js} +1 -1
- package/web/_astro/{stateDiagram-AJRCARHV.CD62ZJ2H.js → stateDiagram-AJRCARHV.DlFf2sJm.js} +1 -1
- package/web/_astro/{stateDiagram-v2-BHNVJYJU.CeVk1TAj.js → stateDiagram-v2-BHNVJYJU.DXR7I1H5.js} +1 -1
- package/web/_astro/{timeline-definition-PNZ67QCA.C_ZPA5tT.js → timeline-definition-PNZ67QCA.BcO-GyX2.js} +1 -1
- package/web/_astro/{vennDiagram-CIIHVFJN.CrThO_FQ.js → vennDiagram-CIIHVFJN.ChCECmmW.js} +1 -1
- package/web/_astro/{wardleyDiagram-YWT4CUSO.DSZCA5nl.js → wardleyDiagram-YWT4CUSO.CRaT12mD.js} +1 -1
- package/web/_astro/{xychartDiagram-2RQKCTM6.KI7baTuk.js → xychartDiagram-2RQKCTM6.B3lsHVpj.js} +1 -1
- package/web/board-runtime.json +69 -0
- package/web/index.html +2 -2
- package/plugins/sp/lib/artifact-digest.generated.d.mts +0 -7
- package/plugins/sp/lib/artifact-digest.generated.mjs +0 -48
- package/plugins/sp/scripts/feature-sync-bounded.mjs +0 -298
- package/plugins/sp/scripts/feature-sync-bounded.ts +0 -479
- package/plugins/sp/scripts/idea-coverage-check.ts +0 -168
- package/plugins/sp/scripts/inline-pipeline-parity-check.ts +0 -298
- package/plugins/sp/scripts/record-feature-sync.mjs +0 -63
- package/plugins/sp/scripts/record-feature-sync.ts +0 -84
- package/plugins/sp/scripts/script-contract-check.ts +0 -377
- package/plugins/sp/scripts/stage-registry-adapter.ts +0 -1533
- package/plugins/sp/scripts/surface-drift-inventory.ts +0 -989
- package/plugins/sp/scripts/task-evidence-precheck.ts +0 -187
- package/plugins/sp/scripts/task-size-precheck.ts +0 -210
- package/plugins/sp/scripts/transition-shim-check.ts +0 -238
- package/plugins/sp/scripts/validate-commands.ts +0 -689
- package/plugins/sp/scripts/validate-flag-contracts.ts +0 -878
- package/plugins/sp/scripts/verify-answer-lint.ts +0 -547
- package/web/_astro/BoardApp.C02hAHPO.js +0 -1
- package/web/_astro/TaskDetail.C-GdsS-t.js +0 -1
- package/web/_astro/architectureDiagram-3BPJPVTR.CGe629A1.js +0 -36
- package/web/_astro/channel.fsgl7o5j.js +0 -1
- package/web/_astro/client.yhYJvxCU.js +0 -9
- package/web/_astro/cose-bilkent-S5V4N54A.2fH4YOlp.js +0 -1
- package/web/_astro/ganttDiagram-6RSMTGT7.DC_p36PI.js +0 -292
- package/web/_astro/index.De90oHcH.js +0 -1
- package/web/_astro/index.Hjbr15fG.css +0 -1
|
@@ -68,13 +68,13 @@ each would be scope creep for one-liner procedures.
|
|
|
68
68
|
| # | Operation | Command | Backing | Skill / Verb | Arg-hint |
|
|
69
69
|
| --- | ---------- | ------------------- | ----------------- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
70
70
|
| 1 | unit | `dev-unit` | `Skill()` | `sp:code-testing` | `<target> [--coverage <pct>] [--agent <inline\|auto\|name>] [--auto]` |
|
|
71
|
-
| 2 | review | `dev-review` | `Skill()` | `sp:code-verification` (`review`) + `sp:functional-review` + `sp:code-improvement` | `[<
|
|
71
|
+
| 2 | review | `dev-review` | `Skill()` | `sp:code-verification` (`review`) + `sp:functional-review` + `sp:code-improvement` | `[--tasks <selector> \| --feature <id>[,<id>] \| --scope <path>[,<path>]] [--agent <inline\|auto\|name>] [--focus <dims>] [--triage] [--worktree [<name>]] [--auto]` |
|
|
72
72
|
| 3 | verify | `dev-verify` | `Skill()` | `sp:code-verification` (`verify`) | `<wbs> [--agent <inline\|auto\|name>] [--fix <none\|blockers-first\|all>] [--focus <lens>] [--bdd] [--auto] [--force] [--next] [--skip-shippable]` |
|
|
73
73
|
| 3a | verifyall | `dev-verifyall` | `Skill()` → agent | `sp:spur-dev` (`verifyall`) | `--tasks <selector> [--feature <id>] [--agent <inline\|auto\|name>] [--fix <none\|blockers-first\|all>] [--focus <lens>] [--bdd] [--auto] [--force] [--next] [--json] [--skip-shippable] [--worktree [<name>]]` |
|
|
74
74
|
| 4 | run | `dev-run` | `Skill()` | `sp:spur-dev` (`run` / `implement`) | `<wbs> [--mode <full\|implement>] [--agent <inline\|auto\|name>] [--auto] [--next] [--wrap] [--continue] [--worktree [<name>]]` |
|
|
75
75
|
| 5 | refine | `dev-refine` | `Skill()` | `sp:spur-dev` (`refine`) | `<wbs> [--focus <mode>] [--description <text>] [--depth <standard\|ready>] [--agent <inline\|auto\|name>] [--auto] [--next]` |
|
|
76
76
|
| 5a | refineall | `dev-refineall` | `Skill()` | `sp:spur-dev` (`refineall`) | `--feature <id> \| --tasks <selector> [--focus <mode>] [--description <text>] [--depth <standard\|ready>] [--agent <inline\|auto\|name>] [--auto] [--keep-going] [--status <s>] [--json] [--worktree [<name>]]` |
|
|
77
|
-
| 6 | plan | `dev-plan` | `Skill()` | inline driver (`idea-pipeline`) or async workflow | `"<description>" [--feature <id>] [--parent <feature-id>] [--agent <inline\|auto\|name>] [--
|
|
77
|
+
| 6 | plan | `dev-plan` | `Skill()` | inline driver (`idea-pipeline`) or async workflow | `"<description>" [--feature <id>] [--parent <feature-id>] [--skip-design] [--agent <inline\|auto\|name>] [--auto]` |
|
|
78
78
|
| 7 | docs | _(no thin wrapper)_ | `Skill()` | `sp:doc-evolve` | `"<change description>"` |
|
|
79
79
|
| 8 | changelog | `dev-changelog` | `inline` | git log + conventional-commit grouping | `[--since <ref>] [--until <ref>] [--version <ver>]` |
|
|
80
80
|
| 9 | gitmsg | `dev-gitmsg` | `inline` | bounded diff capture → concern grouping → conventional commit | `[--commit] [--squash] [--all] [--scope <path>]` |
|
|
@@ -85,7 +85,7 @@ each would be scope creep for one-liner procedures.
|
|
|
85
85
|
| 13a | parallel | `dev-parallel` | `Skill()` | `sp:parallel-execution` | `--tasks <selector> [--feature <id>] [--mode <fan-out\|review-panel\|investigation>] [--agent <inline\|auto\|name>] [--json]` |
|
|
86
86
|
| 14 | wrap | `dev-wrap` | `Skill()` | `spur workflow run` (wrapup-pipeline) | `<wbs> [--agent <inline\|auto\|name>] [--auto] [--merge] [--dry-run]` |
|
|
87
87
|
| 15 | wrapall | `dev-wrapall` | `Skill()` | `spur workflow run` (wrapup-pipeline) | `[--since <iso>] [--feature <id>] [--status <s>] [--agent <inline\|auto\|name>] [--auto] [--merge] [--dry-run]` |
|
|
88
|
-
| 16 | idea | `dev-idea` | `Skill()` | inline driver (`idea-pipeline`) or async workflow | `"<idea>"
|
|
88
|
+
| 16 | idea | `dev-idea` | `Skill()` | inline driver (`idea-pipeline`) or async workflow | `"<idea>" \| --from-file <path> [--skip-design] [--agent <inline\|auto\|name>] [--auto]` |
|
|
89
89
|
| 17 | refactor | `dev-refactor` | `Skill()` | `sp:code-refactoring` skill (thin wrapper, ADR-032) | `[<description>] [--scope <path>] [--focus <api\|architect\|tests\|ui\|auto>] [--fix <none\|blockers-first\|all>] [--check <cmd>] [--agent <inline\|auto\|name>] [--auto]` |
|
|
90
90
|
|
|
91
91
|
## Skill-backed operations
|
|
@@ -112,17 +112,19 @@ must not be changed without updating the backing skill.
|
|
|
112
112
|
|
|
113
113
|
### 2. review
|
|
114
114
|
|
|
115
|
-
- **Purpose:** Multi-dimensional code review of a task or
|
|
115
|
+
- **Purpose:** Multi-dimensional code review of a task, a task set, or paths — (1) functional requirements traceability (per task target), (2) SECUA framework (Security, Efficiency, Correctness, Usability, Architecture), (3) architecture depth.
|
|
116
116
|
- **Modes:**
|
|
117
|
-
- **
|
|
118
|
-
- **
|
|
119
|
-
- **
|
|
117
|
+
- **Task-set mode (`--tasks <selector>` / `--feature <id>[,<id>]`)**: resolves the set once with the batch selector grammar ([execution-batch.md § Step 1](execution-batch.md#step-1--selector-resolution-r1)) — comma WBS list or `feature:<id>` (the `--feature` comma list is union sugar); status pseudo-lists and `ready` are rejected for review. One WBS-mode review per implemented task, each writing its own merged `## Review` (F92 0593 R1); tasks in `backlog`/`todo`/`blocked` are reported NOT-STARTED and skipped (§ 3a vocabulary); a per-task failure does not stop the remaining tasks; the run ends with a combined summary table (WBS, verdict, P1/P2 counts).
|
|
118
|
+
- **WBS mode (`<wbs>`, the per-task recipe)**: Runs functional requirements traceability (`sp:functional-review`), SECUA framework (`sp:code-verification`), and architectural depth (`sp:code-improvement`). The three skills return review fragments; the coordinator writes the combined `## Review` (F92 0593 R1).
|
|
119
|
+
- **Path mode (`<path>`, the per-path recipe)**: Runs advisory SECUA framework (`sp:code-verification`) and architectural depth (`sp:code-improvement`). Performs no task mutation.
|
|
120
|
+
- **Path-set mode (`--scope <path>[,<path>]`)**: paths must exist (exit 2 otherwise), are normalized, duplicates dropped and nested paths collapse to the ancestor (`--scope apps,apps/cli` → `apps`); one advisory sub-review per surviving path (Step 3p path scope, eligible for native-subagent dispatch per [dispatch-surface.md](../../parallel-execution/references/dispatch-surface.md)); the coordinator merges the sub-reviews, runs one cross-path architecture pass (`sp:code-improvement` over the inter-path imports), and emits one merged advisory report. No task mutation.
|
|
121
|
+
- **Inputs:** exactly one of `--tasks <selector>`, `--feature <id>[,<id>]`, or `--scope <path>[,<path>]` (deprecated positional alias, below) — more than one exits 2 naming the conflict; none exits 2 with usage (no implicit `cwd` target). Review executes inline (in-session) by default. `--agent <inline|auto|name>` selector accepted (see [SSOT](cross-cutting.md#inline-default-execution-surface)). `--focus <dims>` narrows the review dimensions — vocabulary SSOT: [code-verification/SKILL.md](../../code-verification/SKILL.md) review mode (`functional` → `sp:functional-review`; `architecture` → `sp:code-improvement` + SECUA-A; S/E/C/U → `sp:code-verification`). `--auto` skips objective HITL confirmations (the pipeline's review stage passes it). `--triage` opts into bounded remediation after the report (below). `--worktree [<name>]` isolates the triage writes (below; requires `--triage`). Note: the positional `<wbs\|path>` is a **deprecated alias** for one release — a `^\d{4}$` token with a resolvable task → `--tasks`; an existing path → `--scope`; otherwise exit 2, with a deprecation warning naming the replacement. `--fix` is **deprecated** (accepted no-op with warning; route remediation to `--triage` or `/sp:dev-verify --fix`); `--next` is **removed** (route progression to `/sp:dev-next`). The task pipeline's review stage never passes `--triage` or `--worktree`.
|
|
120
122
|
- **Triage (`--triage`):** runs inline in the invoking session after the merged report — never inside `sp:super-reviewer` or the review skills, which stay report-only. With `--agent <name>`, only the review is delegated; triage still runs inline on the returned findings. Never fix straight from the raw findings list:
|
|
121
123
|
1. **Bucket every finding exactly once.** **Direct fix** — local, low-risk, obvious root cause: no design choice, no public-surface / schema / dependency change, not a shared write path, verifiable by a targeted check (docs, a guard, a missing throw, a wrong path helper, a stale comment). **Task** — real and actionable but needs design, crosses modules, touches a public surface, or is not verifiable locally; skip it when an existing task already owns it (cite that WBS). **Note** — pre-existing, environmental, or ownerless; report only.
|
|
122
124
|
2. **Apply direct fixes** — smallest surgical diff in project style, then re-verify each with its targeted check (focused test, lint, or the exact command that exhibited the defect). A fix that grows beyond the bar or fails its check moves to the Task bucket with what was learned; do not leave it half-applied.
|
|
123
|
-
3. **File the Task bucket as one or more tasks**, one per cohesive unit of work that one agent can implement and verify in one run — split unrelated fixes, merge findings that share a root cause or file set. File under the existing feature that owns the affected surface; if none fits, create a child feature under the closest existing parent — never a new root feature. Write through the CLI-gated corpus surface only (`spur task create --feature <id> --skip-ready`, then `spur task update <wbs> --section <s> --from-file`). Each task must meet the implement-ready bar ([§ 5. refine](#5-refine), `--depth ready`) so it cannot drift: per finding the evidence (`file:line`), the defect, the chosen fix direction with rejected alternatives, file targets, AC, and out-of-scope; promote `backlog → todo` only when `spur task check <wbs> --json` is clean. Name what the direct fixes already resolved in each task's Background.
|
|
125
|
+
3. **File the Task bucket as one or more tasks**, one per cohesive unit of work that one agent can implement and verify in one run — split unrelated fixes, merge findings that share a root cause or file set. File under the existing non-terminal feature that owns the affected surface (a `done` owner blocks `todo` promotion with `L4.feature-terminal` — reopen it with `spur feature update <id> active` when its goal still covers the work); if none fits, create a child feature under the closest existing parent — never a new root feature. Write through the CLI-gated corpus surface only (`spur task create --feature <id> --skip-ready`, then `spur task update <wbs> --section <s> --from-file`). Each task must meet the implement-ready bar ([§ 5. refine](#5-refine), `--depth ready`) so it cannot drift: per finding the evidence (`file:line`), the defect (a root cause not reproduced in this session is written as a labeled hypothesis with its confirming repro, never as the fix premise), the chosen fix direction with rejected alternatives, file targets, AC, and out-of-scope; promote `backlog → todo` only when `spur task check <wbs> --json` is clean. Name what the direct fixes already resolved in each task's Background.
|
|
124
126
|
4. **Gate and report.** Run the project gate once after the direct fixes. Report a Triage section: each applied fix (path + one-line what + verification), each filed task (WBS + feature + scope), and the Notes. Never commit or create a branch outside `--worktree`.
|
|
125
|
-
- **Worktree (`--worktree [<name>]`):** omitted → all writes land in the current working tree on the current branch; no branch creation, checkout, or commit (the operator commits). Given → the [execution-batch.md § Worktree isolation](execution-batch.md#worktree-isolation---worktree-name) lifecycle as a run of one: marker `command` = `dev-review`, `selector` = the
|
|
127
|
+
- **Worktree (`--worktree [<name>]`):** omitted → all writes land in the current working tree on the current branch; no branch creation, checkout, or commit (the operator commits). Given → the [execution-batch.md § Worktree isolation](execution-batch.md#worktree-isolation---worktree-name) lifecycle as a run of one: marker `command` = `dev-review`, `selector` = the full normalized target list, derived branch/directory slug = `sp/review-<first>-and-<N>-<short-id>` for a multi-target run (N = target count) or `sp/review-<slug>-<short-id>` for a single target (the WBS or the path's basename). Admission is "every target resolves" (each a known WBS or an existing path) — no `quickReadiness` task-set check. Review and triage both run in the tree; WT-3b commits the fixes and filed tasks, bucketed across all targets once (identical `file:line` findings deduped). The WT-4 success condition reads as "every direct fix passed its check and the project gate is green"; a failed check or gate takes the WT-5 retention path. Rejected without `--triage` (WT-7) — to review another worktree read-only, pass a path inside it.
|
|
126
128
|
- **Backing:** `sp:functional-review`, `sp:code-verification` (review mode), `sp:code-improvement`.
|
|
127
129
|
- **Behavior:** WBS mode runs functional traceability + SECUA + architecture depth, ranking findings P1–P4, and hands the merged report to the review coordinator, which writes `## Review`. Component skills never write `## Review` in coordinated mode. Path mode runs advisory SECUA + architecture depth with no task mutation.
|
|
128
130
|
- **Delegation:** WBS mode: `sp:functional-review` + `sp:code-verification` (review) + `sp:code-improvement`; Path mode: `sp:code-verification` (review) + `sp:code-improvement`.
|
|
@@ -322,7 +324,7 @@ must not be changed without updating the backing skill.
|
|
|
322
324
|
- **Inputs:** `"<description>"` (required). `--feature <id>` links to an existing feature. `--parent <feature-id>` nests under a parent. Omitted/`inline` drives `idea-pipeline.yaml` in the host session; `auto` or a name launches the async workflow worker. **Design package flags (unified with `/sp:dev-idea`):**
|
|
323
325
|
- **Default:** author task `design` on every batch item + feature satellite when the seam heuristic fires (**ties lean design**). There is **no** `--design` force flag.
|
|
324
326
|
- `--skip-design` — skip feature satellite **and** omit task `design` fields (scaffold only; refine fills later). Sole design opt-out.
|
|
325
|
-
- `--
|
|
327
|
+
- `--auto` — accept the recommendation at every operator gate, taste gates included (same contract as § 16 idea).
|
|
326
328
|
- **Backing:** `sp:spur-dev` skill, `plan` operation. Stage floor: the `planner` role per [`roles.md`](../../../references/roles.md) — this file names roles, never tiers (0538 R4).
|
|
327
329
|
- **Behavior:** Clarify scope → `spur feature create` → author BDD AC → `spur feature check` gate → decompose into task-batch JSON **including `design` (unless `--skip-design`)** → `spur task batch-create` gate. Design package details: [planning-workflow.md](planning-workflow.md) Step 5.5.
|
|
328
330
|
- **Delegation:** `Skill(skill="sp:spur-dev", args="plan $ARGUMENTS")`
|
|
@@ -369,7 +371,7 @@ must not be changed without updating the backing skill.
|
|
|
369
371
|
- **Purpose:** Wrap up a single completed task — capture learnings, record metrics, sync docs, and optionally advance the feature / clean up the branch.
|
|
370
372
|
- **Inputs:** `<wbs>` (required, positional). `--agent <inline|auto|name>` names the wrap's model-bearing executor (default: `inline`, resolving identically when omitted; task 0687); wrap is workflow-backed (headless), so omit ≡ explicit `inline` (task 0687): tier substitution under objective trigger 3 (durable auditable run record required) plus one warning naming the substituted executor. `auto` tier-resolves an executor, and a name pins that executor into `vars.agent` (see [SSOT](cross-cutting.md#inline-default-execution-surface)). `--auto` skips objective confirmations (the branch-cleanup HITL gate still pauses — irreversible). `--merge` triggers branch cleanup (irreversible HITL gate).
|
|
371
373
|
- **Backing:** `spur workflow run wrapup-pipeline.yaml` — direct workflow invocation (no backing skill; the pipeline IS the procedure).
|
|
372
|
-
- **Behavior:** Resolves the executor (`agent.default` for omit/`inline`, tier-resolved for `auto`, unchanged for a name), emits a pre-dispatch notice naming the subprocess override — `execution surface: subprocess`, `reason: trigger 3 — durable auditable run record required`, `requested agent: <selector>`, `executor: <resolved>` — then builds `--vars '{"tasks":"[\"<wbs>\"]","agent":"<resolved>","profile":"interactive|auto","merge":"true|false"}'` and invokes the wrapup pipeline. The pipeline runs: task-resolve → doc-sync →
|
|
374
|
+
- **Behavior:** Resolves the executor (`agent.default` for omit/`inline`, tier-resolved for `auto`, unchanged for a name), emits a pre-dispatch notice naming the subprocess override — `execution surface: subprocess`, `reason: trigger 3 — durable auditable run record required`, `requested agent: <selector>`, `executor: <resolved>` — then builds `--vars '{"tasks":"[\"<wbs>\"]","agent":"<resolved>","profile":"interactive|auto","merge":"true|false"}'` and invokes the wrapup pipeline. The pipeline runs: task-resolve → doc-sync → learnings-validate → learnings-append → doc-tripwire → metrics-record → (feature-transition) → (branch-cleanup) → done. `doc-tripwire` (1037) runs the TRUSTED CONFIG ONLY `docTripwireCmd` over the still-uncommitted wrap diff after the doc-sync exits converge — the default runs `bun run test-repo-wide` only when `package.json` declares the script (a no-op in other projects); override it via `--vars`, and an empty string disables the check while still recording PASS; a FAIL fails the wrap with already-written learnings/docs preserved. Task statuses are NOT mutated. Branch cleanup is an irreversible HITL gate that always pauses, even under `--auto`.
|
|
373
375
|
- **Vars string typing:** `tasks` is a JSON-encoded **string**, not a JSON array — `spur workflow run --vars` accepts only string values (`--vars values must be strings`); the pipeline's guards parse the string with `jq length`. `jq -nc` guarantees the shape:
|
|
374
376
|
|
|
375
377
|
```bash
|
|
@@ -385,7 +387,7 @@ must not be changed without updating the backing skill.
|
|
|
385
387
|
- **Purpose:** Wrap up a batch of completed tasks — capture learnings, record metrics, sync docs, advance a feature through legal lifecycle edges, and optionally clean up branches.
|
|
386
388
|
- **Inputs:** `--since <iso-date>` filters done tasks by frontmatter `updated_at >= date` (v1 approximation). `--feature <id>` selects all tasks under a feature AND advances the feature through legal lifecycle edges (`backlog → active → verifying → done`, guards honored). `--status <s>` (default: `done`) filters by task status. `--agent <inline|auto|name>` names the wrap's model-bearing executor (default: `inline`, resolving identically when omitted; task 0687); wrap is workflow-backed (headless), so omit ≡ explicit `inline` (task 0687): tier substitution under objective trigger 3 (durable auditable run record required) plus one warning naming the substituted executor. `auto` tier-resolves an executor, and a name pins that executor into `vars.agent` (see [SSOT](cross-cutting.md#inline-default-execution-surface)). `--auto` skips objective confirmations. `--merge` triggers branch cleanup (irreversible HITL gate).
|
|
387
389
|
- **Backing:** `spur workflow run wrapup-pipeline.yaml` — direct workflow invocation.
|
|
388
|
-
- **Behavior:** Resolves the task list via `spur task list --json` (filtered by `--feature`, `--since`, `--status`), resolves the executor (omission and explicit `--agent inline` tier-substitute identically with a warning per task 0687, `auto` tier-resolves, a name pins), emits a pre-dispatch notice naming the subprocess override — `execution surface: subprocess`, `reason: trigger 3 — durable auditable run record required`, `requested agent: <selector>`, `executor: <resolved>` — then builds `--vars '{"tasks":"[...]","feature":"<id>","agent":"<resolved>","profile":"interactive|auto","merge":"true|false"}'` and invokes the wrapup pipeline. The pipeline runs the same states as `wrap` but with the full task list and optional feature transition. Task statuses are NOT mutated. Feature transitions go through `spur feature update` so lifecycle guards apply. Branch cleanup is an irreversible HITL gate.
|
|
390
|
+
- **Behavior:** Resolves the task list via `spur task list --json` (filtered by `--feature`, `--since`, `--status`), resolves the executor (omission and explicit `--agent inline` tier-substitute identically with a warning per task 0687, `auto` tier-resolves, a name pins), emits a pre-dispatch notice naming the subprocess override — `execution surface: subprocess`, `reason: trigger 3 — durable auditable run record required`, `requested agent: <selector>`, `executor: <resolved>` — then builds `--vars '{"tasks":"[...]","feature":"<id>","agent":"<resolved>","profile":"interactive|auto","merge":"true|false"}'` and invokes the wrapup pipeline. The pipeline runs the same states as `wrap` — including the `doc-tripwire` hop (1037), whose TRUSTED CONFIG ONLY `docTripwireCmd` runs the repo-wide tripwires over the still-uncommitted wrap diff and can be overridden or disabled (empty string) via `--vars` — but with the full task list and optional feature transition. Task statuses are NOT mutated. Feature transitions go through `spur feature update` so lifecycle guards apply. Branch cleanup is an irreversible HITL gate.
|
|
389
391
|
- **Vars string typing:** `tasks` is a JSON-encoded **string**, not a JSON array — `--vars` values must be strings (the CLI rejects raw arrays); `jq -nc` passes the array text through as a string value:
|
|
390
392
|
|
|
391
393
|
```bash
|
|
@@ -400,11 +402,14 @@ must not be changed without updating the backing skill.
|
|
|
400
402
|
|
|
401
403
|
- **Purpose:** Turn a vague idea into a feature with AC and a decomposed task batch — the unified entry point for the planning half.
|
|
402
404
|
- **Inputs:** `"<idea>"` (quoted) or `--from-file <path>` — exactly one; the two are mutually
|
|
403
|
-
exclusive (0887 R7).
|
|
404
|
-
- `--auto` —
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
405
|
+
exclusive (0887 R7). Two everyday axes:
|
|
406
|
+
- `--auto` — accept the recommendation at **every** operator gate (objective and taste):
|
|
407
|
+
sets `profile=auto`, `idea_approved=true`, `design_approved=true`. idea-eval follows the
|
|
408
|
+
report's `## Recommendation` (`proceed`/`reshape` continue, `drop` cancels, missing still
|
|
409
|
+
asks); design-approval approves only on a PASS design check (FAIL still asks).
|
|
410
|
+
- `--skip-design` — design package off (system-design + task Design). There is **no** `--design` force flag.
|
|
411
|
+
- Removed: `--approve-taste`, `--idea-approved`, `--design-approved` (folded into `--auto`;
|
|
412
|
+
ignored with a one-line notice if passed).
|
|
408
413
|
- `--from-file <path>` — read the idea text from a file instead of the positional argument
|
|
409
414
|
(verbatim; long/multiline asks). Mutually exclusive with `"<idea>"`.
|
|
410
415
|
- **Verbatim idea artifact:** before `start` executes, the driver persists the idea argument (or
|
|
@@ -414,7 +419,7 @@ must not be changed without updating the backing skill.
|
|
|
414
419
|
- **Backing:** `idea-pipeline.yaml` through the inline driver for omitted/`inline`, or `spur workflow run idea-pipeline.yaml --async` for `auto`/name.
|
|
415
420
|
- **Behavior:** Builds vars from the table above and drives the idea pipeline. Flow: discovery → **idea-eval** (taste; reject → cancelled) → feature-create → ac-generate → feature-check → system-design (conditional) → design-approval (taste) → decompose → batch-create (`--skip-ready`) → ready-prepare (ready checklist per created task + ready-evidence sidecar, 0788) → handoff. STOPS at handoff — no task execution, no pipeline nesting. Headless runs use one `trace --follow`; cancellation is reported stopped only when `workflow cancel --json` returns `killed: true`.
|
|
416
421
|
- **Delegation:** Host-session inline driver by default; explicit executor selection uses the async workflow worker.
|
|
417
|
-
- **Idea-evaluation gate:** After discovery, operator reviews `.spur/run/idea-eval-report.md` ([idea-evaluation.md](idea-evaluation.md)). Approve continues; reject/cancel → no feature. Under `--auto`,
|
|
422
|
+
- **Idea-evaluation gate:** After discovery, operator reviews `.spur/run/idea-eval-report.md` ([idea-evaluation.md](idea-evaluation.md)). Approve continues; reject/cancel → no feature. Under `--auto`, follows the report's recommendation (`drop` → cancelled; missing recommendation → pauses). Enhanced idea is a sidecar — `vars.idea` is not overwritten.
|
|
418
423
|
- **Design package (`--skip-design` only):**
|
|
419
424
|
|
|
420
425
|
| Flags | Feature satellite (`system-design`) | Task `### Design` in batch |
|
|
@@ -425,7 +430,7 @@ must not be changed without updating the backing skill.
|
|
|
425
430
|
Ties lean design — when the signal is ambiguous, `system-design` runs. Task Design defaults on
|
|
426
431
|
unless `--skip-design`. Plan path uses the same package contract (no `--design` force flag).
|
|
427
432
|
|
|
428
|
-
- **
|
|
433
|
+
- **Operator gates:** every pause is one `AskUserQuestion` [decision brief](decision-brief.md) — recommended option first; see the gate table in `commands/dev-idea.md` and the `hitl.confirm` rule in [inline-pipeline-driver.md](inline-pipeline-driver.md).
|
|
429
434
|
|
|
430
435
|
### 17. refactor
|
|
431
436
|
|
|
@@ -460,73 +465,84 @@ is the procedure. The backing is a combination of git CLI, `spur` CLI, and agent
|
|
|
460
465
|
|
|
461
466
|
### 9. gitmsg
|
|
462
467
|
|
|
463
|
-
- **Purpose:** Generate conventional commit message(s) for the current change set — one
|
|
468
|
+
- **Purpose:** Generate conventional commit message(s) for the current change set — one gather call → concern grouping → one message per concern; optionally commit. Git + POSIX shell only; no helper script.
|
|
464
469
|
- **Inputs:** `--scope <path>` (default: the whole change set) — path filter; an explicit `--scope` always wins over change-set auto-discovery. `--all` (default: off) — widen the change set past the index to every change in the tree: unstaged **and untracked** files. Omitted, the change set is the index only, which keeps pre-commit semantics stable. `--commit` (default: off) — commit the change set, one commit per concern. `--squash` (default: off) — collapse every concern into one message and one commit; implies `--commit`.
|
|
465
|
-
- **Backing:** `inline` — bounded
|
|
470
|
+
- **Backing:** `inline` — one bounded gather call + concern grouping + conventional commit formatting.
|
|
466
471
|
- **Behavior:**
|
|
467
472
|
|
|
468
|
-
1. **Gather
|
|
473
|
+
1. **Gather — exactly one Bash call.** Set the three variables from the flags and run the block
|
|
474
|
+
verbatim. It resolves the change set, applies the empty-index rule, and prints everything the
|
|
475
|
+
message needs; the guards run in shell, not in the model:
|
|
469
476
|
|
|
470
477
|
```bash
|
|
471
|
-
|
|
472
|
-
# --all
|
|
473
|
-
|
|
474
|
-
git
|
|
475
|
-
git diff
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
478
|
+
bash <<'EOF'
|
|
479
|
+
ALL=0 COMMIT=0 SCOPE=':/' # --all → ALL=1 · --commit/--squash → COMMIT=1 · --scope <p> → SCOPE=<p>
|
|
480
|
+
EX=(':!*.lock' ':!*lock.json' ':!*.lockb')
|
|
481
|
+
untracked() { git ls-files -o --exclude-standard -- "$SCOPE" "${EX[@]}"; }
|
|
482
|
+
if [ "$ALL" = 0 ] && git diff --cached --quiet -- "$SCOPE"; then
|
|
483
|
+
t=$(git diff --name-only HEAD -- "$SCOPE" | wc -l | tr -d ' '); u=$(untracked | wc -l | tr -d ' ')
|
|
484
|
+
[ "$COMMIT" = 1 ] && { echo "STOP index empty ($t tracked, $u untracked changed) — re-run with --all"; exit; }
|
|
485
|
+
echo "NOTE index empty — reading the whole tree instead"; ALL=1
|
|
486
|
+
fi
|
|
487
|
+
[ "$ALL" = 1 ] && R=HEAD || R=--cached
|
|
488
|
+
stream() {
|
|
489
|
+
git diff $R -U0 --diff-filter=d -- "$SCOPE" "${EX[@]}"
|
|
490
|
+
[ "$ALL" = 1 ] && untracked | while IFS= read -r f; do git diff --no-index -U0 -- /dev/null "$f"; done
|
|
491
|
+
}
|
|
492
|
+
[ -z "$(stream | head -c1)" ] && { echo "STOP no changes in $SCOPE"; exit; }
|
|
493
|
+
echo "## context"; git rev-parse --abbrev-ref HEAD --git-dir --git-common-dir --show-superproject-working-tree
|
|
494
|
+
echo "## recent subjects"; git log -12 --format=%s
|
|
495
|
+
echo "## stat"; git diff $R --stat=100 --compact-summary -- "$SCOPE"
|
|
496
|
+
[ "$ALL" = 1 ] && untracked | sed 's/^/ (untracked) /'
|
|
497
|
+
[ "$ALL" = 0 ] && { echo "## partially staged"; comm -12 <(git diff --cached --name-only | sort) <(git diff --name-only | sort); }
|
|
498
|
+
echo "## secret hits"
|
|
499
|
+
stream | awk '/^\+\+\+ /{f=substr($0,7)} /^\+[^+]/{print f": "$0}' \
|
|
500
|
+
| grep -E '(password|passwd|secret|api[_-]?key|access[_-]?token|auth[_-]?token)["'"'"']?[[:space:]]*[:=][[:space:]]*["'"'"'][^"'"'"'[:space:]]{12,}|BEGIN [A-Z ]*PRIVATE KEY|(ghp_[A-Za-z0-9]{36}|github_pat_[A-Za-z0-9_]{40,}|sk-[A-Za-z0-9_-]{20,}|AKIA[0-9A-Z]{16})' | head -5
|
|
501
|
+
echo "## diff (-U0, ≤80 lines/file, ≤40 KB)"
|
|
502
|
+
stream | awk '/^diff --git/{n=0} n++<80' | head -c 40000
|
|
503
|
+
EOF
|
|
479
504
|
```
|
|
480
505
|
|
|
481
|
-
|
|
506
|
+
What the block guarantees:
|
|
507
|
+
- **Untracked files are read, not just named** — under `--all` each one is diffed against `/dev/null`, so a new file (often the main change) shapes the message.
|
|
508
|
+
- **Every file gets a share** — the per-file 80-line cap runs before the 40 KB total cap, so one large file cannot starve the rest. Deleted files contribute only their `(gone)` stat line; lockfiles are excluded.
|
|
509
|
+
- **Empty index, no `--all`:** a message-only run widens to the whole tree and says so (`NOTE`); a committing run prints `STOP` with the counts — re-print the exact re-run line (`/sp:dev-gitmsg <same flags> --all`) and stop. Committing untracked files is never inferred.
|
|
510
|
+
- **`STOP no changes`** → report it and stop.
|
|
482
511
|
|
|
483
|
-
|
|
484
|
-
not a mutation, so the two cases split there:
|
|
485
|
-
- **No committing flag** → re-gather once with `--all` semantics and say so
|
|
486
|
-
(`index empty — read the whole tree instead`). A message-only run has nothing to lose by
|
|
487
|
-
looking wider, and the operator gets an answer instead of an errand.
|
|
488
|
-
- **`--commit` / `--squash`** → stop. Print the worktree counts (`N tracked, M untracked`) and
|
|
489
|
-
the exact re-run line (`/sp:dev-gitmsg <the same flags> --all`). Committing
|
|
490
|
-
untracked files is never inferred from an empty index — that is the operator's call, and it
|
|
491
|
-
is now one paste away rather than a guess.
|
|
512
|
+
2. **Stay inside the budget.** The block's output is the whole input. Never run a second, wider `git diff`, `git show`, or file `Read` to "see more"; never paste hunks into the output. A truncated file is typed from its stat line and path.
|
|
492
513
|
|
|
493
|
-
|
|
514
|
+
3. **Group by concern.** A concern is one coherent change a reviewer would accept or revert as a unit:
|
|
515
|
+
- Tests, docs, and registry/index updates travel **with the code they cover** — not as separate `test`/`docs` groups. A standalone `test`/`docs` group exists only when nothing else in the change set motivates it.
|
|
516
|
+
- Behavior changes and pure formatting/refactor churn are **different** concerns.
|
|
517
|
+
- Prefer fewer groups; a single group is the common case. Order groups by dependency (refactor before the feature that uses it).
|
|
494
518
|
|
|
495
|
-
|
|
519
|
+
4. **Write each message.**
|
|
520
|
+
- **Type** from the dominant change: `feat` · `fix` · `refactor` · `perf` · `docs` · `test` · `style` · `build` (deps, bundling) · `ci` (workflows, pipelines) · `chore` (other tooling/config) · `revert`.
|
|
521
|
+
- **Scope** — reuse a scope that appears in `## recent subjects` for the same area (the repo's own vocabulary beats a guessed one); `--scope <path>` overrides. Omit the scope rather than invent one.
|
|
522
|
+
- **Summary** — imperative, ≤72 chars, lowercase first word, no period; says what changed in user/maintainer terms, not which files.
|
|
523
|
+
- **Body** — only when the *why* is not obvious from the summary: intent and consequence in 1–3 lines, never a restated diff or file list. `--squash` → one combined message (dominant type/scope, one body bullet per concern).
|
|
496
524
|
|
|
497
|
-
|
|
525
|
+
5. **Report.** Print: one context line (branch; `linked worktree` when `--git-dir` ≠ `--git-common-dir` and the superproject line is empty), then each message in a fenced block. No per-file summaries, no restated diff. With neither `--commit` nor `--squash`, add one copy-paste `git commit` line per message and stop.
|
|
498
526
|
|
|
499
|
-
|
|
500
|
-
-
|
|
501
|
-
-
|
|
502
|
-
- Message:
|
|
527
|
+
6. **Commit (`--commit` / `--squash`) — one more Bash call.** `--squash` implies `--commit`, so both together is just `--squash`. Refuse before touching the index when:
|
|
528
|
+
- `## secret hits` is non-empty → print each `file: line`, commit nothing;
|
|
529
|
+
- `--commit` would split (more than one group) and `## partially staged` is non-empty → splitting would widen those `git add -p` stagings to whole files; print the paths and commit nothing (`--squash` is allowed — it commits the index as staged).
|
|
503
530
|
|
|
504
|
-
|
|
505
|
-
<type>(<scope>): <summary>
|
|
531
|
+
Otherwise run the commits in one heredoc — `--all` first stages the scope (`git add -A -- "$SCOPE"`); a single group or `--squash` is one `git commit -F -`; multiple groups commit in dependency order:
|
|
506
532
|
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
6. **Report, then commit if asked.** Print the resolved message(s), a copy-paste `git commit` line per message, and a one-line context header: current branch, and `linked worktree` when `--git-dir` differs from `--git-common-dir` and `git rev-parse --show-superproject-working-tree` is empty (a non-empty result means submodule, not worktree). With neither `--commit` nor `--squash`, stop here — the operator commits.
|
|
518
|
-
|
|
519
|
-
7. **Committing (`--commit` / `--squash`).** The two flags name outcomes, not dimensions: `--commit`
|
|
520
|
-
commits **by concern**, `--squash` commits **everything as one**. `--squash` implies `--commit`,
|
|
521
|
-
so `--commit --squash` is just `--squash`, never an error.
|
|
533
|
+
```bash
|
|
534
|
+
bash <<'EOF'
|
|
535
|
+
git reset -q -- :/ && git add -A -- <group-1 paths> && git commit -q -F - <<'MSG'
|
|
536
|
+
<group-1 message>
|
|
537
|
+
MSG
|
|
538
|
+
# …repeat per group…
|
|
539
|
+
git log --oneline -<n>; git status --short
|
|
540
|
+
EOF
|
|
541
|
+
```
|
|
522
542
|
|
|
523
|
-
|
|
524
|
-
- `--all` → `git add -A $PATHSPEC` first (this is what stages the untracked files).
|
|
525
|
-
- `--squash`, or `--commit` on a single group → `git commit -m "$MESSAGE"`.
|
|
526
|
-
- `--commit` on multiple groups → **commit each group in sequence**: record the full staged file list once, then per group `git reset -q -- <all staged paths>` → `git add -- <that group's paths>` → `git commit -m "<that group's message>"`. This is the split; it needs no re-run and no re-staging by the operator.
|
|
527
|
-
- **Partial-staging guard:** if any path appears in _both_ `git diff --cached --name-only` and `git diff --name-only` (a `git add -p` staging), the sequence above would silently widen those commits to the whole file. Do not split — report the affected paths and commit nothing unless `--squash` was given.
|
|
543
|
+
Hooks stay enabled; a failing hook stops the run with its output — never `--no-verify`.
|
|
528
544
|
|
|
529
|
-
- **Invariants:** With neither `--commit` nor `--squash`, never runs `git commit` — message only. Neither flag commits across a
|
|
545
|
+
- **Invariants:** Git and POSIX shell only — no helper script, no temp file. At most two Bash calls: gather, then (only when committing) commit. With neither `--commit` nor `--squash`, never runs `git commit` — message only. Neither flag commits across a secret hit, and `--commit` never splits across a partial staging. Without `--all` the change set is the index, so plain `/sp:dev-gitmsg` keeps pre-commit semantics; only `--all` reaches unstaged and untracked files, and only a committing run stages them. The empty-index widen is read-only and always announced — a committing run never widens its own scope. An explicit `--scope <path>` always bounds the change set, with or without `--all`. One bounded, context-free capture per run — never a second, wider read.
|
|
530
546
|
|
|
531
547
|
### 10. fixall
|
|
532
548
|
|
|
@@ -34,7 +34,7 @@ If you hand-walk lifecycle statuses (manual `spur task update <wbs> <status>` wi
|
|
|
34
34
|
pipeline), you MUST state so explicitly in your final message and name the gate you verified:
|
|
35
35
|
|
|
36
36
|
```
|
|
37
|
-
Transitioned manually. Gate verified: spur task check <wbs> --
|
|
37
|
+
Transitioned manually. Gate verified: spur task check <wbs> --as done -> PASS
|
|
38
38
|
```
|
|
39
39
|
|
|
40
40
|
Silent manual transitions are the anti-pattern to forbid. Either the pipeline ran (name the
|
|
@@ -128,7 +128,7 @@ silently incomplete (H6 shipped at 23/48 that way, with one verdict carrying an
|
|
|
128
128
|
`acceptanceCriteria` array and still reading PASS). See `ac-style-guide.md` §
|
|
129
129
|
"Verdict AC ↔ feature scenario linkage" for the id forms and evidence vocabulary.
|
|
130
130
|
|
|
131
|
-
**Parser contract (
|
|
131
|
+
**Parser contract (`spur task verdict` answer lint, 0817 re-verify findings):**
|
|
132
132
|
|
|
133
133
|
1. The requirement id cell must be the **bare** id — `| R1 | MET | … |`. Suffixes (`R1 (AC1)`) or
|
|
134
134
|
decoration (`**R1**`) fail the exact-match completeness check (`missing requirement row`).
|
|
@@ -160,7 +160,7 @@ command printing `0`.
|
|
|
160
160
|
| # | Check | Command to run (literal - paste the output) | Pass condition |
|
|
161
161
|
|---|-------|----------------------------------------------|----------------|
|
|
162
162
|
| 1 | F1 - no unchecked boxes anywhere | `grep -c '^\s*- \[ \]' <task-file>` | output is exactly `0` (whole file, not just Plan) |
|
|
163
|
-
| 2 | F2 - honest transition | (state it) | named a pipeline run-id, OR "manual + `spur task check <wbs> --
|
|
163
|
+
| 2 | F2 - honest transition | (state it) | named a pipeline run-id, OR "manual + `spur task check <wbs> --as done` PASS" |
|
|
164
164
|
| 3 | F4 - gate evidence | (recall change type) | raw gate tails pasted if code/test/infra touched; one-liner only if pure-doc |
|
|
165
165
|
| 4 | F5 - no `/tmp` residue | `ls /tmp/<wbs>-* 2>/dev/null \| wc -l` | output is `0` |
|
|
166
166
|
| 5 | Dogfood (only if in dogfood mode) | `rg -c '^### 3\. Monitor Ledger' <report> && rg -c '── Dogfood Summary ──' <report> && rg -c '^status: (complete\|aborted)' <report>` | all three counts are `>= 1` (report exists under `docs/dogfood/` AND carries the mandatory ledger section AND the mandatory summary footer AND terminal frontmatter status - not just any file matching the slug) |
|
|
@@ -64,6 +64,10 @@ function normalizeArgs(raw: Args): Args {
|
|
|
64
64
|
|
|
65
65
|
- If `--feature FOO` is present and `--tasks` is absent, treat the effective selector as `feature:FOO`.
|
|
66
66
|
- If both are present, `--tasks` wins (with a one-line note in the batch report).
|
|
67
|
+
- **Per-command admission filters (I33 1023).** Step 1 is the shared baseline; commands may layer
|
|
68
|
+
stricter grammar on top — e.g. `/sp:dev-review` rejects `ready`/status pseudo-lists and the mixed
|
|
69
|
+
`--tasks` + `--feature` combination (exit 2), and accepts multi-id `--feature <id>,<id>` as
|
|
70
|
+
caller-level sugar expanded by the command layer before the resolver.
|
|
67
71
|
|
|
68
72
|
**Feature-derived strict preflight (R2, task 0510).** After normalization, if the **effective
|
|
69
73
|
selector** is `feature:<id>` (whether via `--tasks feature:<id>` or the `--feature <id>` sugar),
|
|
@@ -291,8 +295,8 @@ Each pipeline run ends in one of two terminal states:
|
|
|
291
295
|
`.spur/run/<wbs>-verify-answer.txt` AC table is exactly four columns:
|
|
292
296
|
`| AC | Status | Evidence Type | Evidence |`. The evidence-type token
|
|
293
297
|
(`test`, `command`, `static-ref`, `manual-review`, `llm-judge`, `n/a`, or a `+`
|
|
294
|
-
compound) is isolated in cell 3. A token merged into the evidence cell fails
|
|
295
|
-
`
|
|
298
|
+
compound) is isolated in cell 3. A token merged into the evidence cell fails the
|
|
299
|
+
`spur task verdict` answer lint.
|
|
296
300
|
|
|
297
301
|
**Driver acceptance (0930 R3).** The trace row and `.spur/run/<wbs>-verdict.json` are accepted as
|
|
298
302
|
terminal evidence only if BOTH hold:
|
|
@@ -328,40 +332,35 @@ node "$(superskill script path sp batch-preflight.mjs)" --wbs <wbs> --status <st
|
|
|
328
332
|
Helper: `recoveryHint(status, wbs)` in `plugins/sp/scripts/batch-preflight.ts`. Tables remain SSOT
|
|
329
333
|
in next-router; this only maps status → primary TABLE A hop for recovery.
|
|
330
334
|
|
|
331
|
-
### 3.3c
|
|
335
|
+
### 3.3c Feature-sync retry suppression (task 0411; 1004 R3 moved it into the sync service)
|
|
332
336
|
|
|
333
337
|
During a batch, the per-task `record` step and the wrap-up `feature-transition` step each invoke
|
|
334
338
|
feature status sync. When a feature is L4-gate-blocked (e.g. not all linked tasks are `done`), the
|
|
335
339
|
identical blocked proposal repeats on every call with no intervening input change — in the H9
|
|
336
|
-
dogfood, 4 redundant sync calls produced the same blocked result. The
|
|
337
|
-
|
|
340
|
+
dogfood, 4 redundant sync calls produced the same blocked result. The service fixes this, not the
|
|
341
|
+
engine.
|
|
338
342
|
|
|
339
343
|
Both `task-pipeline.yaml` (`record` step) and `wrapup-pipeline.yaml` (`feature-transition` step)
|
|
340
|
-
invoke
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
`applied: true` while still gate-blocked), then `applied`, then `no-op`.
|
|
352
|
-
3. On a **blocked** result, persists `.spur/run/feature-sync-blocked-<id>.json` and, on the next
|
|
353
|
-
call with an **identical fingerprint**, suppresses the redundant sync and replays the prior
|
|
354
|
-
blocked result.
|
|
355
|
-
4. On **applied** or **no-op** results, passes through unchanged (no suppression).
|
|
356
|
-
5. When the fingerprint **changes** (a task completed, a verdict file updated), suppression is
|
|
344
|
+
invoke `spur feature sync <feature-id> --json` directly — retry suppression lives inside the
|
|
345
|
+
`FeatureService.syncFeature` implementation:
|
|
346
|
+
|
|
347
|
+
1. On a **blocked** result (`gateBlocked` checked first — a partial hop can have `applied: true`
|
|
348
|
+
while still gate-blocked — then an unapplied from≠to deferral), the service persists
|
|
349
|
+
`.spur/run/feature-sync-blocked-<id>.json` keyed by an input fingerprint (feature file content
|
|
350
|
+
hash, linked task statuses, verdict artifact mtimes).
|
|
351
|
+
2. On the next call with an **identical fingerprint**, the service suppresses the redundant sync
|
|
352
|
+
and replays the prior blocked result (`suppressed: true`) without re-deriving hops.
|
|
353
|
+
3. On **applied** or **no-op** results, the state file is cleared (no suppression).
|
|
354
|
+
4. When the fingerprint **changes** (a task completed, a verdict file updated), suppression is
|
|
357
355
|
invalidated and a fresh sync runs.
|
|
356
|
+
5. `--force` (and an explicit confirm re-attempt) bypass the replay and re-derive live; dry-run
|
|
357
|
+
never reads or writes the state.
|
|
358
358
|
|
|
359
|
-
**Batch driver contract:** the orchestrator does **nothing extra** — the
|
|
360
|
-
pipeline's `record` step and the wrap-up's `feature-transition` step. The driver still
|
|
361
|
-
`task-pipeline.yaml` verbatim (R4.1). Suppression is transparent: the
|
|
362
|
-
`FeatureSyncResult` JSON shape
|
|
363
|
-
The only observable difference is fewer redundant `feature sync`
|
|
364
|
-
`feature-sync-bounded:` annotation on stderr when a duplicate is suppressed.
|
|
359
|
+
**Batch driver contract:** the orchestrator does **nothing extra** — the suppression lives inside
|
|
360
|
+
the pipeline's `record` step and the wrap-up's `feature-transition` step. The driver still
|
|
361
|
+
launches `task-pipeline.yaml` verbatim (R4.1). Suppression is transparent: the sync emits the same
|
|
362
|
+
`FeatureSyncResult` JSON shape (`suppressed: true` added on replay), so downstream report logic is
|
|
363
|
+
unchanged. The only observable difference is fewer redundant `feature sync` derivations.
|
|
365
364
|
|
|
366
365
|
### 3.4 Metadata-only host controller (R5, task 0510)
|
|
367
366
|
|
|
@@ -492,7 +491,8 @@ batch can never destroy its own evidence. Reuse mode retains its operator-owned
|
|
|
492
491
|
persists the Step 5 report under the invoking tree; the reused tree's `.spur/run/` remains the live
|
|
493
492
|
copy while that tree lives on. The per-run provenance — the worktree DB's run/action rows and the
|
|
494
493
|
`.spur/run/<runId>.md` + `.state.json` records — is persisted mechanically by WT-4a's
|
|
495
|
-
`inline-run-setup.ts --persist-out --from <worktree
|
|
494
|
+
`inline-run-setup.ts --persist-out --from <worktree> [--task-file <merged-task>]...` call,
|
|
495
|
+
not by hand.
|
|
496
496
|
|
|
497
497
|
**Stage records are worktree-local too (0948 R9, E7 Finding 5; persisted by 0975 R1).** Each task's
|
|
498
498
|
own per-stage run record (`.spur/run/<runId>.md` + `.state.json`) and the worktree DB's run rows are
|
|
@@ -500,10 +500,38 @@ written inside the worktree and **are removed with it** in create mode — the E
|
|
|
500
500
|
this evidence. Copying them out is no longer a manual audit-time duty: WT-4a (create-mode block
|
|
501
501
|
below) runs `inline-run-setup.ts --persist-out --from "$WT_PATH"` **before** WT-4b holder cleanup,
|
|
502
502
|
which copies the run/action/phase/transition/workflow-state rows and both record files into the
|
|
503
|
-
invoking tree.
|
|
504
|
-
|
|
503
|
+
invoking tree.
|
|
504
|
+
|
|
505
|
+
**Cited evidence rides the same call (0984 R1/R2).** The driver forwards each merged task file with
|
|
506
|
+
repeatable `--task-file <path>` (paths resolved in the invoking tree after the FF merge, e.g.
|
|
507
|
+
`spur task show <wbs> --json` → `.filePath`), and persist-out then copies/verifies every literal
|
|
508
|
+
`.spur/run/<file>` that file cites — WBS verdicts, check receipts, test-gate logs, run-ID records —
|
|
509
|
+
so a merged task file never anchors a path that died with the tree. Abbreviated references
|
|
510
|
+
(`fadca099-…`, `run-*-ac87.log`, `{batch-report.md,…}`) are not literal files and carry no
|
|
511
|
+
obligation; neither do root-qualified paths (`knowledge-kit/.spur/run/…`, `/abs/.spur/run/…`),
|
|
512
|
+
which cite another project's evidence — cite foreign run artifacts that way, never bare. A citation missing in BOTH trees, a divergent cited file (never overwritten — reconcile
|
|
513
|
+
by hand), an unreadable task file, or more than 64 distinct cited files fails the pass → WT-5.
|
|
514
|
+
|
|
515
|
+
**Owned evidence rides it too (1012).** With at least one `--task-file`, persist-out also treats as
|
|
516
|
+
copy obligations the worktree's `.spur/run/` direct children named `<wbs>-…` (the WBS is each
|
|
517
|
+
forwarded task file's leading four digits before `_`) or `<runId>-…` (every run row in the worktree
|
|
518
|
+
DB, whichever task it ran) — `<wbs>-verdict.json`, check receipts, route reasons — whether or not
|
|
519
|
+
the task file cites them. They join the cited set: same copy / byte-identical no-op /
|
|
520
|
+
divergent-refuse handling. The 64-file cap bounds citations alone; owned names are bounded per
|
|
521
|
+
owner (each `<wbs>-` / `<runId>-` prefix gets its own 64-file budget, task 1034), so the bound
|
|
522
|
+
scales with the batch and one runaway owner refuses by name before any write. `<runId>.md` /
|
|
523
|
+
`<runId>.state.json` stay with the record copy (a conflict there is a reported skip). Files
|
|
524
|
+
matching neither a citation nor an ownership prefix are left behind. An absent worktree `.spur/run/`
|
|
525
|
+
means nothing is owned; any other listing failure (not a directory, permission denied) fails the
|
|
526
|
+
pass before the invoking tree is written → WT-5. Without `--task-file` nothing is enumerated.
|
|
527
|
+
|
|
528
|
+
The shapes are pinned (task 0975 R1; `record-missing` and citation behavior per 0984): idempotent on re-persist;
|
|
529
|
+
success exits 0 printing
|
|
530
|
+
`{"ok":true,"persisted":<n>,"skipped":[{"id":<run-id>,"reason":"id-exists"|"external-key-conflict"|"record-conflict:<file>"|"record-missing:<file>"|"cited-directory:<name>"|"cited-symlink:<name>"|"cited-non-file:<name>"}]}`
|
|
505
531
|
— an `id-exists` / `external-key-conflict` skip never modifies the pre-existing target rows, a
|
|
506
|
-
`record-conflict:<file>` skip never overwrites a divergent invoking-tree record
|
|
532
|
+
`record-conflict:<file>` skip never overwrites a divergent invoking-tree record, and a
|
|
533
|
+
`record-missing:<file>` skip is a known `task-lifecycle`/`feature-lifecycle` row with no record file
|
|
534
|
+
at all (its inserted DB row still counts in `persisted` — 0984 R5). Any failure
|
|
507
535
|
exits 1 printing `{"ok":false,"error":<message>}` (a worktree DB run id that is not a single safe
|
|
508
536
|
filename component is rejected before any target write). Any persist-out failure
|
|
509
537
|
routes to **WT-5** — worktree and branch retained — the same copy-out-first contract as the
|
|
@@ -528,6 +556,15 @@ The wrap receives only what it would accept:
|
|
|
528
556
|
3. When the done subset is **empty**, skip the wrap entirely with the reason (e.g. `batch wrap
|
|
529
557
|
skipped: no done tasks`) instead of invoking wrapup-pipeline on an empty set.
|
|
530
558
|
|
|
559
|
+
**Repo-wide tripwire (1037).** After the doc-sync exits converge, the pipeline's `doc-tripwire` hop
|
|
560
|
+
runs the TRUSTED CONFIG ONLY `docTripwireCmd` over the still-uncommitted wrap diff before
|
|
561
|
+
metrics-record. The default probes `package.json` for a `test-repo-wide` script and runs
|
|
562
|
+
`bun run test-repo-wide` only when it is declared (a no-op in other projects), so the batch driver
|
|
563
|
+
passes no extra vars. Batch callers override it like any wrap var (`docTripwireCmd` in `--vars`);
|
|
564
|
+
an empty string disables the check while still recording PASS. A FAIL routes the wrap to `failed`
|
|
565
|
+
with already-written learnings/docs preserved — fix the flagged working-diff violation and re-run
|
|
566
|
+
the wrap.
|
|
567
|
+
|
|
531
568
|
Filtering lives here, in the batch driver — no change to wrapup-pipeline.yaml or wrapup-steps.ts;
|
|
532
569
|
the wrap's refusal of non-done tasks remains the hard invariant.
|
|
533
570
|
|
|
@@ -566,11 +603,14 @@ non-PASS verify verdict, or a HITL pause that ends the run take the WT-5 retenti
|
|
|
566
603
|
full pipeline is eligible — `--worktree --mode implement` is rejected (WT-7), because that mode is
|
|
567
604
|
the pipeline's implement stage and already runs in the driver's tree.
|
|
568
605
|
|
|
569
|
-
**Review triage `dev-review` (run of one).** `/sp:dev-review <
|
|
606
|
+
**Review triage `dev-review` (run of one).** `/sp:dev-review [--tasks <selector> | --feature <id>[,<id>] | --scope <path>[,<path>]] --triage --worktree [<name>]`
|
|
570
607
|
runs this lifecycle around one review-plus-triage pass: WT-1…WT-6 apply unchanged, the marker's
|
|
571
|
-
`command` is `dev-review` and its `selector`
|
|
572
|
-
|
|
573
|
-
|
|
608
|
+
`command` is `dev-review` and its `selector` records the full normalized target list, and the slug
|
|
609
|
+
is `sp/review-<first>-and-<N>-<short-id>` for a multi-target run (N = target count) or
|
|
610
|
+
`sp/review-<slug>-<short-id>` for a single target (the WBS or the path's basename). It skips
|
|
611
|
+
`quickReadiness` (there is no task set; admission is "every target resolves" — each WBS/path must
|
|
612
|
+
resolve before the tree is cut). Under `--triage` the findings are bucketed across all targets once
|
|
613
|
+
(identical `file:line` findings deduped). WT-4 success reads as "every direct fix passed its check and the
|
|
574
614
|
project gate is green"; anything else takes WT-5. Contract: [dev-operations.md § 2. review](dev-operations.md#2-review).
|
|
575
615
|
|
|
576
616
|
One flag, two modes (see the glossary entry for the ownership rule). Bare `--worktree` is **create
|
|
@@ -828,12 +868,16 @@ git merge --ff-only "$BRANCH" # FF-only: never rebase, merge-commit, or
|
|
|
828
868
|
WT_PATH="$(cd "../<worktree-dir>" && pwd)" # hoisted: needed by WT-4a AND WT-4b below
|
|
829
869
|
# WT-4a provenance persist-out (task 0975 R1): copy the worktree DB's run rows plus
|
|
830
870
|
# the .spur/run/<runId>.md + .state.json records into THIS tree. Run from the main
|
|
831
|
-
# tree (cwd = the invoking tree).
|
|
832
|
-
#
|
|
833
|
-
#
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
871
|
+
# tree (cwd = the invoking tree). --task-file (0984 R2) forwards each merged task
|
|
872
|
+
# file (post-merge path) so the cited .spur/run/<file> evidence is copied/verified
|
|
873
|
+
# too. Resolve the merged path(s) BEFORE this block — an empty value exits 2:
|
|
874
|
+
# TASK_FILE="$(spur task show <wbs> --json | jq -r .filePath)" # per done task;
|
|
875
|
+
# build TASK_FILE_ARGS=(--task-file "$TASK_FILE") # one flag each
|
|
876
|
+
# Idempotent; conflicts are reported, never overwritten. A non-zero exit —
|
|
877
|
+
# including an unresolved or divergent citation, or a half-readable worktree — must
|
|
878
|
+
# NOT proceed to WT-4b removal:
|
|
879
|
+
SETUP_SCRIPT=plugins/sp/scripts/inline-run-setup.ts; [ -f config/plugin-scripts.json -a -f "$SETUP_SCRIPT" ] || SETUP_SCRIPT="$(superskill script path sp inline-run-setup.mjs 2>/dev/null)"
|
|
880
|
+
bun "$SETUP_SCRIPT" --persist-out --from "$WT_PATH" "${TASK_FILE_ARGS[@]}" \
|
|
837
881
|
|| { echo "halt: worktree run-record persist-out failed - worktree retained (WT-5)" >&2; exit 1; }
|
|
838
882
|
#
|
|
839
883
|
# WT-4b — bounded CWD-holder cleanup (task 0720 R1). $WT_PATH above is the EXACT
|
|
@@ -959,6 +1003,25 @@ Resume, merge, or discard:
|
|
|
959
1003
|
discard: git worktree remove <worktree-path> && git branch -D <branch> && spur projects remove <worktree-path>
|
|
960
1004
|
```
|
|
961
1005
|
|
|
1006
|
+
When the halt cause is `non-FF base ref`, the report replaces the one-line `merge:` hint with this
|
|
1007
|
+
ordered divergence recipe, run by the operator — the driver never merges, rebases, or resolves
|
|
1008
|
+
conflicts itself. Other halt causes (task failure, HITL pause) keep the hint as printed:
|
|
1009
|
+
|
|
1010
|
+
```
|
|
1011
|
+
# 1. integrate as a merge commit — never a rebase; task evidence cites the branch's commit SHAs
|
|
1012
|
+
git checkout <base-ref> && git merge --no-ff --no-commit <branch>
|
|
1013
|
+
# 2. resolve source conflicts by hand; generated files are then regenerated with the project's
|
|
1014
|
+
# generator, never hand-merged
|
|
1015
|
+
# (this repo: bun run build:plugin-lib && bun run --filter @gobing-ai/spur build:bundle)
|
|
1016
|
+
# 3. stage every resolved path and regenerated bundle (git add …) — an unmerged or
|
|
1017
|
+
# unstaged path makes step 5 abort
|
|
1018
|
+
# 4. run qualityGateCmd once, after ALL conflicts are resolved
|
|
1019
|
+
# 5. commit the merge with the prepared message file
|
|
1020
|
+
git commit -F <message-file>
|
|
1021
|
+
# 6. persist evidence out (WT-4a), then WT-4b/4c cleanup, and set the marker to merged
|
|
1022
|
+
inline-run-setup --persist-out --from <worktree> --task-file …
|
|
1023
|
+
```
|
|
1024
|
+
|
|
962
1025
|
The report reuses the [`--next` chain contract](flag-glossary.md#--next-chain-contract) halt-report
|
|
963
1026
|
shape (halt cause + where + why), not new vocabulary. Retention is the right default: these batches
|
|
964
1027
|
are long and already resumable via `--continue`; auto-deleting is data loss, auto-merging is a
|
|
@@ -1136,11 +1199,11 @@ per-task with `/sp:dev-run <wbs> --worktree <branch>`.
|
|
|
1136
1199
|
### Generated regions — defer the sync, regenerate once (R5)
|
|
1137
1200
|
|
|
1138
1201
|
The only per-task writer of feature files is the `record` step's post-record feature sync
|
|
1139
|
-
(`task-pipeline.yaml
|
|
1202
|
+
(`task-pipeline.yaml`). Parallel launches set
|
|
1140
1203
|
the pipeline var `deferFeatureSync: "true"` (default `"false"`): the record step appends
|
|
1141
1204
|
`feature sync deferred to batch integration` to the task report and skips the sync, so task
|
|
1142
1205
|
branches never touch feature files or `docs/features/INDEX.md`. After the last integration, on the
|
|
1143
|
-
base ref, the orchestrator runs
|
|
1206
|
+
base ref, the orchestrator runs `spur feature sync <f> --json` (service-level suppression) plus `spur feature refresh --feature <f>`
|
|
1144
1207
|
once per touched feature and commits the result as one `chore(corpus)` commit. Sequential and
|
|
1145
1208
|
inline runs keep the default `"false"` and are unchanged. Any rebase conflict — on a generated
|
|
1146
1209
|
path or any other — is an R4 `integration-conflict`; there is no path-based exception.
|