@gobing-ai/spur 0.4.3 → 0.4.4
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/config/rules/docs/verdict-confidence.yaml +68 -0
- package/config/rules/quality/coverage-gate.yaml +13 -0
- package/config/rules/recommended-pre-check.yaml +6 -2
- package/config/rules/strict/runtime-boundaries.yaml +3 -0
- package/config/rules/surface/check-cli-surface.yaml +1 -3
- package/config/templates/AGENTS.md +7 -0
- package/config/workflows/feature-verification.yaml +9 -1
- package/config/workflows/task-lifecycle.yaml +50 -0
- package/config/workflows/task-pipeline.yaml +15 -9
- package/package.json +10 -10
- package/plugins/sp/agents/super-reviewer.md +5 -2
- package/plugins/sp/commands/dev-changelog.md +1 -1
- package/plugins/sp/commands/dev-gitmsg.md +6 -2
- package/plugins/sp/commands/dev-handover.md +1 -0
- package/plugins/sp/commands/dev-job-dump.md +2 -1
- package/plugins/sp/commands/dev-refine.md +14 -2
- package/plugins/sp/commands/dev-refineall.md +7 -1
- package/plugins/sp/commands/dev-review.md +1 -0
- package/plugins/sp/lib/history-anatomy.generated.mjs +18 -18
- package/plugins/sp/lib/idea-handoff.generated.mjs +91 -91
- package/plugins/sp/lib/inline-run.generated.mjs +233 -277
- package/plugins/sp/lib/plan-projection.generated.mjs +62 -38
- package/plugins/sp/lib/quality-gate.generated.d.mts +1 -0
- package/plugins/sp/lib/quality-gate.generated.mjs +13793 -13966
- package/plugins/sp/lib/residual-scan.generated.d.mts +13 -0
- package/plugins/sp/lib/residual-scan.generated.mjs +51 -21
- package/plugins/sp/lib/step-profile.generated.mjs +8 -8
- package/plugins/sp/plugin.json +1 -1
- package/plugins/sp/scripts/batch-plan.mjs +62 -40
- package/plugins/sp/scripts/batch-preflight.mjs +34 -12
- package/plugins/sp/scripts/commit-guard.mjs +6 -6
- package/plugins/sp/scripts/daily-summary/daily-summary.mjs +26 -28
- package/plugins/sp/scripts/dogfood-testing/detect-pipeline-driving.mjs +11 -11
- package/plugins/sp/scripts/dogfood-testing/validate-report.mjs +4 -4
- package/plugins/sp/scripts/feature-verification-steps.mjs +15 -4
- package/plugins/sp/scripts/feature-verification-steps.ts +29 -1
- package/plugins/sp/scripts/history-anatomy-cache.mjs +19 -19
- package/plugins/sp/scripts/idea-handoff.mjs +2 -2
- package/plugins/sp/scripts/inline-run-dispatch.mjs +2 -2
- package/plugins/sp/scripts/inline-run-setup.mjs +20 -20
- package/plugins/sp/scripts/persist-out-check.mjs +5 -5
- package/plugins/sp/scripts/pr-reviewing.mjs +13 -13
- package/plugins/sp/scripts/quality-gate.mjs +13715 -13884
- package/plugins/sp/scripts/residual-scan.mjs +58 -27
- package/plugins/sp/scripts/residual-scan.ts +8 -8
- package/plugins/sp/scripts/run-summary.mjs +15 -15
- package/plugins/sp/scripts/script-root.mjs +6 -6
- package/plugins/sp/scripts/session-timeline.mjs +16 -16
- package/plugins/sp/scripts/task-diffstat.mjs +8 -8
- package/plugins/sp/scripts/workflow-step-profile.mjs +12 -12
- package/plugins/sp/scripts/wrapup-drift-probe.mjs +9 -9
- package/plugins/sp/scripts/wrapup-steps.mjs +25 -25
- package/plugins/sp/skills/next-router/SKILL.md +3 -1
- package/plugins/sp/skills/next-router/references/routing-table.md +9 -3
- package/plugins/sp/skills/spur-cli/references/tasks.md +24 -4
- package/plugins/sp/skills/spur-dev/references/cross-cutting.md +8 -1
- package/plugins/sp/skills/spur-dev/references/dev-operations.md +37 -11
- package/plugins/sp/skills/spur-dev/references/execution-batch.md +6 -3
- package/plugins/sp/skills/spur-dev/references/flag-glossary.md +4 -2
- package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +22 -2
- package/schemas/section-matrix.schema.json +3 -2
- package/spur.js +24403 -32459
- package/web/_astro/{BoardApp.5IIl2O-z.js → BoardApp.Niubpe6z.js} +1 -1
- package/web/_astro/{BoardApp.Drnx-KeM.js → BoardApp.hF0RAIrg.js} +112 -112
- package/web/_astro/TaskDetail.DJpapt38.js +1 -0
- package/web/_astro/{arc.j2EVkYVd.js → arc.BgKcK0i8.js} +1 -1
- package/web/_astro/{architectureDiagram-3BPJPVTR.DZWSFqEG.js → architectureDiagram-3BPJPVTR.ChP-Ig0V.js} +1 -1
- package/web/_astro/{blockDiagram-GPEHLZMM.DE6GpXCN.js → blockDiagram-GPEHLZMM.BVaCBoeN.js} +1 -1
- package/web/_astro/{c4Diagram-AAUBKEIU.DoVR1G6B.js → c4Diagram-AAUBKEIU.CHSDpEO5.js} +1 -1
- package/web/_astro/channel.DkpvN2tD.js +1 -0
- package/web/_astro/{chunk-2J33WTMH.Do6-Gbyf.js → chunk-2J33WTMH.MYRcYVRa.js} +1 -1
- package/web/_astro/{chunk-4BX2VUAB.BYV1HGHx.js → chunk-4BX2VUAB.S5j22Zqa.js} +1 -1
- package/web/_astro/{chunk-55IACEB6.CvI1zkrc.js → chunk-55IACEB6.gciRPvmZ.js} +1 -1
- package/web/_astro/{chunk-727SXJPM.DNGSCRlX.js → chunk-727SXJPM.CdqrSQkX.js} +1 -1
- package/web/_astro/{chunk-AQP2D5EJ.DXhhgT5z.js → chunk-AQP2D5EJ.CyokdHT3.js} +1 -1
- package/web/_astro/{chunk-FMBD7UC4.dzkRKP2u.js → chunk-FMBD7UC4.Bg9KJhjW.js} +1 -1
- package/web/_astro/{chunk-ND2GUHAM.DujGLeEf.js → chunk-ND2GUHAM.1gxxI-vD.js} +1 -1
- package/web/_astro/{chunk-QZHKN3VN.BWtIT3ZU.js → chunk-QZHKN3VN.DDEYtCKU.js} +1 -1
- package/web/_astro/{classDiagram-4FO5ZUOK.DyApg0Nn.js → classDiagram-4FO5ZUOK.Ch3zi37T.js} +1 -1
- package/web/_astro/{classDiagram-v2-Q7XG4LA2.DyApg0Nn.js → classDiagram-v2-Q7XG4LA2.Ch3zi37T.js} +1 -1
- package/web/_astro/{cose-bilkent-S5V4N54A.DJQB-u_l.js → cose-bilkent-S5V4N54A.D2q5AINI.js} +1 -1
- package/web/_astro/{cynefin-OW5HDTMX.bi3D_siV.js → cynefin-OW5HDTMX.BA9kC2YT.js} +1 -1
- package/web/_astro/{dagre-BM42HDAG.C-f7TrRg.js → dagre-BM42HDAG.CHO08nRp.js} +1 -1
- package/web/_astro/{diagram-2AECGRRQ.DrPfjHQB.js → diagram-2AECGRRQ.BfFQt0LW.js} +1 -1
- package/web/_astro/{diagram-5GNKFQAL.C9S4WUHO.js → diagram-5GNKFQAL.CHMwMTe4.js} +1 -1
- package/web/_astro/{diagram-KO2AKTUF.Dzzye8QH.js → diagram-KO2AKTUF.BJ-7gK-w.js} +1 -1
- package/web/_astro/{diagram-LMA3HP47.DX-LRiof.js → diagram-LMA3HP47.C5xqcc0t.js} +1 -1
- package/web/_astro/{diagram-OG6HWLK6.Z-kAKwIz.js → diagram-OG6HWLK6.C2pQjfrC.js} +1 -1
- package/web/_astro/{erDiagram-TEJ5UH35.D6dyClSv.js → erDiagram-TEJ5UH35._FoNyxgC.js} +1 -1
- package/web/_astro/{flowDiagram-I6XJVG4X.Cx3q2cxD.js → flowDiagram-I6XJVG4X.B_ENkT2I.js} +1 -1
- package/web/_astro/{ganttDiagram-6RSMTGT7.DU3gH6CT.js → ganttDiagram-6RSMTGT7.B3q8h77C.js} +1 -1
- package/web/_astro/{gitGraphDiagram-PVQCEYII.ISmCnJ87.js → gitGraphDiagram-PVQCEYII.QWZFDboZ.js} +1 -1
- package/web/_astro/index.BFyW13JJ.css +1 -0
- package/web/_astro/{infoDiagram-5YYISTIA.DR6_iNOK.js → infoDiagram-5YYISTIA.Cs6eEc92.js} +1 -1
- package/web/_astro/{ishikawaDiagram-YF4QCWOH.D7wY-ZGA.js → ishikawaDiagram-YF4QCWOH.BU9DJMHA.js} +1 -1
- package/web/_astro/{journeyDiagram-JHISSGLW.DkP9-WK8.js → journeyDiagram-JHISSGLW.D35k6Jpe.js} +1 -1
- package/web/_astro/{kanban-definition-UN3LZRKU.wtgY98M2.js → kanban-definition-UN3LZRKU.DBqcAT4m.js} +1 -1
- package/web/_astro/{linear.CI6djNi7.js → linear.D-LSNK8W.js} +1 -1
- package/web/_astro/{mermaid.core.CuQPxS8b.js → mermaid.core.CSruWVOa.js} +4 -4
- package/web/_astro/{mindmap-definition-RKZ34NQL.5HNIEG7R.js → mindmap-definition-RKZ34NQL.BiFaUsfj.js} +1 -1
- package/web/_astro/{pieDiagram-4H26LBE5.CchhDFjE.js → pieDiagram-4H26LBE5.D1KTKqb9.js} +1 -1
- package/web/_astro/{quadrantDiagram-W4KKPZXB.PYXXJPSJ.js → quadrantDiagram-W4KKPZXB.DBHflsMG.js} +1 -1
- package/web/_astro/{requirementDiagram-4Y6WPE33.cUQuNAKU.js → requirementDiagram-4Y6WPE33.hwX9CNdk.js} +1 -1
- package/web/_astro/{sankeyDiagram-5OEKKPKP.BO7MnRIA.js → sankeyDiagram-5OEKKPKP.DkI8mJiE.js} +1 -1
- package/web/_astro/{sequenceDiagram-3UESZ5HK.D9bElyD6.js → sequenceDiagram-3UESZ5HK.DMz7jBDx.js} +1 -1
- package/web/_astro/{stateDiagram-AJRCARHV.DhGdRz7I.js → stateDiagram-AJRCARHV.B6Ef2xJ1.js} +1 -1
- package/web/_astro/{stateDiagram-v2-BHNVJYJU.5GvLeAoL.js → stateDiagram-v2-BHNVJYJU.CgoaufB9.js} +1 -1
- package/web/_astro/{timeline-definition-PNZ67QCA.LtAT9haM.js → timeline-definition-PNZ67QCA.B3c8h1t-.js} +1 -1
- package/web/_astro/{vennDiagram-CIIHVFJN.DRth1yLA.js → vennDiagram-CIIHVFJN.BdHPAxAb.js} +1 -1
- package/web/_astro/{wardleyDiagram-YWT4CUSO.h9MlZfcr.js → wardleyDiagram-YWT4CUSO.BrJXPPAj.js} +1 -1
- package/web/_astro/{xychartDiagram-2RQKCTM6.DHqy9DYA.js → xychartDiagram-2RQKCTM6.CMH5yFsV.js} +1 -1
- package/web/index.html +2 -2
- package/web/spur_logo.svg +1 -1
- package/web/_astro/TaskDetail.Ci4LNn9S.js +0 -1
- package/web/_astro/channel.DmdDxGsq.js +0 -1
- package/web/_astro/index.Do2lLdgo.css +0 -1
|
@@ -79,7 +79,7 @@ each would be scope creep for one-liner procedures.
|
|
|
79
79
|
| 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]` |
|
|
80
80
|
| 7 | docs | _(no thin wrapper)_ | `Skill()` | `sp:doc-evolve` | `"<change description>"` |
|
|
81
81
|
| 8 | changelog | `dev-changelog` | `inline` | git log + conventional-commit grouping | `[<file>] [--since <ref>] [--until <ref>] [--version <ver>]` |
|
|
82
|
-
| 9 | gitmsg | `dev-gitmsg` | `inline` | bounded diff capture → concern grouping → conventional commit | `[--commit] [--squash] [--all] [--scope <path>]`
|
|
82
|
+
| 9 | gitmsg | `dev-gitmsg` | `inline` | bounded diff capture → concern grouping → conventional commit | `[--commit] [--squash] [--all] [--scope <path>] [--check <cmd>]` |
|
|
83
83
|
| 10 | fixall | `dev-fixall` | `inline` | lint + test fix loop | `[<validation-command>] [--max-retry <n>] [--scope <path>] [--gate-log <path>] [--findings <anchors>]` |
|
|
84
84
|
| 11 | handover | `dev-handover` | `inline` | structured doc generation | `"<blocker description>"` |
|
|
85
85
|
| 11a | job-dump | `dev-job-dump` | `Skill()` | `sp:spur-dev` (`job-dump`) | `--file <path>` |
|
|
@@ -250,7 +250,8 @@ check receipt (`receipt.runId === runId`), otherwise `n/a (<reason>)`. Any value
|
|
|
250
250
|
checklist** against target sections (read codebases, ADRs, dependent WBS, dogfood evidence as
|
|
251
251
|
needed). If any item fails, synthesize and rewrite via CLI-gated section updates until all pass
|
|
252
252
|
(or surface a blocked Q&A with a concrete question). Outcome vocabulary: `refined` (wrote) |
|
|
253
|
-
`ready` (checklist already met, no write — optional alias of refined with zero writes) |
|
|
253
|
+
`ready` (checklist already met, no write — optional alias of refined with zero writes) |
|
|
254
|
+
`cancelled` (issue triage found no valid issue — see `premises`) | `failed`.
|
|
254
255
|
Prefer reporting `refined` when any section changed; if checklist already fully met, emit:
|
|
255
256
|
|
|
256
257
|
```
|
|
@@ -295,6 +296,17 @@ check receipt (`receipt.runId === runId`), otherwise `n/a (<reason>)`. Any value
|
|
|
295
296
|
list`, `spur task list --status wip --json`) are recorded in References/Design.
|
|
296
297
|
- **Scope** — the work is not already done, and not owned by another task.
|
|
297
298
|
|
|
299
|
+
**Issue triage.** When the task bundles several issues (findings, defects, R-items with their
|
|
300
|
+
proposed fixes), judge each one separately as `valid` (reproduced or confirmed in the current
|
|
301
|
+
tree), `already-fixed`, `owned-elsewhere` (name the WBS) or `invalid` (premise false). An issue
|
|
302
|
+
that is not `valid` is removed **with everything that exists only for it**: its Background
|
|
303
|
+
paragraph, R-items, Design/Solution notes, Plan steps and ACs. Renumber nothing that other
|
|
304
|
+
tasks or feature scenarios cite; leave a gap instead. Each removal is one correction-record
|
|
305
|
+
line. When **no** issue stays valid, do not rewrite the task. Record the triage in the
|
|
306
|
+
correction block, then `spur task update <wbs> cancelled --json`, and report outcome
|
|
307
|
+
`cancelled`. Cancelling is not demotion; it is valid only within the backlog/todo status scope
|
|
308
|
+
above.
|
|
309
|
+
|
|
298
310
|
Contradictions are corrected in **this** refine (rewrite the claim, or re-point the design at
|
|
299
311
|
ground truth), never deferred to the implementer. `--depth ready` exists so a downstream agent
|
|
300
312
|
does not re-derive the analysis; a frozen design built on a false premise is the worst
|
|
@@ -309,7 +321,10 @@ check receipt (`receipt.runId === runId`), otherwise `n/a (<reason>)`. Any value
|
|
|
309
321
|
1. Run `spur task check <wbs> --as todo --json`. Any error means the task is not ready. Fix it,
|
|
310
322
|
or report `failed`.
|
|
311
323
|
2. Fill metadata that is still unset: `spur task update <wbs> --priority <P0–P3>` and
|
|
312
|
-
`--estimate-hours <n>` (both `--json`). Never overwrite a value the operator set.
|
|
324
|
+
`--estimate-hours <n>` (both `--json`). Never overwrite a value the operator set. The one
|
|
325
|
+
exception is a triage that dropped issues: re-estimate the remaining scope and record
|
|
326
|
+
old → new in the correction block. The CLI cannot rename a task. When a drop leaves the title
|
|
327
|
+
naming removed scope, record that in the correction block as well.
|
|
313
328
|
3. Promote `backlog → todo` idempotently with `spur task update <wbs> todo --json`, the same FSM
|
|
314
329
|
transition `--next` uses. Create-time ready preparation skips its own promotion when the task
|
|
315
330
|
is already `todo`, and next-router stops routing the task back to refine. Without `--next`,
|
|
@@ -341,9 +356,10 @@ check receipt (`receipt.runId === runId`), otherwise `n/a (<reason>)`. Any value
|
|
|
341
356
|
3. Topo-sort by `dependencies[]` (Kahn, WBS-ascending tie-break). Cycle → abort entire batch before any refine. Out-of-set deps: `done` → allow; else → block subtree (same as runall).
|
|
342
357
|
4. For each WBS in order: invoke single-task refine with shared flags **including `--depth`**. Under `--auto` + **`--depth standard`** (default), the per-task **L3 pre-synthesis SKIP gate** still applies. Under **`--depth ready`**, each task runs the implement-ready checklist (no L3-only SKIP). That includes the premises audit, the correction record and ready finalization, so a passing task leaves at `todo`.
|
|
343
358
|
5. Failure policy: **stop-the-batch** (default) or `--keep-going` (skip in-batch dependents of a failed refine; continue independents).
|
|
344
|
-
6. Emit a batch report (markdown or `--json`) that records `depth` once at the header. Under `--depth ready`, each row also carries the corrections count, status before → after, and failed checklist ids.
|
|
345
|
-
|
|
346
|
-
- **
|
|
359
|
+
6. Emit a batch report (markdown or `--json`) that records `depth` once at the header. Under `--depth ready`, each row also carries the corrections count, dropped issues, status before → after, and failed checklist ids.
|
|
360
|
+
7. **Cross-task proposals (`--depth ready` only).** After the per-task pass, list two kinds of proposals in the report: tasks whose remaining issues overlap another set member (same root cause or file set → name the merge target; tasks that only share a step, such as one upstream release, or that fix two layers of one failure → propose ordering or a shared step, not a merge), and tasks with no `feature_id` (name the candidate owning feature with evidence). These are proposals only. Refineall merges, cancels or links a task only when the operator's `--description` names that task and the action (e.g. `cancel 0273 and merge its issues into 0269; link 0260 to G11`). That explicit directive is the confirmation the [feature-link helper](feature-link-helper.md) requires. A merge moves the surviving issues with their fixes into the target through CLI section updates, records the merge in both tasks' correction blocks, then cancels the source. Run directives before the per-task pass, so each target is refined with its merged content.
|
|
361
|
+
- **Per-task outcome vocabulary:** `refined` (synthesis wrote sections) | `SKIP` (already meets the active depth bar under `--auto`) | `cancelled` (no valid issue left, or merged away by directive) | `failed` | `skipped` (dep failed under `--keep-going`) | `not-attempted` (halted) | `blocked` (unmet out-of-set dep).
|
|
362
|
+
- **Batch verdict:** `clean` (all attempted tasks `refined`, `SKIP` or `cancelled`) | `halted` (a failure stopped the batch) | `aborted` (cycle / unknown selector / empty set after filter).
|
|
347
363
|
- **`--next` is not accepted** (dropped by feature H8, 2026-07-31 — see `plugins/sp/commands/dev-refineall.md` for the removal record). Chain execution explicitly: refineall, then `/sp:dev-runall --feature <id>`.
|
|
348
364
|
- **`--auto` recommendation:** Batch refine without `--auto` requires per-task interactive Q&A and does not scale. Default operator path: `/sp:dev-refineall --feature <id> --auto`. For implement handoffs, or to re-audit a feature's filed tasks: `/sp:dev-refineall --feature <id> --auto --depth ready`.
|
|
349
365
|
- **Delegation:** `Skill(skill="sp:spur-dev", args="refineall $ARGUMENTS")` → per task `Skill(skill="sp:spur-dev", args="refine <wbs> $SHARED_FLAGS")` (shared flags include `--depth` when set).
|
|
@@ -375,7 +391,7 @@ check receipt (`receipt.runId === runId`), otherwise `n/a (<reason>)`. Any value
|
|
|
375
391
|
- **Behavior:**
|
|
376
392
|
1. Parse arguments, preserving quoted paths with spaces. Reject a missing/empty path, repeated `--file`, unknown flags, or extra positional arguments with usage. Resolve the absolute path before changing directories. Reject a directory target; create missing parent directories. Respect CLI-gated corpus writes: task/feature documents cannot be dump targets.
|
|
377
393
|
2. Gather the mission, original invocation/options, approved outcome, completed and partial work, blockers, and next actions. Verify repository/worktree paths, branch, HEAD/base, dirty files and relevant commits with Git. Inspect referenced tasks/features/runs through the CLI facade with `--json` in their execution directory. Preserve frozen batch membership, dependency order, run IDs, workflow/checkpoint identity, failure policy, executor state and worktree marker when applicable. Record inspection time and provenance; label unavailable facts `unknown`.
|
|
378
|
-
3. Fill every template section for this job; use `N/A` where inapplicable. Include uncommitted work and ownership, gate commands/results, pending questions, approvals given or still required, discovery maps, evidence paths, and wrap/merge/cleanup success conditions. Keep confirmed lessons and rejected approaches with anchors. Link authoritative specifications instead of copying them; never turn task-specific bypasses into general instructions.
|
|
394
|
+
3. Fill every template section for this job; use `N/A` where inapplicable. Include uncommitted work and ownership, gate commands/results already on record (never run a gate to fill this — write `not run`), pending questions, approvals given or still required, discovery maps, evidence paths, and wrap/merge/cleanup success conditions. Keep confirmed lessons and rejected approaches with anchors. Link authoritative specifications instead of copying them; never turn task-specific bypasses into general instructions.
|
|
379
395
|
4. Redact credentials, tokens and sensitive personal data. Link large logs/artifacts by path and note their durability and availability to the recipient; the Markdown file does not transfer referenced files. Include essential continuation context directly so missing optional scratch notes do not erase the plan.
|
|
380
396
|
5. Construct the complete snapshot before writing or refreshing `--file`. Read it back to verify the mission, execution directory, ordered remaining work and first actions. Report the absolute path and unresolved facts. Dumping only saves context: it does not stop an active executor, execute remaining work, change lifecycle state, commit, merge, or remove a worktree; record any executor still running.
|
|
381
397
|
|
|
@@ -552,6 +568,14 @@ gate commands, pending questions and approval requirements.>
|
|
|
552
568
|
These define their procedure directly in the command file. No `Skill()` delegation — the command
|
|
553
569
|
is the procedure. The backing is a combination of git CLI, `spur` CLI, and agent reasoning.
|
|
554
570
|
|
|
571
|
+
**Gate ownership.** A project quality gate (`bun run gate`, `spur-check`, lint, typecheck, tests,
|
|
572
|
+
rule runs) runs only where an operation's own contract names it: the pipeline `test` hop
|
|
573
|
+
(`run`/`runall`), `fixall`, `gtd`, `fixgha`, `unit`, and the `--check <cmd>` loops. The scribe
|
|
574
|
+
operations — `changelog`, `gitmsg`, `handover`, `job-dump` — produce text or a commit, not code, so
|
|
575
|
+
they run **no gate by default**, and a generic "verify before you finish" rule from `AGENTS.md` or
|
|
576
|
+
host instructions does not add one. An opt-in gate is explicit: `gitmsg --check <cmd>`, or
|
|
577
|
+
`/sp:dev-gtd [--no-push]` for gate → auto-fix → commit. Commit hooks still run as configured.
|
|
578
|
+
|
|
555
579
|
### 8. changelog
|
|
556
580
|
|
|
557
581
|
- **Purpose:** Generate a structured changelog from git commits between two refs.
|
|
@@ -568,12 +592,12 @@ is the procedure. The backing is a combination of git CLI, `spur` CLI, and agent
|
|
|
568
592
|
6. Emit: with `<file>`, insert the section into that file above its newest `## [` release heading (or after its title when none exists) and touch nothing else in the file; without `<file>`, print it to stdout.
|
|
569
593
|
7. Self-check before emitting: every short hash in `<since>..<until>` appears exactly once. Fix any miss or duplicate; do not report a verdict.
|
|
570
594
|
8. Reply in at most three lines: the range, bullet counts per category, and the output target.
|
|
571
|
-
- **Invariants:** Output is derived from `git log` only. No quality gates — no lint/test/`spur-check`/rule runs, citation or manifest lookups, confidence ratings, or edits beyond the one inserted section. The file is left uncommitted.
|
|
595
|
+
- **Invariants:** Output is derived from `git log` only. No quality gates — no `bun run gate`/lint/typecheck/test/`spur-check`/rule runs, citation or manifest lookups, confidence ratings, or edits beyond the one inserted section. The file is left uncommitted.
|
|
572
596
|
|
|
573
597
|
### 9. gitmsg
|
|
574
598
|
|
|
575
599
|
- **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.
|
|
576
|
-
- **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`.
|
|
600
|
+
- **Inputs:** `--scope <path>` (default: the whole change set) — path filter; an explicit `--scope` always wins over change-set auto-discovery. `--check <cmd>` (default: off) — run `<cmd>` once as a pre-commit gate (step 5a). `--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`.
|
|
577
601
|
- **Backing:** `inline` — one bounded gather call + concern grouping + conventional commit formatting.
|
|
578
602
|
- **Behavior:**
|
|
579
603
|
|
|
@@ -631,6 +655,8 @@ is the procedure. The backing is a combination of git CLI, `spur` CLI, and agent
|
|
|
631
655
|
|
|
632
656
|
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.
|
|
633
657
|
|
|
658
|
+
5a. **Gate (`--check <cmd>` only) — one more Bash call.** Without `--check`, run no gate of any kind. With it, run `<cmd>` exactly once, verbatim, after the report: exit 0 → one `check PASS` line and continue; non-zero → print its last 30 lines and commit nothing. Never fix, retry, or widen the command — gate → fix → commit is `/sp:dev-gtd`.
|
|
659
|
+
|
|
634
660
|
6. **Commit (`--commit` / `--squash`) — one more Bash call.** `--squash` implies `--commit`, so both together is just `--squash`. Refuse before touching the index when:
|
|
635
661
|
- `## secret hits` is non-empty → print each `file: line`, commit nothing;
|
|
636
662
|
- `--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).
|
|
@@ -649,7 +675,7 @@ is the procedure. The backing is a combination of git CLI, `spur` CLI, and agent
|
|
|
649
675
|
|
|
650
676
|
Hooks stay enabled; a failing hook stops the run with its output — never `--no-verify`.
|
|
651
677
|
|
|
652
|
-
- **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.
|
|
678
|
+
- **Invariants:** Git and POSIX shell only — no helper script, no temp file. At most two Bash calls: gather, then (only when committing) commit — three with `--check`. No quality gate (`bun run gate`, lint, typecheck, tests, `spur-check`) unless `--check` names one. 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.
|
|
653
679
|
|
|
654
680
|
### 10. fixall
|
|
655
681
|
|
|
@@ -796,4 +822,4 @@ is the procedure. The backing is a combination of git CLI, `spur` CLI, and agent
|
|
|
796
822
|
`## Testing`, `## Review`), verdict files (`.spur/run/<wbs>-verdict.json`), diffs, and docs — by
|
|
797
823
|
**path**, not by pasting their content into the handover body. The handover is a pointer document;
|
|
798
824
|
restating content it can instead link to makes it stale the moment the source changes.
|
|
799
|
-
- **Invariants:** The handover is honest — rejected approaches are recorded so the next agent doesn't retry them. The blocker is specific, not "it doesn't work."
|
|
825
|
+
- **Invariants:** The handover is honest — rejected approaches are recorded so the next agent doesn't retry them. The blocker is specific, not "it doesn't work." No quality gate runs — cite gate results already on record.
|
|
@@ -152,8 +152,8 @@ kickoff** — the driver never re-queries `spur task list` to recompute membersh
|
|
|
152
152
|
| --- | --- | --- |
|
|
153
153
|
| Explicit WBS list | `^[0-9, ]+$` | Split on comma; validate each token is a 4-digit WBS; collect the explicit set. (R1.1) |
|
|
154
154
|
| `feature:<id>` (via `--tasks` or `--feature <id>`) | literal `feature:` prefix or `--feature` flag | `spur task list --feature <id> --json`; collect `wbs` from each row. The `--feature` flag is sugar that becomes `--tasks feature:<id>` at the command layer. (R1.3) |
|
|
155
|
-
| `ready` | literal `ready` | Resolve the union of `spur task list --status todo --json` + `spur task list --status backlog --json`, drop tasks with open children (R1.5, umbrella-parent exclusion below), then keep only tasks whose every `dependencies[]` entry resolves to `status == done` (via `spur task show <dep> --json | jq '{wbs, status, dependencies, feature_id}'` — R5 metadata-only). Report each excluded task with its unmet dependency. (R1.4) |
|
|
156
|
-
| Status pseudo-list | `todo` \| `backlog` \| `wip` \| `blocked` \| `testing` | `spur task list --status <value> --json`; collect `wbs` from each row. (R1.2) |
|
|
155
|
+
| `ready` | literal `ready` | Resolve the union of `spur task list --status todo --json` + `spur task list --status backlog --json`, drop tasks with open children (R1.5, umbrella-parent exclusion below), then keep only tasks whose every `dependencies[]` entry resolves to `status == done` (via `spur task show <dep> --json | jq '{wbs, status, dependencies, feature_id}'` — R5 metadata-only). Report each excluded task with its unmet dependency. A `deprecated` dependency is *not* satisfied (ADR-137: a frozen task never reads as `done`), so it keeps its dependents out of the ready set. (R1.4) |
|
|
156
|
+
| Status pseudo-list | `todo` \| `backlog` \| `wip` \| `blocked` \| `testing` | `spur task list --status <value> --json`; collect `wbs` from each row. (R1.2) `deprecated` is deliberately not a selector value: a frozen task has no pipeline hop to drive, so a batch is never built from that status (ADR-137; `/sp:dev-next` row A10 stops the same way). |
|
|
157
157
|
| *(else)* | no match | Error: "unknown selector `<value>`" — list the valid forms and halt before running anything. |
|
|
158
158
|
|
|
159
159
|
**Dedup:** an explicit list with a repeated WBS (`--tasks 0040,0040`) collapses to a single entry;
|
|
@@ -200,7 +200,9 @@ For each dependency edge to a task **outside** the frozen set, resolve its curre
|
|
|
200
200
|
- status ≠ `done` → mark the dependent **blocked**. Transitively mark its in-set descendants blocked
|
|
201
201
|
too (fixpoint propagation: any task depending on a blocked task is itself blocked). Exclude all
|
|
202
202
|
blocked tasks from execution and record the unmet dependency + the blocked subtree for the report
|
|
203
|
-
(R2.4). Independent (non-blocked) tasks in the set still run.
|
|
203
|
+
(R2.4). Independent (non-blocked) tasks in the set still run. **`deprecated` is not satisfied**
|
|
204
|
+
(ADR-137): a frozen task never reads as `done`, so the dependent blocks and the report names the
|
|
205
|
+
remedy — re-point the edge, or un-deprecate (`spur task update <dep> todo`).
|
|
204
206
|
|
|
205
207
|
### 2.4 Topological sort
|
|
206
208
|
|
|
@@ -277,6 +279,7 @@ node "$(superskill script path sp batch-preflight.mjs)" \
|
|
|
277
279
|
| `action: skip` code **A2** | Do not launch; report `preflight-skip` + unmet deps (mirrors TABLE A2) |
|
|
278
280
|
| `action: skip` code **A7** | Do not launch; report blocked (handover is operator-side) |
|
|
279
281
|
| `action: skip` code **A8**/**A9** | Do not launch; already done / cancelled |
|
|
282
|
+
| `action: skip` code **DEPRECATED** | Do not launch; frozen and retained (ADR-137) — the reason line names the un-deprecate command. A deprecated WBS can reach preflight through an explicit `--tasks` list or a `feature:<id>` selector (`spur task list --feature` reports every linked row, whatever its status); the `ready` and status pseudo-lists exclude it |
|
|
280
283
|
|
|
281
284
|
**Invariants:** Preflight never replaces the pipeline with a loop of `/sp:dev-next`. TABLES A/B/C
|
|
282
285
|
remain SSOT in `next-router/references/routing-table.md`. Step 2.3 already pre-blocks many unmet
|
|
@@ -225,8 +225,10 @@ the `feature:<id>` sets, resolved once and frozen.
|
|
|
225
225
|
|
|
226
226
|
**Anchor:** `#flag-check`.
|
|
227
227
|
|
|
228
|
-
Verification command a command iterates against (`dev-simplify`, `dev-refactor`). The command
|
|
228
|
+
Verification command a command iterates against (`dev-simplify`, `dev-refactor`, `dev-gitmsg`). The command
|
|
229
229
|
establishes a baseline with it before the first change and re-runs it after each change.
|
|
230
|
+
`dev-gitmsg` uses it as a one-shot opt-in pre-commit gate: run once, non-zero commits nothing, no
|
|
231
|
+
fix loop. A command without `--check` in its contract runs no gate.
|
|
230
232
|
|
|
231
233
|
### `--focus <dims>` — constrain the operation to specific dimensions
|
|
232
234
|
|
|
@@ -462,7 +464,7 @@ Orthogonal to `--focus` (which _narrows_ domains) and to `--mode` on other comma
|
|
|
462
464
|
| Value (refine family) | Bar | `--auto` SKIP behavior |
|
|
463
465
|
| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
|
|
464
466
|
| `standard` (default when omitted) | L3 structural completeness (not empty/placeholder; check-clean for target sections) | **SKIP** when no L3 findings on target sections |
|
|
465
|
-
| `ready` | **Implement-ready** freeze: another agent can implement without inventing design (frozen names/APIs or explicit "no new API", anti-patterns, file targets, handoffs, out-of-scope) | **Do not SKIP** on L3-clean alone — audit existing claims, run the ready checklist, rewrite sections until the bar is met, then promote `backlog → todo` |
|
|
467
|
+
| `ready` | **Implement-ready** freeze: another agent can implement without inventing design (frozen names/APIs or explicit "no new API", anti-patterns, file targets, handoffs, out-of-scope) | **Do not SKIP** on L3-clean alone — audit existing claims, drop invalid issues with their fixes (cancel when none stays valid), run the ready checklist, rewrite sections until the bar is met, then promote `backlog → todo` |
|
|
466
468
|
|
|
467
469
|
Default for refine stays `standard` so ordinary `refineall --auto` remains cheap. Use `ready` for
|
|
468
470
|
multi-package / multi-agent handoffs, flaky-pipeline features where a wrong implement is costly, and
|
|
@@ -922,8 +922,10 @@ verdict artifact exists (tasks 0617, 0619 — the clobbering spiral).
|
|
|
922
922
|
|
|
923
923
|
## Running the full gate (task 0872 / 1127 R7)
|
|
924
924
|
|
|
925
|
-
The full gate legitimately runs
|
|
926
|
-
|
|
925
|
+
The full gate legitimately runs minutes, not seconds — measured 1.8-3.1 min for `bun run spur-check`
|
|
926
|
+
on an idle 10-core host (2026-10-13), and far longer when other agents' suites run concurrently.
|
|
927
|
+
Five rules keep it from becoming a hazard (the first two
|
|
928
|
+
were both violated once on 2026-10-10, aborting the run's own verification):
|
|
927
929
|
|
|
928
930
|
- **Never wrap it in an external `timeout`, and never treat its runtime as a hang.** An outer bound
|
|
929
931
|
that fires mid-suite leaves a half-finished suite behind while the caller believes it is gone.
|
|
@@ -936,6 +938,24 @@ violated once on 2026-10-10, aborting the run's own verification):
|
|
|
936
938
|
- **Preserve a signal-induced receipt.** A cap-killed attempt leaves a red receipt that the next
|
|
937
939
|
recheck's `no-progress` guard honours, so it reads as a genuine failure unless the receipt is kept
|
|
938
940
|
under a distinct name and the run log says so.
|
|
941
|
+
- **Clear the killed attempt's process tree before re-running.** A cap-signalled gate leaves its
|
|
942
|
+
`bun test --test-worker` children alive: the parent dies, the workers keep burning ~100% CPU, and
|
|
943
|
+
each retry is slower than the last until the cap kills that one too and mints another leak.
|
|
944
|
+
Observed 2026-10-13: five leaked workers (ages 23 min, 37 min, 50 min, 2 h 17 m, 4 h 18 m) drove
|
|
945
|
+
consecutive attempts from the measured 1.8-3.1 min up to 13-40 min, and the real defect of the
|
|
946
|
+
session only became visible once they were cleared. Find them by age and cwd, then clear the tree
|
|
947
|
+
before the next run; leave a tree alone whose cwd is another session's live run:
|
|
948
|
+
|
|
949
|
+
```bash
|
|
950
|
+
ps -Ao pid=,ppid=,etime=,%cpu=,command= | grep -E "run-tests\.ts|bun test --test-worker" | grep -v grep
|
|
951
|
+
kill -TERM <pid> <ppid>; sleep 4; kill -KILL <pid> <ppid> # escalate only if TERM is ignored
|
|
952
|
+
```
|
|
953
|
+
|
|
954
|
+
- **One gate per tree.** Nothing serializes gate runs since task 1173 deleted the lock, so confirm
|
|
955
|
+
no live gate is already running in your tree before starting one: two suites in one tree contend
|
|
956
|
+
for CPU and for the shared fixtures, and the second one's result is uninterpretable. Measured
|
|
957
|
+
2026-10-13: a duplicate gate launched into a tree already running another session's
|
|
958
|
+
`bun run spur-check` burned 40 min at the host cap and left an orphaned worker behind.
|
|
939
959
|
|
|
940
960
|
> Historical (task 1127, removed in task 1173): these rules were once stated in terms of a host-wide
|
|
941
961
|
> `full-gate.lock`. The lock mechanism was deleted (`refactor(gate): remove gate-lock mechanism and
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"variant": {
|
|
54
54
|
"type": "object",
|
|
55
55
|
"additionalProperties": false,
|
|
56
|
-
"description": "A variant may declare any subset of the
|
|
56
|
+
"description": "A variant may declare any subset of the 8 canonical statuses (enumerated below); an unknown status key is rejected.",
|
|
57
57
|
"properties": {
|
|
58
58
|
"backlog": { "$ref": "#/$defs/entry" },
|
|
59
59
|
"todo": { "$ref": "#/$defs/entry" },
|
|
@@ -61,7 +61,8 @@
|
|
|
61
61
|
"testing": { "$ref": "#/$defs/entry" },
|
|
62
62
|
"blocked": { "$ref": "#/$defs/entry" },
|
|
63
63
|
"done": { "$ref": "#/$defs/entry" },
|
|
64
|
-
"cancelled": { "$ref": "#/$defs/entry" }
|
|
64
|
+
"cancelled": { "$ref": "#/$defs/entry" },
|
|
65
|
+
"deprecated": { "$ref": "#/$defs/entry" }
|
|
65
66
|
}
|
|
66
67
|
}
|
|
67
68
|
}
|