@gobing-ai/spur 0.3.85 → 0.3.87
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/pipeline-budgets.json +0 -25
- package/config/plugin-scripts.json +4 -5
- package/config/rules/boundary/env-var-hygiene.yaml +41 -0
- package/config/templates/feature/default.md +2 -0
- package/config/templates/task/brainstorm.md +2 -2
- package/config/templates/task/feature-impl.md +2 -2
- package/config/templates/task/issue.md +2 -2
- package/config/templates/task/meta.md +2 -2
- package/config/templates/task/review.md +2 -2
- package/config/templates/task/standard.md +2 -2
- package/config/transition-shims.json +1 -1
- package/config/workflow-candidates.json +19 -0
- package/config/workflows/feature-lifecycle.yaml +10 -2
- package/config/workflows/feature-verification.yaml +71 -0
- package/config/workflows/idea-pipeline.yaml +87 -39
- package/config/workflows/task-pipeline.yaml +43 -12
- package/config/workflows/wrapup-pipeline.yaml +70 -7
- package/package.json +9 -9
- package/plugins/sp/README.md +7 -7
- package/plugins/sp/commands/dev-idea.md +9 -2
- package/plugins/sp/commands/dev-refactor.md +33 -0
- package/plugins/sp/hooks/agent-hint.ts +5 -4
- package/plugins/sp/hooks/careful-guard.ts +3 -1
- package/plugins/sp/hooks/context-post-tool.ts +2 -1
- package/plugins/sp/hooks/context-session-start.ts +4 -3
- package/plugins/sp/hooks/context-session-stop.ts +2 -1
- package/plugins/sp/hooks/pi/guard-extension.ts +4 -3
- package/plugins/sp/hooks/task-write-guard.ts +4 -3
- package/plugins/sp/lib/idea-handoff.generated.mjs +260 -260
- package/plugins/sp/plugin.json +1 -1
- package/plugins/sp/references/roles.md +1 -1
- package/plugins/sp/scripts/daily-summary/daily-summary.mjs +13 -4
- package/plugins/sp/scripts/daily-summary/daily-summary.ts +6 -4
- package/plugins/sp/scripts/feature-sync-bounded.mjs +10 -2
- package/plugins/sp/scripts/feature-sync-bounded.ts +2 -1
- package/plugins/sp/scripts/idea-coverage-check.ts +168 -0
- package/plugins/sp/scripts/idea-handoff.mjs +6 -1
- package/plugins/sp/scripts/idea-handoff.ts +4 -1
- package/plugins/sp/scripts/inline-pipeline-parity-check.ts +115 -4
- package/plugins/sp/scripts/inline-run-setup.ts +195 -2
- package/plugins/sp/scripts/pr-reviewing.mjs +8 -1
- package/plugins/sp/scripts/pr-reviewing.ts +2 -1
- package/plugins/sp/scripts/quality-gate.mjs +8 -1
- package/plugins/sp/scripts/quality-gate.ts +2 -1
- package/plugins/sp/scripts/surface-drift-inventory.ts +1 -4
- package/plugins/sp/scripts/task-evidence-precheck.ts +2 -1
- package/plugins/sp/scripts/task-size-precheck.ts +6 -4
- package/plugins/sp/scripts/verify-answer-lint.ts +2 -1
- package/plugins/sp/scripts/workflow-step-profile.mjs +10 -2
- package/plugins/sp/scripts/workflow-step-profile.ts +2 -1
- package/plugins/sp/scripts/wrapup-steps.mjs +8 -1
- package/plugins/sp/scripts/wrapup-steps.ts +2 -1
- package/plugins/sp/skills/brainstorm/SKILL.md +4 -0
- package/plugins/sp/skills/code-refactoring/SKILL.md +155 -0
- package/plugins/sp/skills/code-refactoring/references/finding-schema.md +74 -0
- package/plugins/sp/skills/code-refactoring/references/fix-ladder.md +52 -0
- package/plugins/sp/skills/code-refactoring/references/focus-detection.md +44 -0
- package/plugins/sp/skills/code-refactoring/references/refactor-finding.schema.json +95 -0
- package/plugins/sp/skills/spec-decomposition/references/decomposition.md +23 -16
- package/plugins/sp/skills/spur-cli/references/features/acceptance-criteria.md +4 -2
- package/plugins/sp/skills/spur-cli/references/features.md +6 -1
- package/plugins/sp/skills/spur-cli/references/workflows/authoring-workflows.md +2 -2
- package/plugins/sp/skills/spur-cli/references/workflows/operations.md +3 -3
- package/plugins/sp/skills/spur-cli/references/workflows/workflow-fit-and-tuning.md +1 -1
- package/plugins/sp/skills/spur-cli/references/workflows.md +8 -7
- package/plugins/sp/skills/spur-dev/references/ac-style-guide.md +24 -0
- package/plugins/sp/skills/spur-dev/references/cross-cutting.md +4 -5
- package/plugins/sp/skills/spur-dev/references/dev-operations.md +18 -2
- package/plugins/sp/skills/spur-dev/references/done-housekeeping.md +1 -1
- package/plugins/sp/skills/spur-dev/references/flag-glossary.md +22 -3
- package/plugins/sp/skills/spur-dev/references/gate-checklists.md +2 -2
- package/plugins/sp/skills/spur-dev/references/idea-evaluation.md +11 -1
- package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +91 -1
- package/plugins/sp/skills/taste-refactoring-api/SKILL.md +44 -1
- package/plugins/sp/skills/taste-refactoring-api/references/protocol-modes.md +31 -0
- package/plugins/sp/skills/taste-refactoring-architect/SKILL.md +43 -0
- package/plugins/sp/skills/taste-refactoring-tests/SKILL.md +42 -0
- package/plugins/sp/skills/taste-refactoring-ui/SKILL.md +43 -0
- package/schemas/state-machine-workflow.schema.json +5 -0
- package/schemas/task-batch.schema.json +2 -2
- package/schemas/transition-flow-workflow.schema.json +5 -0
- package/spur.js +21106 -20669
- package/web/_astro/BoardApp.CJiqp5pS.js +1 -0
- package/web/_astro/{BoardApp.yW425dRZ.js → BoardApp.yBBcFXWP.js} +4 -4
- package/web/_astro/{TaskDetail.CGwJAinW.js → TaskDetail.DqFJbRFc.js} +1 -1
- package/web/_astro/{arc.B-qNXzSO.js → arc.DL-BpHoi.js} +1 -1
- package/web/_astro/{architectureDiagram-3BPJPVTR.Bdg-xiji.js → architectureDiagram-3BPJPVTR.9IdQYyDq.js} +1 -1
- package/web/_astro/{blockDiagram-GPEHLZMM.DFArg3Kp.js → blockDiagram-GPEHLZMM.BKsFCqTl.js} +1 -1
- package/web/_astro/{c4Diagram-AAUBKEIU.BkOLcjyx.js → c4Diagram-AAUBKEIU.DhwI0dh1.js} +1 -1
- package/web/_astro/channel.CX5453qQ.js +1 -0
- package/web/_astro/{chunk-2J33WTMH.DN3c20V4.js → chunk-2J33WTMH.B3QVmQ9S.js} +1 -1
- package/web/_astro/{chunk-4BX2VUAB.B64K0Ttd.js → chunk-4BX2VUAB.DBSuqs9F.js} +1 -1
- package/web/_astro/{chunk-55IACEB6.C-AJvNwa.js → chunk-55IACEB6.BSYTWAYD.js} +1 -1
- package/web/_astro/{chunk-727SXJPM.DMkr46uS.js → chunk-727SXJPM.cWVuxXfS.js} +1 -1
- package/web/_astro/{chunk-AQP2D5EJ.4_WGbI64.js → chunk-AQP2D5EJ.DpU_Ob3d.js} +1 -1
- package/web/_astro/{chunk-FMBD7UC4.cbFW_lVE.js → chunk-FMBD7UC4.BykFkyji.js} +1 -1
- package/web/_astro/{chunk-ND2GUHAM.CDW_-2O1.js → chunk-ND2GUHAM.DwgHlMdY.js} +1 -1
- package/web/_astro/{chunk-QZHKN3VN.BoYOt_yg.js → chunk-QZHKN3VN.CusXUGWM.js} +1 -1
- package/web/_astro/{classDiagram-4FO5ZUOK.BNT6XpHQ.js → classDiagram-4FO5ZUOK.fx0ObzkN.js} +1 -1
- package/web/_astro/{classDiagram-v2-Q7XG4LA2.BNT6XpHQ.js → classDiagram-v2-Q7XG4LA2.fx0ObzkN.js} +1 -1
- package/web/_astro/{cose-bilkent-S5V4N54A.CI1DQxR3.js → cose-bilkent-S5V4N54A.Z4HgOlsd.js} +1 -1
- package/web/_astro/{cynefin-OW5HDTMX.A8ARH61p.js → cynefin-OW5HDTMX.B5dIZHJu.js} +1 -1
- package/web/_astro/{dagre-BM42HDAG.u28ZmqwR.js → dagre-BM42HDAG.DT70Q_Yw.js} +1 -1
- package/web/_astro/{diagram-2AECGRRQ.Dx8JcrGc.js → diagram-2AECGRRQ.DqHA3XBF.js} +1 -1
- package/web/_astro/{diagram-5GNKFQAL.BXJUG9GY.js → diagram-5GNKFQAL.BmCem957.js} +1 -1
- package/web/_astro/{diagram-KO2AKTUF.BtlMuWqW.js → diagram-KO2AKTUF.sn0-hrE0.js} +1 -1
- package/web/_astro/{diagram-LMA3HP47.C4T7qaAy.js → diagram-LMA3HP47.BSHe9tVc.js} +1 -1
- package/web/_astro/{diagram-OG6HWLK6.D5HECE10.js → diagram-OG6HWLK6.DHIc-86k.js} +1 -1
- package/web/_astro/{erDiagram-TEJ5UH35.B_hMR3yw.js → erDiagram-TEJ5UH35.Bxayrs7v.js} +1 -1
- package/web/_astro/{flowDiagram-I6XJVG4X.BAmpcYl3.js → flowDiagram-I6XJVG4X.BkzoE_5I.js} +1 -1
- package/web/_astro/{ganttDiagram-6RSMTGT7.DV1bSWK-.js → ganttDiagram-6RSMTGT7.okT6CvTo.js} +1 -1
- package/web/_astro/{gitGraphDiagram-PVQCEYII.DxYKkKrJ.js → gitGraphDiagram-PVQCEYII.CJuYbhC7.js} +1 -1
- package/web/_astro/{infoDiagram-5YYISTIA.BAWY2xMb.js → infoDiagram-5YYISTIA.RqLy7nBo.js} +1 -1
- package/web/_astro/{ishikawaDiagram-YF4QCWOH.CZssRn6V.js → ishikawaDiagram-YF4QCWOH.BwIcoagw.js} +1 -1
- package/web/_astro/{journeyDiagram-JHISSGLW.C--muARd.js → journeyDiagram-JHISSGLW.UB1VbWtH.js} +1 -1
- package/web/_astro/{kanban-definition-UN3LZRKU.D_QCK4et.js → kanban-definition-UN3LZRKU.AaxMKpTk.js} +1 -1
- package/web/_astro/{linear.DzrmTtZ0.js → linear.Nv_xOUjP.js} +1 -1
- package/web/_astro/{mermaid.core.Da03W3iu.js → mermaid.core.Bc4LqQgX.js} +4 -4
- package/web/_astro/{mindmap-definition-RKZ34NQL.6cy-8hR_.js → mindmap-definition-RKZ34NQL.oKUvU_qi.js} +1 -1
- package/web/_astro/{pieDiagram-4H26LBE5.C5rS1pdU.js → pieDiagram-4H26LBE5.DQk0oo03.js} +1 -1
- package/web/_astro/{quadrantDiagram-W4KKPZXB.w56GZZ6Q.js → quadrantDiagram-W4KKPZXB.BdDjESDa.js} +1 -1
- package/web/_astro/{requirementDiagram-4Y6WPE33.CipX3Pwu.js → requirementDiagram-4Y6WPE33.C2u9hUeH.js} +1 -1
- package/web/_astro/{sankeyDiagram-5OEKKPKP.C0VVzgJm.js → sankeyDiagram-5OEKKPKP.CDEoiJST.js} +1 -1
- package/web/_astro/{sequenceDiagram-3UESZ5HK.BX2dUUbF.js → sequenceDiagram-3UESZ5HK.D_hT_GAT.js} +1 -1
- package/web/_astro/{stateDiagram-AJRCARHV.ypCdgODQ.js → stateDiagram-AJRCARHV.DI8RYG0b.js} +1 -1
- package/web/_astro/{stateDiagram-v2-BHNVJYJU.In0baEtg.js → stateDiagram-v2-BHNVJYJU.Bkxz4DnP.js} +1 -1
- package/web/_astro/{timeline-definition-PNZ67QCA.CJN4Vkvl.js → timeline-definition-PNZ67QCA.DSY-kH3-.js} +1 -1
- package/web/_astro/{vennDiagram-CIIHVFJN.Cf8KkIPY.js → vennDiagram-CIIHVFJN.CpaDtuGr.js} +1 -1
- package/web/_astro/{wardleyDiagram-YWT4CUSO.DCZBo9xw.js → wardleyDiagram-YWT4CUSO.DujQWvo8.js} +1 -1
- package/web/_astro/{xychartDiagram-2RQKCTM6.Cm4v_MiJ.js → xychartDiagram-2RQKCTM6.DcM5Y4b9.js} +1 -1
- package/web/index.html +1 -1
- package/config/workflows/basic.yaml +0 -146
- package/config/workflows/docs-pipeline.yaml +0 -350
- package/config/workflows/feature-dev.yaml +0 -288
- package/plugins/sp/scripts/feature-dev-precheck.mjs +0 -146
- package/plugins/sp/scripts/feature-dev-precheck.ts +0 -238
- package/web/_astro/BoardApp.CHenHFia.js +0 -1
- package/web/_astro/channel.CbDHK5UQ.js +0 -1
|
@@ -27,6 +27,14 @@ Rules:
|
|
|
27
27
|
- **One R-number = one scenario.** Never split a requirement across multiple scenarios
|
|
28
28
|
under the same R-number; never merge two requirements into one scenario.
|
|
29
29
|
|
|
30
|
+
## Task-side numbering (`AC<n>`)
|
|
31
|
+
|
|
32
|
+
`R<n>` is the **feature** scenario key and the **task Requirements** key. Task `### Acceptance
|
|
33
|
+
Criteria` items therefore use their own namespace: `- [ ] AC1 — <title>` or `Scenario: AC1 — <title>`,
|
|
34
|
+
numbered task-locally. Carry a feature scenario by copying its title after the prefix (`normalizeTitle`
|
|
35
|
+
strips both `AC<n>` and `R<n>`, so DD-09 matching is unaffected); bind a task requirement with
|
|
36
|
+
`(req: R<n>)`. Legacy tasks that wrote `- [ ] R<n> —` / `Scenario: R<n> —` keep working unchanged.
|
|
37
|
+
|
|
30
38
|
## Two AC tiers (authoring convention)
|
|
31
39
|
|
|
32
40
|
A planning convention (DD-06 "permissive start"), not a `spur feature check` feature today —
|
|
@@ -73,6 +81,10 @@ scenario, it matches by title. Rules:
|
|
|
73
81
|
Registered user can log in with email and password" is traceable.
|
|
74
82
|
- **No synonyms in cross-references.** The title in the feature file and the title in the
|
|
75
83
|
task's AC reference must be byte-identical.
|
|
84
|
+
- **Avoid gate vocabulary in titles.** `spur task check` (L4.gate-language) rejects task sections
|
|
85
|
+
containing `HITL`, `approval`/`approved`, `merged`/`merge event`, `content-gate`, `GATED`, or
|
|
86
|
+
`capstone` as standalone words; task AC bullets copy scenario titles verbatim, so a title using
|
|
87
|
+
them fails every child task. Write "pause for an operator answer" instead of "HITL approval".
|
|
76
88
|
|
|
77
89
|
## Verdict AC ↔ feature scenario linkage
|
|
78
90
|
|
|
@@ -199,6 +211,18 @@ Use the canonical BDD template at `templates/bdd/gherkin.md`. Key rules:
|
|
|
199
211
|
- **When** describes the single action under test.
|
|
200
212
|
- **Then** asserts the observable outcome.
|
|
201
213
|
- **And** chains additional preconditions, actions, or assertions.
|
|
214
|
+
- **Trace the scenario to its requirements (0887 R4).** Directly under each `Scenario:`
|
|
215
|
+
heading add a comment line listing the requirement-inventory ids the scenario covers;
|
|
216
|
+
the BDD parser skips `#` comment lines, so the form is checker-inert:
|
|
217
|
+
|
|
218
|
+
```gherkin
|
|
219
|
+
Scenario: Registered user can log in with email and password
|
|
220
|
+
# covers: I1, I3
|
|
221
|
+
Given ...
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
Every inventory item without a `[deferred: ...]` marker must be covered by at least one
|
|
225
|
+
scenario — `idea-coverage-check` measures this at the idea-pipeline's ac-generate boundary.
|
|
202
226
|
|
|
203
227
|
Avoid:
|
|
204
228
|
|
|
@@ -573,8 +573,6 @@ invariants that keep the pipeline set coherent as new ones are added.
|
|
|
573
573
|
| `idea-pipeline.yaml` | Ideation + planning (vague idea or known slug → feature + AC + task batch) | `/sp:dev-idea`, `/sp:dev-plan` | `handoff`, `cancelled` |
|
|
574
574
|
| `task-pipeline.yaml` | Execution (one task → done) | `/sp:dev-run` | `done`, `failed` |
|
|
575
575
|
| `wrapup-pipeline.yaml` | Wrap-up (completed tasks → learning + metrics + doc-sync) | `/sp:dev-wrap`, `/sp:dev-wrapall` | `done`, `skipped` |
|
|
576
|
-
| `feature-dev.yaml` | Umbrella (brainstorm → plan → execute → feature-verify) | `/sp:dev-runall --feature <id>` (or `--tasks feature:<id>`) | `done`, `failed` |
|
|
577
|
-
| `basic.yaml` | Simple (generic implement/check/fix loop) | direct `spur workflow run` | `done`, `failed` |
|
|
578
576
|
| `feature-lifecycle.yaml` | Feature status FSM (entity lifecycle, not a phase pipeline) | `spur feature update` | `done`, `cancelled` |
|
|
579
577
|
| `task-lifecycle.yaml` | Task status FSM (entity lifecycle, not a phase pipeline) | `spur task update` | `done`, `cancelled` |
|
|
580
578
|
|
|
@@ -587,8 +585,9 @@ not replace them.
|
|
|
587
585
|
A pipeline may invoke another workflow through a command wrapper or `spur workflow run` **only at a
|
|
588
586
|
phase boundary** — it must NOT inline another pipeline's state graph. Concretely:
|
|
589
587
|
|
|
590
|
-
-
|
|
591
|
-
|
|
588
|
+
- The feature-level batch entry (`/sp:dev-runall --feature <id>`) dispatches `task-pipeline.yaml`
|
|
589
|
+
per task through the CLI command wrapper, not by inlining the task graph (feature roster →
|
|
590
|
+
execution boundary).
|
|
592
591
|
- `idea-pipeline.yaml`'s `handoff` state may output a command for the operator to run
|
|
593
592
|
`task-pipeline.yaml` (phase boundary: ideation → execution).
|
|
594
593
|
- `task-pipeline.yaml`'s `implement` state must NOT contain a nested state machine for
|
|
@@ -692,7 +691,7 @@ Field semantics (enforced by `parseCheckpointMetadata` / `checkpointStaleness`):
|
|
|
692
691
|
**Writer cadence (0784 R4).** There is exactly one canonical writer: the `task-pipeline` done
|
|
693
692
|
state's terminal checkpoint (`status: done`, real HEAD, run id from `$__runId`, and `$wbs`-expanded
|
|
694
693
|
artifact paths). It is a plain `shell` step — checkpoints are working memory, not CLI-gated corpus.
|
|
695
|
-
The `
|
|
694
|
+
The `wrapup-pipeline`, and `idea-pipeline` pipelines (plus the since-retired `feature-dev`) used to echo pseudo-checkpoints
|
|
696
695
|
("checkpoint: <workflow> done ...") that violated the canonical schema; those writers were removed
|
|
697
696
|
in 0784 — the persisted run row is the authoritative terminal record, and a non-canonical echo
|
|
698
697
|
cannot be resumed, routed, or reclaimed safely.
|
|
@@ -85,7 +85,8 @@ 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>" [--auto] [--skip-design] [--approve-taste] [--agent <inline\|auto\|name>]`
|
|
88
|
+
| 16 | idea | `dev-idea` | `Skill()` | inline driver (`idea-pipeline`) or async workflow | `"<idea>" [--from-file <path>] [--auto] [--skip-design] [--approve-taste] [--agent <inline\|auto\|name>]` |
|
|
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]` |
|
|
89
90
|
|
|
90
91
|
## Skill-backed operations
|
|
91
92
|
|
|
@@ -335,11 +336,18 @@ must not be changed without updating the backing skill.
|
|
|
335
336
|
### 16. idea
|
|
336
337
|
|
|
337
338
|
- **Purpose:** Turn a vague idea into a feature with AC and a decomposed task batch — the unified entry point for the planning half.
|
|
338
|
-
- **Inputs:** `"<idea>"` (
|
|
339
|
+
- **Inputs:** `"<idea>"` (quoted) or `--from-file <path>` — exactly one; the two are mutually
|
|
340
|
+
exclusive (0887 R7). Three everyday axes:
|
|
339
341
|
- `--auto` — skip **objective** HITL (feature-check, batch-create); taste gates still pause.
|
|
340
342
|
- `--skip-design` — design package off (system-design + task Design).
|
|
341
343
|
- `--approve-taste` — with `--auto`, skip **all** remaining taste pauses this run (idea-eval + design-approval). Sets `idea_approved=true` and `design_approved=true`.
|
|
342
344
|
Aliases (prefer `--approve-taste`): `--idea-approved` → `idea_approved`; `--design-approved` → `design_approved`. There is **no** `--design` force flag.
|
|
345
|
+
- `--from-file <path>` — read the idea text from a file instead of the positional argument
|
|
346
|
+
(verbatim; long/multiline asks). Mutually exclusive with `"<idea>"`.
|
|
347
|
+
- **Verbatim idea artifact:** before `start` executes, the driver persists the idea argument (or
|
|
348
|
+
`--from-file` contents) unmodified to `.spur/run/<run-id>-idea-input.md` (0887 R1); the precheck
|
|
349
|
+
fails the run when that file is empty or missing, and every model-bearing stage prompt treats
|
|
350
|
+
it as the authoritative ask (R2).
|
|
343
351
|
- **Backing:** `idea-pipeline.yaml` through the inline driver for omitted/`inline`, or `spur workflow run idea-pipeline.yaml --async` for `auto`/name.
|
|
344
352
|
- **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`.
|
|
345
353
|
- **Delegation:** Host-session inline driver by default; explicit executor selection uses the async workflow worker.
|
|
@@ -356,6 +364,14 @@ must not be changed without updating the backing skill.
|
|
|
356
364
|
|
|
357
365
|
- **Taste pre-clear (`--approve-taste`):** owned with design-approval var semantics in [cross-cutting.md](cross-cutting.md) § "Design Approval Gate"; idea-eval uses the parallel `idea_approved` var. One CLI flag sets both.
|
|
358
366
|
|
|
367
|
+
### 17. refactor
|
|
368
|
+
|
|
369
|
+
- **Purpose:** Lens-routed refactoring with a preservation contract — route a scope through taste lenses (api / architect / tests / ui, auto-detected by path), classify findings on the shared `refactor-finding` schema, and apply via the fix ladder without breaking preserved behavior.
|
|
370
|
+
- **Inputs:** `[<description>]` free-text steering, `--scope <path>` (default: working tree), `--focus <lens>` (default: auto), `--fix <policy>` (default: none), `--check <cmd>` (default: project gate), `--agent <selector>` (default: inline), `--auto` (default: off).
|
|
371
|
+
- **Backing:** `sp:code-refactoring` skill — the command carries zero orchestration logic (ADR-032); the skill owns focus auto-detection, lens dispatch, the P1–P4 severity map, objective/taste gates, and the fix ladder with revert-on-regression.
|
|
372
|
+
- **Behavior:** Green `--check` baseline → focus detection → lens dispatch → findings to `.spur/run/<run-id>-refactor-findings.json` + human report `.spur/run/<run-id>-refactor-report.md` (lens set, P1–P4 table, preservation summary, applied/reverted/deferred). `--fix blockers-first` auto-applies P1/P2 `auto`-eligible findings; `--fix all` extends to `operator`-eligible P3/P4; every fix re-runs `--check` and reverts on regression. Tests are never removed or weakened by an `auto` fix.
|
|
373
|
+
- **Operator taste gates:** every `cutting` or `breaking` finding pauses for an explicit operator answer in every mode — even `--auto` skips only objective gates. `--fix none` (the default) writes both artifacts with no edits.
|
|
374
|
+
|
|
359
375
|
---
|
|
360
376
|
|
|
361
377
|
## Inline operations
|
|
@@ -105,7 +105,7 @@ gate will reject the task without it). Use the normal `--section --from-file` co
|
|
|
105
105
|
**4. Force-done with an honest reason.**
|
|
106
106
|
|
|
107
107
|
```bash
|
|
108
|
-
|
|
108
|
+
spur task update <wbs> done --force-done --provenance-bypass \
|
|
109
109
|
--reason "<step> agent.run timed out at <N>s; recovered manually: lint clean, <suite> pass, sections authored by hand"
|
|
110
110
|
```
|
|
111
111
|
|
|
@@ -160,13 +160,21 @@ Scope the operation to all tasks under a feature id (`^[A-Z][1-9]*$`). On featur
|
|
|
160
160
|
commands (`dev-wrapall`) it also advances the feature through legal lifecycle edges with guards
|
|
161
161
|
honored.
|
|
162
162
|
|
|
163
|
+
### `--check <cmd>` — validation command for iterate-and-check loops
|
|
164
|
+
|
|
165
|
+
**Anchor:** `#flag-check`.
|
|
166
|
+
|
|
167
|
+
Verification command a command iterates against (`dev-simplify`, `dev-refactor`). The command
|
|
168
|
+
establishes a baseline with it before the first change and re-runs it after each change.
|
|
169
|
+
|
|
163
170
|
### `--focus <dims>` — constrain the operation to specific dimensions
|
|
164
171
|
|
|
165
172
|
**Anchor:** `#flag-focus`.
|
|
166
173
|
|
|
167
174
|
Constrain the operation to a named subset of dimensions — review dimensions on `dev-review`/
|
|
168
175
|
`dev-verify`/`dev-verifyall` (`all|stack|dependencies|data|flows|api|security|quality|performance`),
|
|
169
|
-
a
|
|
176
|
+
a refactor lens set on `dev-refactor` (`api|architect|tests|ui|auto`), a refine focus mode on
|
|
177
|
+
`dev-refine`/`dev-refineall`, or a reconstruction lens on `dev-reverse`.
|
|
170
178
|
Narrowing reduces token cost; omitting runs
|
|
171
179
|
all dimensions.
|
|
172
180
|
|
|
@@ -175,7 +183,7 @@ all dimensions.
|
|
|
175
183
|
**Anchor:** `#flag-scope`.
|
|
176
184
|
|
|
177
185
|
Limit the operation to a file or directory path (`dev-arch`, `dev-debug`, `dev-fixall`,
|
|
178
|
-
`dev-gitmsg`, `dev-gtd`, `dev-simplify`) to bound the working set.
|
|
186
|
+
`dev-gitmsg`, `dev-gtd`, `dev-refactor`, `dev-simplify`) to bound the working set.
|
|
179
187
|
|
|
180
188
|
### `--all` — widen the operation to everything in its domain
|
|
181
189
|
|
|
@@ -253,7 +261,8 @@ tasks by `updated_at >= date`).
|
|
|
253
261
|
|
|
254
262
|
**Anchor:** `#flag-fix`.
|
|
255
263
|
|
|
256
|
-
Remediation policy on verify-family commands (`dev-verify`, `dev-verifyall`)
|
|
264
|
+
Remediation policy on verify-family commands (`dev-verify`, `dev-verifyall`) and the refactor
|
|
265
|
+
coordinator (`dev-refactor`):
|
|
257
266
|
`none|blockers-first|all`. `none` reports findings without fixing; `blockers-first` fixes only P1/P2;
|
|
258
267
|
`all` fixes everything found. Deprecated on `dev-review` (routes to `dev-verify --fix`).
|
|
259
268
|
|
|
@@ -294,6 +303,16 @@ verifying a task whose artifact is intentionally not yet shippable (e.g. a doc-o
|
|
|
294
303
|
Omit the design package (system-design satellite + task `### Design`) on planning commands
|
|
295
304
|
(`dev-plan`, `dev-idea`). The task is created without the design section; refine supplies it later.
|
|
296
305
|
|
|
306
|
+
### `--from-file <path>` — read the idea from a file (dev-idea)
|
|
307
|
+
|
|
308
|
+
**Anchor:** `#flag-from-file`.
|
|
309
|
+
|
|
310
|
+
`dev-idea` reads the idea text from `<path>` instead of the positional argument. Mutually
|
|
311
|
+
exclusive with `"<idea>"` — exactly one must be present. The file's contents become the verbatim
|
|
312
|
+
idea text, persisted unmodified to `.spur/run/<run-id>-idea-input.md` (0887 R1) and treated as
|
|
313
|
+
the authoritative ask by every model-bearing stage prompt. Useful for long or multiline asks
|
|
314
|
+
that are awkward to quote (0887 R7).
|
|
315
|
+
|
|
297
316
|
### `--output <path>` — write the result to a path
|
|
298
317
|
|
|
299
318
|
**Anchor:** `#flag-output`.
|
|
@@ -149,11 +149,11 @@ passed, so provenance denied first and Review L3 denied on the retry.
|
|
|
149
149
|
|
|
150
150
|
| # | Gate layer | Triggers denial when | Remediation |
|
|
151
151
|
|---|------------|----------------------|-------------|
|
|
152
|
-
| 1 | **Strict-core + verdict artifact** (`spur task check <wbs> --strict-core` + `done-transition-guard.ts`) | The strict-core check fails, or `.spur/run/<wbs>-verdict.json` is **missing** or has a non-PASS aggregate. **Missing artifact is a deny** (not a silent allow — closes the 0349 "done without verdict" class). The aggregate is recomputed from requirement/AC rows; the harsher of stored and computed wins. | Re-run `/sp:dev-verify <wbs>` until PASS (writes the artifact), or explicitly override with `spur task update <wbs> done --force-done --reason "<why>"`. Docs-only
|
|
152
|
+
| 1 | **Strict-core + verdict artifact** (`spur task check <wbs> --strict-core` + `done-transition-guard.ts`) | The strict-core check fails, or `.spur/run/<wbs>-verdict.json` is **missing** or has a non-PASS aggregate. **Missing artifact is a deny** (not a silent allow — closes the 0349 "done without verdict" class). The aggregate is recomputed from requirement/AC rows; the harsher of stored and computed wins. | Re-run `/sp:dev-verify <wbs>` until PASS (writes the artifact), or explicitly override with `spur task update <wbs> done --force-done --reason "<why>"`. Docs-only procedures meet the same layer: read-only measured verification
|
|
153
153
|
(answer file + `spur task verdict`) writes the standard `.spur/run/<wbs>-verdict.json` artifact
|
|
154
154
|
under proof-input digest bracketing; missing or non-PASS evidence is a refusal, never a synthetic
|
|
155
155
|
PASS stub. |
|
|
156
|
-
| 2 | **Provenance guard** (`lifecycle-adapter.ts`) | No pipeline-kind run link exists for `<wbs>`. | Run `/sp:dev-run <wbs>` through the full pipeline, use `/sp:dev-run <wbs> --mode implement --auto --next` for the explicit step chain, or record the audited bypass with `
|
|
156
|
+
| 2 | **Provenance guard** (`lifecycle-adapter.ts`) | No pipeline-kind run link exists for `<wbs>`. | Run `/sp:dev-run <wbs>` through the full pipeline, use `/sp:dev-run <wbs> --mode implement --auto --next` for the explicit step chain, or record the audited bypass with `--provenance-bypass` on `spur task update`. |
|
|
157
157
|
| 3 | **Review L3** (`task-check.ts`) | `### Review` is empty, placeholder-only, or lacks a populated P1–P4 findings table. | Run `/sp:dev-review <wbs>`; verify cannot write Review because of the Step 10 prohibition above. |
|
|
158
158
|
|
|
159
159
|
When the verdict is **PARTIAL/FAIL**, or any gate layer fails: stop as review-pending — surface
|
|
@@ -20,7 +20,9 @@ recommendation is mandatory, stakes in plain English, and approve/reject is the
|
|
|
20
20
|
re-author the report.
|
|
21
21
|
|
|
22
22
|
**Sidecar rule:** The enhanced idea does **not** overwrite `vars.idea`. Feature-create reads both
|
|
23
|
-
the original idea and this report.
|
|
23
|
+
the original idea and this report. The operator's verbatim ask of record is the run's
|
|
24
|
+
`.spur/run/<run-id>-idea-input.md` (persisted by the pipeline `start` state / the inline driver
|
|
25
|
+
before any processing); the `## Requirement inventory` items trace back to it.
|
|
24
26
|
|
|
25
27
|
## Template
|
|
26
28
|
|
|
@@ -30,6 +32,13 @@ the original idea and this report.
|
|
|
30
32
|
## Enhanced Idea
|
|
31
33
|
<one-paragraph refined statement of what the idea actually requires — the "real requirement" after discovery sharpens the vague input>
|
|
32
34
|
|
|
35
|
+
## Requirement inventory
|
|
36
|
+
<mandatory — the coverage gate (idea-coverage-check) parses this section, so keep the exact `- I<n> — ` item form>
|
|
37
|
+
- I1 — <requirement stated as an ask, quoting or paraphrasing the source line from the run's idea-input artifact> (source: "<quoted fragment from the operator's idea>")
|
|
38
|
+
- I2 — <next requirement>
|
|
39
|
+
- I<n> — <optional: a requirement explicitly out of scope> [deferred: <reason>]
|
|
40
|
+
- I<n> — <optional: an ambiguous ask> [unclear: <why it is ambiguous>] — an unclear marker does not exempt the item; it still needs coverage or an explicit deferral
|
|
41
|
+
|
|
33
42
|
## Scores
|
|
34
43
|
|
|
35
44
|
| Dimension | Score (0–5) | Rationale |
|
|
@@ -74,6 +83,7 @@ Stakes: <plain-English cost of proceeding vs not; reversibility; blast radius>
|
|
|
74
83
|
|------|--------|
|
|
75
84
|
| Filled instance path | `.spur/run/idea-eval-report.md` |
|
|
76
85
|
| Template home | this file |
|
|
86
|
+
| Requirement inventory | mandatory `## Requirement inventory` section (0887 R3); consumed by `idea-coverage-check` (R4) |
|
|
77
87
|
| HITL state | `idea-eval` in `idea-pipeline.yaml` |
|
|
78
88
|
| Approve | continue → `feature-create` |
|
|
79
89
|
| Reject / cancel | → `cancelled` (no feature) |
|
|
@@ -25,7 +25,11 @@ implements it; remove the entry when the corresponding kind is dropped from the
|
|
|
25
25
|
|
|
26
26
|
**Actions:** `shell` · `note` · `doctor.probe` · `file.read.into-var` · `hitl.confirm` · `agent.run` · `proof.fingerprint` · `run.artifact` · `command.gate`
|
|
27
27
|
|
|
28
|
-
**Guards (transitions):** `always` · `shell`
|
|
28
|
+
**Guards (transitions):** `always` · `shell` · `action-ok` · `contract-violation`
|
|
29
|
+
|
|
30
|
+
- `action-ok` — pass iff the prior action on this state/node succeeded (engine builtin).
|
|
31
|
+
- `contract-violation` — pass iff the prior `agent.run` result is a named contract violation
|
|
32
|
+
(`data.outcome === 'contract-violation'`, ADR-118); the report carries `contract` and `observed`.
|
|
29
33
|
|
|
30
34
|
## What this driver is
|
|
31
35
|
|
|
@@ -156,6 +160,35 @@ the human/native presentation layer — labels are display addresses only, never
|
|
|
156
160
|
This is required for the normal `testing → done` provenance guard. Planning pipelines have no
|
|
157
161
|
task lifecycle link and skip this task-specific action.
|
|
158
162
|
|
|
163
|
+
### Idea-pipeline quick start (0887 R1/R2)
|
|
164
|
+
|
|
165
|
+
Minimum files to read for `/sp:dev-idea` inline runs — then drive `idea-pipeline.yaml`:
|
|
166
|
+
|
|
167
|
+
- `.spur/workflows/idea-pipeline.yaml` (the machine) and this driver.
|
|
168
|
+
- `plugins/sp/skills/spur-dev/references/idea-evaluation.md` (report template incl. the mandatory
|
|
169
|
+
`## Requirement inventory`) and `references/ac-style-guide.md` (scenario `# covers:` form).
|
|
170
|
+
- `references/dev-operations.md` § idea for the stage-by-stage surface.
|
|
171
|
+
|
|
172
|
+
**Persist the verbatim idea FIRST.** Before executing the `start` state, write the operator's
|
|
173
|
+
idea argument (or `--from-file` contents) **unmodified** to
|
|
174
|
+
`.spur/run/<run-id>-idea-input.md`; the run precheck fails when that file is empty or missing,
|
|
175
|
+
and every model-bearing stage prompt treats it as the authoritative ask. `--from-file` and the
|
|
176
|
+
positional idea are mutually exclusive — exactly one must be present.
|
|
177
|
+
|
|
178
|
+
Expected artifacts per stage (all run-scoped under `.spur/run/<run-id>-*`):
|
|
179
|
+
|
|
180
|
+
| Stage | Artifacts |
|
|
181
|
+
| ----- | --------- |
|
|
182
|
+
| start | `-idea-input.md` (verbatim idea), `-idea-precheck-doctor.status` |
|
|
183
|
+
| discovery | `-idea-eval-report.md` (with `## Requirement inventory`), `-idea-needs-design.json` |
|
|
184
|
+
| feature-create | `-idea-feature-id.txt`, `-idea-goal.md`, `-idea-scope.md` |
|
|
185
|
+
| ac-generate | `-idea-ac-content.md`, `-idea-ac-check.status`, `-idea-coverage.status` |
|
|
186
|
+
| system-design | `-idea-design-review.md`, `-idea-design-check.status` |
|
|
187
|
+
| decompose | `-idea-task-batch.json`, `-idea-task-order.json` |
|
|
188
|
+
| batch-create-run | `-idea-batch-create-result.json`, `-idea-batch-create.done`/`.failed` |
|
|
189
|
+
| ready-prepare | `-idea-ready.json` |
|
|
190
|
+
| handoff-finalize | `-idea-handoff.md` |
|
|
191
|
+
|
|
159
192
|
## Comprehensive-check retention and evidence (R7/R8)
|
|
160
193
|
|
|
161
194
|
**R7 — comprehensive checks stay at their owning boundaries.** Quick readiness and plan projection are
|
|
@@ -398,6 +431,63 @@ keep their exact content after the stamp prefix. This normalization is contractu
|
|
|
398
431
|
**bare local-clock stamps are prohibited** — a hand-appended `[stage 12:31]` form mixes timezones
|
|
399
432
|
in one file and makes the run unauditable (task 0726 mixed both forms).
|
|
400
433
|
|
|
434
|
+
## Structured trace emission (ADR-117, task 0868)
|
|
435
|
+
|
|
436
|
+
`.spur/run/<run-id>.log` is a human convenience, **not the record of truth**. A run's
|
|
437
|
+
observability is a property of the run, so the inline driver owes the same structured trace the
|
|
438
|
+
engine subprocess writes — and it owes it through the **same writer**, never a parallel
|
|
439
|
+
implementation. The shared writer is `WorkflowActionTraceWriter`
|
|
440
|
+
(`packages/app/src/workflow/action-trace.ts`): the same decorator the engine composition installs
|
|
441
|
+
around `DbWorkflowPersistenceAdapter`, so the two surfaces call one emission path and one run-row
|
|
442
|
+
closure path and cannot drift.
|
|
443
|
+
|
|
444
|
+
The driver reaches it through the existing run delegate (`$SETUP_SCRIPT`,
|
|
445
|
+
`plugins/sp/scripts/inline-run-setup.ts`) — no new entry point, no second resolution chain:
|
|
446
|
+
|
|
447
|
+
- **Every executed action** — after the action settles, whether it ran host-inline or via a native
|
|
448
|
+
subagent — append its provenance line as before, then record the boundary:
|
|
449
|
+
|
|
450
|
+
```bash
|
|
451
|
+
bun "$SETUP_SCRIPT" --action --run-id "$RUN_ID" --node <state-id> --kind <action-kind> \
|
|
452
|
+
--status <done|failed> --ok <true|false> --duration-ms <measured-ms>
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
`<state-id>` is the current YAML state id (the `node`), `<action-kind>` the YAML action kind
|
|
456
|
+
(`agent.run`, `shell`, `note`, `doctor.probe`, …). `--status` is `done` when the action settled
|
|
457
|
+
under its declared error policy and `failed` otherwise; `--duration-ms` is the wall clock the
|
|
458
|
+
driver measured around the action. This writes the `action_runs` row (node, kind, status, `ok`,
|
|
459
|
+
`duration_ms`, `run_id`) the engine would have written, so the run's rows are queryable by run id
|
|
460
|
+
(`spur workflow progress <run-id>`, `ActionRunDao`) without reading the text log. The writer
|
|
461
|
+
back-dates the row's `started_at` from its own `completed_at` minus the measured duration
|
|
462
|
+
(0887 R8), so `completed_at − started_at == duration_ms` exactly; a back-date failure is
|
|
463
|
+
recorded (`action.backdate`) and never affects the run.
|
|
464
|
+
|
|
465
|
+
- **At the run's declared terminal state** — before the driver reports the run complete, close the
|
|
466
|
+
row so a successful inline run is never left non-terminal for `spur workflow clean` to reap as
|
|
467
|
+
stale:
|
|
468
|
+
|
|
469
|
+
```bash
|
|
470
|
+
bun "$SETUP_SCRIPT" --close --run-id "$RUN_ID" --status <done|failed|paused>
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
`--status` is the declared terminal state's verdict, not a guess: a run that reached a terminal
|
|
474
|
+
state is `done`; a run halted by a failing action under its error policy is `failed`.
|
|
475
|
+
|
|
476
|
+
**Best-effort at the action boundary only (ADR-117).** An `--action` persistence failure is
|
|
477
|
+
recorded — the delegate appends a `trace-emission-failed` line to `.spur/run/<run-id>.log` and
|
|
478
|
+
prints `{"ok":false}` on stdout — and the run continues to its declared terminal state; the
|
|
479
|
+
delegate exits `0` for that outcome and the driver must never treat an emission failure as a run
|
|
480
|
+
failure, retry it in a loop, or substitute a hand-written row. The run-row closure (`--close`) is
|
|
481
|
+
bookkeeping, not trace emission, and is **not** best-effort: a missing run row or a persistence
|
|
482
|
+
failure exits `1` with `{"ok":false}` and a named error (a missing row also carries
|
|
483
|
+
`code:"RUN_NOT_FOUND"`), because a silently `running` row is exactly the stale state
|
|
484
|
+
`spur workflow clean` reaps as `failed`. Exit `2` means the invocation itself was malformed
|
|
485
|
+
(missing `--node`/`--kind`/`--status`/`--ok`, a miscased `--ok`, a missing or malformed
|
|
486
|
+
`--duration-ms`, or an unsafe run id) and must be corrected, not ignored.
|
|
487
|
+
|
|
488
|
+
Emission is not optional and not deferred: an inline run that skips it reintroduces the
|
|
489
|
+
1,011-untraced-runs gap ADR-117 exists to close.
|
|
490
|
+
|
|
401
491
|
Transition guards are not advisory. Execute the declared guard exactly, in order, with the same
|
|
402
492
|
resolved variables and artifacts. `--no-lifecycle` remains bookkeeping only; the YAML's task checks,
|
|
403
493
|
verdict gate, record step, and done guard all remain authoritative.
|
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: taste-refactoring-api
|
|
3
3
|
description: Design, review, and refactor REST/HTTP, RPC/gRPC, GraphQL, and event API contracts safely.
|
|
4
|
+
license: Apache-2.0
|
|
5
|
+
metadata:
|
|
6
|
+
author: spur
|
|
7
|
+
version: "1.0"
|
|
8
|
+
platforms: "claude-code,codex,openclaw,opencode,antigravity"
|
|
9
|
+
category: execution
|
|
10
|
+
interactions:
|
|
11
|
+
- technique
|
|
12
|
+
operations:
|
|
13
|
+
- refactor-apis
|
|
14
|
+
openclaw:
|
|
15
|
+
emoji: "🔌"
|
|
4
16
|
---
|
|
5
17
|
|
|
6
18
|
# taste-refactoring-api
|
|
@@ -174,7 +186,7 @@ The goal is to eliminate repeated low-level API decisions, not to create bureauc
|
|
|
174
186
|
|
|
175
187
|
## Protocol-specific review
|
|
176
188
|
|
|
177
|
-
After classifying the API, read the matching REST/HTTP, RPC/gRPC, GraphQL, or event/webhook section in [references/protocol-modes.md](references/protocol-modes.md). Apply that checklist before continuing with the refactoring strategy.
|
|
189
|
+
After classifying the API, read the matching REST/HTTP, RPC/gRPC, GraphQL, or event/webhook section in [references/protocol-modes.md](references/protocol-modes.md). Apply that checklist before continuing with the refactoring strategy. For command-line surface work (designing or reviewing a CLI), read the [CLI mode](references/protocol-modes.md) section instead — a CLI is a contract surface with the same compatibility duties as any wire protocol.
|
|
178
190
|
|
|
179
191
|
## Refactoring strategy
|
|
180
192
|
|
|
@@ -332,3 +344,34 @@ Specify the tests/checks needed: contract tests, schema validation, compatibilit
|
|
|
332
344
|
## Decision rule
|
|
333
345
|
|
|
334
346
|
A “better” API is not the one with the prettiest route names. It is the one that makes common client code obvious, predictable, safe under failure, compatible over time, secure by default, and operable in production.
|
|
347
|
+
|
|
348
|
+
## Spur contract
|
|
349
|
+
|
|
350
|
+
Machine-facing adapter for `sp:code-refactoring` dispatch (feature H13). Everything above is the
|
|
351
|
+
lens's native output and is unchanged; this section only maps it to the shared finding schema.
|
|
352
|
+
|
|
353
|
+
**Inputs received:** a scope path, an optional change description, and the `api` focus. Read
|
|
354
|
+
first: the classification and protocol section above (plus [references/protocol-modes.md](references/protocol-modes.md)),
|
|
355
|
+
then `../code-refactoring/references/finding-schema.md` for shared field semantics.
|
|
356
|
+
|
|
357
|
+
**Native finding → schema mapping:** each “Highest-impact refactor” item → `id` as
|
|
358
|
+
`RF-api-<nnn>`; the item's compatibility label → `rung` verbatim (`additive` | `risky` |
|
|
359
|
+
`breaking`); consumer impact → `title` and `proposal` (imperative); cited routes/lines →
|
|
360
|
+
`evidence` as `{file, line}` entries inside scope; `Verification` items → `verify`; the
|
|
361
|
+
“Proposed contract” snippets stay in `proposal`; new findings start at `status: open`.
|
|
362
|
+
|
|
363
|
+
**Severity mapping (design §5):** a `breaking` change already shipped, or contract ambiguity that
|
|
364
|
+
corrupts data → `P1`; a `risky` inconsistency across ≥2 endpoints → `P2`; `additive` cleanups →
|
|
365
|
+
`P3`; naming/docs → `P4`.
|
|
366
|
+
|
|
367
|
+
**Preserved-behavior inventory (required before proposals):** emit the consumer contract —
|
|
368
|
+
audience (public/partner/internal/service-to-service), endpoints/operations in scope, existing
|
|
369
|
+
clients that must remain compatible, and the compatibility promise — before the first finding.
|
|
370
|
+
|
|
371
|
+
**Preservation class (reuses the native classification):** `additive` → `preserving`; `risky`
|
|
372
|
+
and `breaking` → `breaking`; removal of an endpoint, field, or code path with callers →
|
|
373
|
+
`cutting` even when the change reads additive to remaining consumers.
|
|
374
|
+
|
|
375
|
+
**Stop rules:** an established style guide or public compatibility promise is a constraint, not
|
|
376
|
+
suggestion; `cutting`/`breaking` is never below `P2` and never `fix_eligibility: auto`; risky and
|
|
377
|
+
breaking changes carry a migration strategy; anything outside the scope path is not a finding.
|
|
@@ -77,3 +77,34 @@ For mutation races, prefer explicit optimistic concurrency such as ETags / `If-M
|
|
|
77
77
|
- Make consumers tolerant of additive fields.
|
|
78
78
|
- Do not use events as disguised synchronous RPC responses when the caller needs an immediate result.
|
|
79
79
|
|
|
80
|
+
## CLI mode
|
|
81
|
+
|
|
82
|
+
A command-line interface is a contract surface with consumers (scripts, other agents, CI), not a
|
|
83
|
+
collection of convenience shortcuts. Review it with the same compatibility discipline as REST or
|
|
84
|
+
gRPC. Spur's own `apps/cli` is the first target.
|
|
85
|
+
|
|
86
|
+
**Noun/verb grammar:** keep one noun per domain and verbs per action (`spur task show`, not
|
|
87
|
+
`spur showTaskForTask`). Do not introduce a second grammar for the same concept — one spelling per
|
|
88
|
+
noun, one verb per operation, consistent object order.
|
|
89
|
+
|
|
90
|
+
**Flag vocabulary consistency:** shared flags (`--json`, `--scope`, `--agent`, `--fix`) keep the
|
|
91
|
+
same name, arity, and semantics everywhere they appear. A flag that means something new per
|
|
92
|
+
command is a defect; declare a new flag instead.
|
|
93
|
+
|
|
94
|
+
**Exit codes:** `0` = success, nonzero = failure, deterministic and machine-checkable. Never
|
|
95
|
+
swallow failures into `0`; never return nonzero for advisory output. Validation errors and
|
|
96
|
+
runtime failures should be distinguishable from output where practical.
|
|
97
|
+
|
|
98
|
+
**`--json` envelope stability:** `--json` output is a public schema. Add fields additively; never
|
|
99
|
+
remove or rename existing fields, never change a field's type, and emit no human decoration
|
|
100
|
+
(banners, progress text) on the JSON stream. Machine consumers parse the documented envelope only.
|
|
101
|
+
|
|
102
|
+
**Help-text parity:** every accepted flag appears in `--help` with its real arity and default;
|
|
103
|
+
every documented example runs as printed. A flag that works but is not documented, or documented
|
|
104
|
+
but rejected, is a parity break.
|
|
105
|
+
|
|
106
|
+
**Additive vs breaking:** adding a noun, verb, flag, or output field is additive. Renaming or
|
|
107
|
+
removing any of them, re-purposing a flag, changing a default, or altering existing output shape
|
|
108
|
+
is breaking — it requires a migration path and a deprecation window, and it never rides in a
|
|
109
|
+
patch release.
|
|
110
|
+
|
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: taste-refactoring-architect
|
|
3
3
|
description: Review, simplify, and refactor system architecture toward minimum sufficient architecture while preserving required capabilities, quality attributes, delivery safety, and data invariants. Backs architectural refactoring and boundary reviews.
|
|
4
|
+
license: Apache-2.0
|
|
5
|
+
metadata:
|
|
6
|
+
author: spur
|
|
7
|
+
version: "1.0"
|
|
8
|
+
platforms: "claude-code,codex,openclaw,opencode,antigravity"
|
|
9
|
+
category: execution
|
|
10
|
+
interactions:
|
|
11
|
+
- technique
|
|
12
|
+
operations:
|
|
13
|
+
- refactor-architecture
|
|
14
|
+
openclaw:
|
|
15
|
+
emoji: "🏛️"
|
|
4
16
|
---
|
|
5
17
|
|
|
6
18
|
# taste-refactoring-architect
|
|
@@ -469,3 +481,34 @@ Do not block on perfect documentation. Produce:
|
|
|
469
481
|
- decisions that can safely proceed now.
|
|
470
482
|
|
|
471
483
|
Use A7 DEFER/OBSERVE when evidence is too weak for a structural change.
|
|
484
|
+
|
|
485
|
+
## Spur contract
|
|
486
|
+
|
|
487
|
+
Machine-facing adapter for `sp:code-refactoring` dispatch (feature H13). Everything above is the
|
|
488
|
+
lens's native output and is unchanged; this section only maps it to the shared finding schema.
|
|
489
|
+
|
|
490
|
+
**Inputs received:** a scope path, an optional change description, and the `architect` focus.
|
|
491
|
+
Read first: the intervention ladder and workflow above, then
|
|
492
|
+
`../code-refactoring/references/finding-schema.md` for shared field semantics.
|
|
493
|
+
|
|
494
|
+
**Native finding → schema mapping:** `ID` → `id` as `RF-architect-<nnn>`; `Action` (A0–A7) →
|
|
495
|
+
`rung` verbatim; `Observation`/`Why it matters` → `title` plus `proposal` (imperative); `Evidence`
|
|
496
|
+
→ `evidence` as `{file, line}` entries inside scope; `Fitness functions` → `verify`; new findings
|
|
497
|
+
start at `status: open`. ADR candidates and migration plans stay prose findings with
|
|
498
|
+
`fix_eligibility: suggest`.
|
|
499
|
+
|
|
500
|
+
**Severity mapping (design §5):** any axis ≤1 with a correctness/safety consequence → `P1`; axis
|
|
501
|
+
≤2 or A5–A7 seam problems → `P2`; A3–A4 → `P3`; A0–A2, ADR candidates, deferred questions → `P4`.
|
|
502
|
+
|
|
503
|
+
**Preserved-behavior inventory (required before proposals):** emit the Preservation Contract
|
|
504
|
+
table — capabilities, quality attributes, data invariants, and their thresholds — for everything
|
|
505
|
+
in scope before the first finding.
|
|
506
|
+
|
|
507
|
+
**Preservation class:** A0/A3/A4 mechanical consolidations with identical behavior →
|
|
508
|
+
`preserving`; A1/A2 removal of a live service, endpoint, queue, or code path with callers →
|
|
509
|
+
`cutting`; A5–A7 seam or behavior changes → `breaking`; migration plans and ADR candidates →
|
|
510
|
+
`preserving` prose with `fix_eligibility: suggest`.
|
|
511
|
+
|
|
512
|
+
**Stop rules:** no removal without dependency/traffic/contract evidence; `cutting`/`breaking` is
|
|
513
|
+
never below `P2` and never `fix_eligibility: auto`; multi-task migrations are `suggest`, applied
|
|
514
|
+
only after an explicit operator answer; anything outside the scope path is not a finding.
|
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: taste-refactoring-tests
|
|
3
3
|
description: Refactor unit tests for failure sensitivity, deterministic confidence, and regression protection without mock-heavy brittle tests or vanity coverage. Backs test suite quality audits.
|
|
4
|
+
license: Apache-2.0
|
|
5
|
+
metadata:
|
|
6
|
+
author: spur
|
|
7
|
+
version: "1.0"
|
|
8
|
+
platforms: "claude-code,codex,openclaw,opencode,antigravity"
|
|
9
|
+
category: execution
|
|
10
|
+
interactions:
|
|
11
|
+
- technique
|
|
12
|
+
operations:
|
|
13
|
+
- refactor-tests
|
|
14
|
+
openclaw:
|
|
15
|
+
emoji: "🧪"
|
|
4
16
|
---
|
|
5
17
|
|
|
6
18
|
# taste-refactoring-tests
|
|
@@ -480,3 +492,33 @@ A test refactor is complete only when:
|
|
|
480
492
|
- delivery speed is not degraded without a justified risk trade-off.
|
|
481
493
|
|
|
482
494
|
The goal is **earned confidence**: green means something because the suite has demonstrated that it can turn red when the product is wrong.
|
|
495
|
+
|
|
496
|
+
## Spur contract
|
|
497
|
+
|
|
498
|
+
Machine-facing adapter for `sp:code-refactoring` dispatch (feature H13). Everything above is the
|
|
499
|
+
lens's native output and is unchanged; this section only maps it to the shared finding schema.
|
|
500
|
+
|
|
501
|
+
**Inputs received:** a scope path, an optional change description, and the `tests` focus. Read
|
|
502
|
+
first: the intervention ladder, Confidence Contract, and review severity above, then
|
|
503
|
+
`../code-refactoring/references/finding-schema.md` for shared field semantics.
|
|
504
|
+
|
|
505
|
+
**Native finding → schema mapping:** `ID` → `id` as `RF-tests-<nnn>`; `Action` (T0–T7) → `rung`
|
|
506
|
+
verbatim; `Severity` → `severity` via the map below; `Evidence` → `evidence` as `{file, line}`
|
|
507
|
+
entries inside scope; `Why it matters` → `title`; `Proposed change` → `proposal` (imperative);
|
|
508
|
+
`Expected regression-detection improvement` → folded into `proposal`; new findings start at
|
|
509
|
+
`status: open`.
|
|
510
|
+
|
|
511
|
+
**Severity mapping (design §5):** native P0 → `P1`; P1 → `P2`; P2 → `P3`; P3 → `P4`.
|
|
512
|
+
|
|
513
|
+
**Preserved-behavior inventory (required before proposals):** emit the Confidence Contract —
|
|
514
|
+
critical business rules, compatibility contracts, authorization/security decisions, data
|
|
515
|
+
integrity invariants, error semantics, and incident regressions the suite must keep protecting —
|
|
516
|
+
before the first finding.
|
|
517
|
+
|
|
518
|
+
**Preservation class:** T0 and rungs that keep or add protection (fixture cleanup, adding a
|
|
519
|
+
missing test) → `preserving`; removing a test or test file (T1) → `cutting`; weakening or
|
|
520
|
+
semantically changing existing assertions → `breaking`.
|
|
521
|
+
|
|
522
|
+
**Stop rules:** unknown protection is a risk, never permission to delete; a `cutting`/`breaking`
|
|
523
|
+
finding is never `fix_eligibility: auto` and never below `P2`; tests are never removed or
|
|
524
|
+
weakened by an `auto` fix; anything outside the scope path is not a finding.
|
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: taste-refactoring-ui
|
|
3
3
|
description: Design, review, and refactor UI hierarchy, layout, typography, spacing, color, and interactions.
|
|
4
|
+
license: Apache-2.0
|
|
5
|
+
metadata:
|
|
6
|
+
author: spur
|
|
7
|
+
version: "1.0"
|
|
8
|
+
platforms: "claude-code,codex,openclaw,opencode,antigravity"
|
|
9
|
+
category: execution
|
|
10
|
+
interactions:
|
|
11
|
+
- technique
|
|
12
|
+
operations:
|
|
13
|
+
- refactor-ui
|
|
14
|
+
openclaw:
|
|
15
|
+
emoji: "🎨"
|
|
4
16
|
---
|
|
5
17
|
|
|
6
18
|
# taste-refactoring-ui
|
|
@@ -288,3 +300,34 @@ For deeper reasoning and daily use, read:
|
|
|
288
300
|
- `references/refactoring-ui-playbook.md` — chapter-by-chapter distilled guidance.
|
|
289
301
|
- `checklists/daily-ui-review.md` — fast audit and ship checklist.
|
|
290
302
|
- `examples/review-template.md` — reusable UI critique response structure.
|
|
303
|
+
|
|
304
|
+
## Spur contract
|
|
305
|
+
|
|
306
|
+
Machine-facing adapter for `sp:code-refactoring` dispatch (feature H13). Everything above is the
|
|
307
|
+
lens's native output and is unchanged; this section only maps it to the shared finding schema.
|
|
308
|
+
|
|
309
|
+
**Inputs received:** a scope path, an optional change description, and the `ui` focus. Read
|
|
310
|
+
first: the refactoring protocol and output contract above, then
|
|
311
|
+
`../code-refactoring/references/finding-schema.md` for shared field semantics.
|
|
312
|
+
|
|
313
|
+
**Native finding → schema mapping:** each issue → `id` as `RF-ui-<nnn>`; the pass that owns it
|
|
314
|
+
(hierarchy, spacing, typography, color, states) → `rung`; `Observation` + `Refactor` → `title`
|
|
315
|
+
and `proposal` (imperative); the cited component/file and line → `evidence` as `{file, line}`
|
|
316
|
+
entries inside scope; the `System rule` → folded into `proposal`; new findings start at
|
|
317
|
+
`status: open`.
|
|
318
|
+
|
|
319
|
+
**Severity mapping (design §5):** native P0 (task failure) → `P1`; P1 (hierarchy/structure) →
|
|
320
|
+
`P2`; P2 (system inconsistency) → `P3`; P3 (polish) → `P4`.
|
|
321
|
+
|
|
322
|
+
**Preserved-behavior inventory (required before proposals):** emit the controls and interactions
|
|
323
|
+
in scope — primary/secondary actions, navigation, form semantics, accessible names, states —
|
|
324
|
+
before the first finding.
|
|
325
|
+
|
|
326
|
+
**Preservation class:** token normalization and layout/typography consolidation with identical
|
|
327
|
+
function → `preserving`; adding a missing state or a11y attribute → `preserving`; removing or
|
|
328
|
+
merging a control or interaction → `cutting`; changes to user-visible flows or behavior →
|
|
329
|
+
`breaking`.
|
|
330
|
+
|
|
331
|
+
**Stop rules:** meaning is never carried by color alone; preserve component semantics and
|
|
332
|
+
accessibility; a `cutting`/`breaking` finding is never `fix_eligibility: auto` and never below
|
|
333
|
+
`P2`; anything outside the scope path is not a finding.
|
|
@@ -161,6 +161,11 @@
|
|
|
161
161
|
"options": {
|
|
162
162
|
"type": "object",
|
|
163
163
|
"additionalProperties": true
|
|
164
|
+
},
|
|
165
|
+
"onError": {
|
|
166
|
+
"type": "string",
|
|
167
|
+
"enum": ["fail", "continue"],
|
|
168
|
+
"description": "Per-action error handling policy: 'fail' halts the run; 'continue' logs the failure and proceeds so transition guards can route the outcome."
|
|
164
169
|
}
|
|
165
170
|
}
|
|
166
171
|
},
|