@gobing-ai/spur 0.3.40 → 0.3.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. package/.claude-plugin/marketplace.json +15 -0
  2. package/README.md +15 -1
  3. package/config/templates/AGENTS.md +5 -3
  4. package/config/workflows/task-pipeline.yaml +103 -12
  5. package/package.json +15 -12
  6. package/plugins/README.md +655 -0
  7. package/plugins/sp/README.md +621 -0
  8. package/plugins/sp/agents/expert-spur.md +109 -0
  9. package/plugins/sp/agents/super-coder.md +126 -0
  10. package/plugins/sp/agents/super-planner.md +283 -0
  11. package/plugins/sp/agents/super-reviewer.md +154 -0
  12. package/plugins/sp/commands/dev-arch.md +30 -0
  13. package/plugins/sp/commands/dev-brainstorm.md +40 -0
  14. package/plugins/sp/commands/dev-changelog.md +28 -0
  15. package/plugins/sp/commands/dev-daily.md +29 -0
  16. package/plugins/sp/commands/dev-debug.md +29 -0
  17. package/plugins/sp/commands/dev-dogfood.md +33 -0
  18. package/plugins/sp/commands/dev-featurechange.md +130 -0
  19. package/plugins/sp/commands/dev-find-conflict.md +51 -0
  20. package/plugins/sp/commands/dev-find-issue.md +76 -0
  21. package/plugins/sp/commands/dev-find-next.md +60 -0
  22. package/plugins/sp/commands/dev-fixall.md +33 -0
  23. package/plugins/sp/commands/dev-gitmsg.md +28 -0
  24. package/plugins/sp/commands/dev-gtd.md +97 -0
  25. package/plugins/sp/commands/dev-handover.md +26 -0
  26. package/plugins/sp/commands/dev-idea.md +50 -0
  27. package/plugins/sp/commands/dev-next.md +31 -0
  28. package/plugins/sp/commands/dev-parallel.md +30 -0
  29. package/plugins/sp/commands/dev-plan.md +46 -0
  30. package/plugins/sp/commands/dev-refine.md +48 -0
  31. package/plugins/sp/commands/dev-refineall.md +65 -0
  32. package/plugins/sp/commands/dev-refresh.md +32 -0
  33. package/plugins/sp/commands/dev-reverse.md +32 -0
  34. package/plugins/sp/commands/dev-review.md +31 -0
  35. package/plugins/sp/commands/dev-run.md +63 -0
  36. package/plugins/sp/commands/dev-runall.md +80 -0
  37. package/plugins/sp/commands/dev-simplify.md +39 -0
  38. package/plugins/sp/commands/dev-unit.md +29 -0
  39. package/plugins/sp/commands/dev-verify.md +48 -0
  40. package/plugins/sp/commands/dev-verifyall.md +72 -0
  41. package/plugins/sp/commands/dev-wrap.md +30 -0
  42. package/plugins/sp/commands/dev-wrapall.md +33 -0
  43. package/plugins/sp/commands/rule-add.md +18 -0
  44. package/plugins/sp/commands/rule-refine.md +18 -0
  45. package/plugins/sp/commands/rule-scan.md +18 -0
  46. package/plugins/sp/commands/spur-init.md +22 -0
  47. package/plugins/sp/commands/workflow-add.md +18 -0
  48. package/plugins/sp/commands/workflow-refine.md +18 -0
  49. package/plugins/sp/hooks/agent-hint.ts +60 -0
  50. package/plugins/sp/hooks/careful-guard.ts +147 -0
  51. package/plugins/sp/hooks/context-post-tool.ts +325 -0
  52. package/plugins/sp/hooks/context-session-start.ts +182 -0
  53. package/plugins/sp/hooks/context-session-stop.ts +95 -0
  54. package/plugins/sp/hooks/hooks.json +51 -0
  55. package/plugins/sp/hooks/pi/guard-extension.ts +341 -0
  56. package/plugins/sp/hooks/task-write-guard.ts +84 -0
  57. package/plugins/sp/plugin.json +8 -0
  58. package/plugins/sp/scripts/batch-preflight.ts +204 -0
  59. package/plugins/sp/scripts/daily-summary/daily-summary.ts +606 -0
  60. package/plugins/sp/scripts/daily-summary/logger.ts +28 -0
  61. package/plugins/sp/scripts/dogfood-testing/detect-pipeline-driving.ts +363 -0
  62. package/plugins/sp/scripts/dogfood-testing/validate-report.ts +168 -0
  63. package/plugins/sp/scripts/feature-sync-bounded.ts +451 -0
  64. package/plugins/sp/scripts/stage-registry-adapter.ts +1341 -0
  65. package/plugins/sp/scripts/task-size-precheck.ts +202 -0
  66. package/plugins/sp/scripts/validate-commands.ts +651 -0
  67. package/plugins/sp/scripts/validate-flag-contracts.ts +875 -0
  68. package/plugins/sp/skills/brainstorm/SKILL.md +361 -0
  69. package/plugins/sp/skills/brainstorm/agents/openai.yaml +14 -0
  70. package/plugins/sp/skills/brainstorm/examples/ideation-example.md +209 -0
  71. package/plugins/sp/skills/brainstorm/metadata.openclaw +7 -0
  72. package/plugins/sp/skills/brainstorm/references/grilling-interview.md +68 -0
  73. package/plugins/sp/skills/brainstorm/references/workflows.md +255 -0
  74. package/plugins/sp/skills/branch-workflow/SKILL.md +109 -0
  75. package/plugins/sp/skills/branch-workflow/references/branch-lifecycle.md +69 -0
  76. package/plugins/sp/skills/branch-workflow/references/worktree-patterns.md +100 -0
  77. package/plugins/sp/skills/code-implementation/SKILL.md +176 -0
  78. package/plugins/sp/skills/code-implementation/references/debugging.md +64 -0
  79. package/plugins/sp/skills/code-implementation/references/implementation-patterns.md +113 -0
  80. package/plugins/sp/skills/code-improvement/SKILL.md +231 -0
  81. package/plugins/sp/skills/code-improvement/references/deepening-signals.md +205 -0
  82. package/plugins/sp/skills/code-review/SKILL.md +112 -0
  83. package/plugins/sp/skills/code-review/references/receiving-code-review.md +70 -0
  84. package/plugins/sp/skills/code-review/references/review-lenses.md +117 -0
  85. package/plugins/sp/skills/code-review/references/self-review-checklist.md +53 -0
  86. package/plugins/sp/skills/code-review/references/verification-before-completion.md +68 -0
  87. package/plugins/sp/skills/code-simplification/SKILL.md +225 -0
  88. package/plugins/sp/skills/code-testing/SKILL.md +108 -0
  89. package/plugins/sp/skills/code-testing/references/stacks/bun-ts.md +165 -0
  90. package/plugins/sp/skills/code-testing/references/stacks/go.md +88 -0
  91. package/plugins/sp/skills/code-testing/references/stacks/python.md +117 -0
  92. package/plugins/sp/skills/code-testing/references/test-loop-breaker.md +37 -0
  93. package/plugins/sp/skills/code-testing/references/test-output-discipline.md +52 -0
  94. package/plugins/sp/skills/code-testing/references/unit-testing.md +212 -0
  95. package/plugins/sp/skills/code-verification/SKILL.md +535 -0
  96. package/plugins/sp/skills/code-verification/references/code-improvement.md +39 -0
  97. package/plugins/sp/skills/code-verification/references/secu-review.md +94 -0
  98. package/plugins/sp/skills/code-verification/references/verdict-schema.md +141 -0
  99. package/plugins/sp/skills/conflict-finding/SKILL.md +254 -0
  100. package/plugins/sp/skills/conflict-finding/references/authority-resolution.md +258 -0
  101. package/plugins/sp/skills/conflict-finding/references/comparison-protocol.md +277 -0
  102. package/plugins/sp/skills/conflict-finding/references/finding-contract.md +346 -0
  103. package/plugins/sp/skills/conflict-finding/references/remediation-routing.md +276 -0
  104. package/plugins/sp/skills/daily-summary/SKILL.md +171 -0
  105. package/plugins/sp/skills/daily-summary/agents/openai.yaml +13 -0
  106. package/plugins/sp/skills/doc-evolve/SKILL.md +175 -0
  107. package/plugins/sp/skills/doc-evolve/references/operations.md +93 -0
  108. package/plugins/sp/skills/dogfood-testing/SKILL.md +608 -0
  109. package/plugins/sp/skills/dogfood-testing/references/monitor-ledger.md +211 -0
  110. package/plugins/sp/skills/dogfood-testing/references/report-template.md +351 -0
  111. package/plugins/sp/skills/doubt-driven-development/SKILL.md +136 -0
  112. package/plugins/sp/skills/functional-review/SKILL.md +364 -0
  113. package/plugins/sp/skills/functional-review/references/verdict-schema.md +133 -0
  114. package/plugins/sp/skills/indexed-context/SKILL.md +164 -0
  115. package/plugins/sp/skills/issue-finding/SKILL.md +424 -0
  116. package/plugins/sp/skills/issue-finding/agents/openai.yaml +15 -0
  117. package/plugins/sp/skills/issue-finding/examples/expected-findings.json +27 -0
  118. package/plugins/sp/skills/issue-finding/examples/session-test-loop.jsonl +23 -0
  119. package/plugins/sp/skills/issue-finding/references/session-formats.md +121 -0
  120. package/plugins/sp/skills/next-feature/SKILL.md +125 -0
  121. package/plugins/sp/skills/next-feature/references/handoff-routing.md +92 -0
  122. package/plugins/sp/skills/next-feature/references/proposal-contract.md +49 -0
  123. package/plugins/sp/skills/next-feature/references/ranking-rubric.md +52 -0
  124. package/plugins/sp/skills/next-feature/references/signal-derivation.md +67 -0
  125. package/plugins/sp/skills/next-router/SKILL.md +181 -0
  126. package/plugins/sp/skills/next-router/references/messages.md +90 -0
  127. package/plugins/sp/skills/next-router/references/routing-table.md +216 -0
  128. package/plugins/sp/skills/parallel-execution/SKILL.md +148 -0
  129. package/plugins/sp/skills/parallel-execution/references/dispatch-surface.md +100 -0
  130. package/plugins/sp/skills/parallel-execution/references/fan-out-patterns.md +101 -0
  131. package/plugins/sp/skills/parallel-execution/references/result-synthesis.md +94 -0
  132. package/plugins/sp/skills/reverse-engineering/SKILL.md +375 -0
  133. package/plugins/sp/skills/reverse-engineering/agents/openai.yaml +18 -0
  134. package/plugins/sp/skills/source-driven-development/SKILL.md +124 -0
  135. package/plugins/sp/skills/spec-decomposition/SKILL.md +117 -0
  136. package/plugins/sp/skills/spec-decomposition/references/decomposition.md +539 -0
  137. package/plugins/sp/skills/spur-cli/SKILL.md +133 -0
  138. package/plugins/sp/skills/spur-cli/references/agent.md +179 -0
  139. package/plugins/sp/skills/spur-cli/references/features/acceptance-criteria.md +82 -0
  140. package/plugins/sp/skills/spur-cli/references/features/hierarchy-mece.md +177 -0
  141. package/plugins/sp/skills/spur-cli/references/features/roadmap-priority.md +84 -0
  142. package/plugins/sp/skills/spur-cli/references/features/verbs.md +122 -0
  143. package/plugins/sp/skills/spur-cli/references/features.md +234 -0
  144. package/plugins/sp/skills/spur-cli/references/init.md +119 -0
  145. package/plugins/sp/skills/spur-cli/references/message.md +98 -0
  146. package/plugins/sp/skills/spur-cli/references/rules/authoring-rules.md +212 -0
  147. package/plugins/sp/skills/spur-cli/references/rules/fine-tuning.md +148 -0
  148. package/plugins/sp/skills/spur-cli/references/rules/operations.md +228 -0
  149. package/plugins/sp/skills/spur-cli/references/rules/validation-and-extension.md +129 -0
  150. package/plugins/sp/skills/spur-cli/references/rules.md +209 -0
  151. package/plugins/sp/skills/spur-cli/references/serve.md +58 -0
  152. package/plugins/sp/skills/spur-cli/references/tasks/l3-guard-cheatsheet.md +98 -0
  153. package/plugins/sp/skills/spur-cli/references/tasks/section-editing.md +95 -0
  154. package/plugins/sp/skills/spur-cli/references/tasks/verbs.md +361 -0
  155. package/plugins/sp/skills/spur-cli/references/tasks.md +278 -0
  156. package/plugins/sp/skills/spur-cli/references/team.md +133 -0
  157. package/plugins/sp/skills/spur-cli/references/workflows/authoring-workflows.md +226 -0
  158. package/plugins/sp/skills/spur-cli/references/workflows/operations.md +211 -0
  159. package/plugins/sp/skills/spur-cli/references/workflows/validation-and-extension.md +129 -0
  160. package/plugins/sp/skills/spur-cli/references/workflows.md +355 -0
  161. package/plugins/sp/skills/spur-dev/SKILL.md +224 -0
  162. package/plugins/sp/skills/spur-dev/references/ac-style-guide.md +196 -0
  163. package/plugins/sp/skills/spur-dev/references/cross-cutting.md +664 -0
  164. package/plugins/sp/skills/spur-dev/references/decision-brief.md +80 -0
  165. package/plugins/sp/skills/spur-dev/references/dev-operations.md +546 -0
  166. package/plugins/sp/skills/spur-dev/references/done-housekeeping.md +164 -0
  167. package/plugins/sp/skills/spur-dev/references/execution-batch.md +727 -0
  168. package/plugins/sp/skills/spur-dev/references/execution-workflow.md +350 -0
  169. package/plugins/sp/skills/spur-dev/references/feature-link-helper.md +191 -0
  170. package/plugins/sp/skills/spur-dev/references/flag-glossary.md +417 -0
  171. package/plugins/sp/skills/spur-dev/references/gate-checklists.md +171 -0
  172. package/plugins/sp/skills/spur-dev/references/glossary.md +95 -0
  173. package/plugins/sp/skills/spur-dev/references/idea-evaluation.md +80 -0
  174. package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +88 -0
  175. package/plugins/sp/skills/spur-dev/references/planning-workflow.md +302 -0
  176. package/plugins/sp/skills/spur-dev/references/product-planning.md +206 -0
  177. package/plugins/sp/skills/spur-dev/references/section-batching.md +24 -0
  178. package/plugins/sp/skills/sys-architecture/SKILL.md +155 -0
  179. package/plugins/sp/skills/sys-architecture/references/decision-method.md +137 -0
  180. package/plugins/sp/skills/sys-architecture/references/upkeep-survey.md +75 -0
  181. package/plugins/sp/skills/sys-debugging/SKILL.md +228 -0
  182. package/plugins/sp/skills/sys-debugging/references/debugging-protocol.md +62 -0
  183. package/plugins/sp/skills/test-driven-development/SKILL.md +248 -0
  184. package/plugins/sp/skills/wayfinder/SKILL.md +292 -0
  185. package/spur.js +6093 -5180
@@ -0,0 +1,129 @@
1
+ ---
2
+ name: validation-and-extension
3
+ description: Validate rule files and presets, extend the engine with custom evaluators/resolvers/formatters, and the CLI-vs-library capability gaps.
4
+ see_also:
5
+ - spur-cli
6
+ ---
7
+
8
+ # Validation & Extension
9
+
10
+ ## Validating before you trust
11
+
12
+ `spur rule validate` checks a rule file or preset (schema + Zod) without evaluating it. Always
13
+ validate a rule you authored or edited before wiring it into a gate.
14
+
15
+ ```bash
16
+ spur rule validate .spur/rules/typescript/no-debugger.yaml --json # validate a file
17
+ spur rule validate --preset strict-check --json # validate a preset
18
+ spur rule validate <path> --no-schema --json # skip $schema ref, Zod only
19
+ ```
20
+
21
+ What it catches:
22
+
23
+ - **Schema errors** — the file violates `rule-file.schema.json` / `preset.schema.json` (e.g. unknown
24
+ key, wrong type). The quoted `$schema` ref is resolved from the bundled package — no network.
25
+ - **Zod errors** — internal validation (e.g. a regex `config` missing `pattern`, an invalid
26
+ severity, a preset `override` targeting a non-existent rule ID).
27
+
28
+ A preset validation also surfaces broken `extends` references (a category folder that doesn't exist)
29
+ and invalid `overrides`/`disable` targets.
30
+
31
+ **`$schema` quoting gotcha:** the value starts with `@`, which YAML treats as reserved. It must be
32
+ quoted: `$schema: "@gobing-ai/ts-rule-engine/schemas/rule-file.schema.json"`. An unquoted value is a
33
+ parse error.
34
+
35
+ ### Meta-rules: validating the catalog itself
36
+
37
+ Beyond per-file validation, rules can validate the *rule catalog*. Spur ships two:
38
+
39
+ - `rg-evaluator-patterns-are-ripgrep-dialect` (`rg-migration` preset) — fails if any `type: rg` rule
40
+ uses lookbehind/backreferences ripgrep can't compile.
41
+ - `strict/rule-files-structural` — structural integrity of the rule YAML files.
42
+
43
+ Run them as a second-order gate after editing rules:
44
+
45
+ ```bash
46
+ spur rule run --preset rg-migration --fail-on error --json
47
+ ```
48
+
49
+ ## Extending the engine
50
+
51
+ The built-in evaluators cover most needs. When they don't, the library (`@gobing-ai/ts-rule-engine`)
52
+ supports four extension kinds: **resolvers**, **evaluators**, **fixers** (since 0.3.4), and **formatters**.
53
+ Fixer extensions may be loaded from a preset or rule file via the `extensions.fixers` block (gated by
54
+ `allowExtensions`). The other kinds are library-level APIs consumed by code that drives `RuleEngine`
55
+ directly, or by `ts-rule-engine` gaining capabilities upstream.
56
+
57
+ ### Custom evaluator (direct API)
58
+
59
+ For a check no built-in expresses, register a `RuleEvaluator`:
60
+
61
+ ```ts
62
+ import { RuleEngine, createFinding, type RuleEvaluator } from "@gobing-ai/ts-rule-engine";
63
+
64
+ const evaluator: RuleEvaluator = {
65
+ async evaluate(rule, context) {
66
+ if (!context.workdir.includes("service")) {
67
+ return { findings: [createFinding(rule, 'workdir must include "service"', null, { code: "custom:not-service" })], fixes: [] };
68
+ }
69
+ return { findings: [], fixes: [] };
70
+ },
71
+ };
72
+
73
+ const engine = new RuleEngine();
74
+ engine.registerEvaluator("workspace-name", evaluator);
75
+ ```
76
+
77
+ Then a rule references it by `evaluator.type: workspace-name`.
78
+
79
+ ### Preset extensions (declared modules)
80
+
81
+ A preset can declare extension modules. They are **trust-gated**: disabled unless the caller passes
82
+ `allowExtensions: true` to `loadExtensionsIntoHost()`. Without the flag, loading throws — untrusted
83
+ presets cannot silently register code.
84
+
85
+ ```yaml
86
+ # preset.yaml
87
+ extensions:
88
+ resolvers: ["./extensions/custom-resolver.ts"] # source→test path mapping
89
+ evaluators: ["./extensions/custom-evaluator.ts"] # new rule type
90
+ formatters: ["./extensions/compact-formatter.ts"] # output rendering
91
+ ```
92
+
93
+ ```ts
94
+ const loaded = await loadPreset("local", { roots: [".spur/rules"] });
95
+ const engine = new RuleEngine();
96
+ await loadExtensionsIntoHost(engine.host, loaded.extensions, { allowExtensions: true });
97
+ const result = await engine.evaluate(loaded.rules, process.cwd());
98
+ ```
99
+
100
+ Each registered capability is origin-tracked (`builtin`/`extension`/`caller`) so an extension cannot
101
+ silently override a built-in — conflicts are surfaced, not swallowed.
102
+
103
+ ### Custom resolvers and formatters
104
+
105
+ - **Resolver** — maps a source path to its expected test path for `test-location`. Built-ins:
106
+ `typescript`, `python`, `go`, `rust`. Author one for non-standard monorepo conventions
107
+ (`{ name, resolveTestPath(srcRelPath) }`).
108
+ - **Formatter** — renders a `RuleEngineResult` (`{ name, format(result) }`). For team-specific or
109
+ compact output beyond the built-in `TextFormatter`/`JsonFormatter`.
110
+
111
+ ## Capability gaps (be honest about these)
112
+
113
+ The library can do more than the CLI currently exposes. When you hit a wall, the gap type tells you
114
+ the fix path:
115
+
116
+ | Capability | In library? | On `spur rule` CLI? | Fix path |
117
+ | ---------- | ----------- | ------------------- | -------- |
118
+ | Apply fixes (`applyFixes`) | Yes | **Yes** — `--fix-mode auto` applies fixes; `--fix-mode auto --dry-run` previews the diff | Task 0027. Surfaces `evaluateWithFixes` + `applyFixes` from `ts-rule-engine`. |
119
+ | Fix authority `none`/`suggest`/`auto` | Yes (`min(rule, caller)`) | **Yes** — `--fix-mode none\|suggest\|auto` | Task 0027. Maps 1:1 to library `maxFixMode`. |
120
+ | Custom evaluators/resolvers/formatters | Yes (`allowExtensions`) | **No** loading flag | Drive `RuleEngine` from code, or add upstream CLI support. |
121
+ | `EventBus` observability (`rule.*` events, `durationMs`) | Yes | **No** | Library-only; for progress bars/dashboards. |
122
+ | Custom **fixer** providers | **Yes** (`extensions` includes `fixers` since `ts-rule-engine@0.3.4`) | **Yes** (loads via preset or rule-file `extensions.fixers` with `allowExtensions`) | Task 0027 (catalog bump to 0.3.4). Upstream: ts-libs 0023 moved fixers onto the host registry. |
123
+ | FP/FN rate tracking | **No** | No | Tool gap. Convention: track in YAML comments. |
124
+ | Rule-ID rename migration | **No** | No | Tool gap. Don't rename IDs. |
125
+
126
+ **Per project policy:** when `ts-rule-engine` can't support a Spur need cleanly, prefer enhancing the
127
+ shared package upstream over leaking a workaround into Spur. The remaining gaps above (custom
128
+ evaluator loading via CLI flag, `EventBus` observability, FP/FN tracking, rule-ID migration) are
129
+ `ts-rule-engine` evolution candidates or future CLI surface growth.
@@ -0,0 +1,209 @@
1
+ ---
2
+ name: spur-cli-rules
3
+ description: "spur-cli noun reference: operate `spur rule` as the project's constraint quality gate across its full lifecycle — run presets, author rules, fine-tune for delivery quality, validate rule files and preset schemas, and extend the engine. The deterministic verifier in the LLM code-delivery loop."
4
+ see_also:
5
+ - spur-cli
6
+ ---
7
+
8
+ # spur rule — the constraint quality gate
9
+
10
+ `spur rule` runs declarative YAML constraint rules (powered by `@gobing-ai/ts-rule-engine`) over the
11
+ working tree and reports policy violations. It is the **deterministic verifier** in an LLM delivery
12
+ loop: a coding agent is overconfident, the rule engine is not. Putting the deterministic check inside
13
+ the agent's loop catches forbidden patterns, missing tests, leaked secrets, broken import boundaries,
14
+ and coverage regressions that the agent would otherwise confidently ship.
15
+
16
+ Operating the gate well is a full lifecycle — not just running it. This skill covers all of it.
17
+
18
+ ## Lifecycle map
19
+
20
+ | Phase | Activity | Where |
21
+ | ----- | -------- | ----- |
22
+ | **Run & fix** | Gate the diff, interpret findings, self-correct, re-run until green | this file |
23
+ | **Author** | Add a constraint by writing a new rule when a standard/anti-pattern emerges | [rules/authoring-rules.md](rules/authoring-rules.md) |
24
+ | **Fine-tune** | Dial in quality: severity, glob scoping, exemptions, preset `disable`/`overrides`, layering | [rules/fine-tuning.md](rules/fine-tuning.md) |
25
+ | **Validate & extend** | Validate files/presets, smoke-test, add custom evaluators/resolvers/formatters | [rules/validation-and-extension.md](rules/validation-and-extension.md) |
26
+
27
+ ## When to use
28
+
29
+ Use this skill to:
30
+
31
+ - **Gate generated code** — run a preset over changes before declaring a task done or committing.
32
+ - **Add a constraint** — codify a new rule (forbidden pattern, import boundary, required test,
33
+ coverage floor) so the gate enforces it forever. → authoring-rules.md
34
+ - **Fine-tune delivery quality** — adjust severity, scope a rule to kill false positives, exempt a
35
+ legitimate case, or re-tune an inherited rule via preset `overrides`. → fine-tuning.md
36
+ - **Validate before trusting** — schema/Zod-check a rule file or preset; smoke-test a new rule
37
+ against known-good/known-bad files. → validation-and-extension.md
38
+ - **Extend the engine** — write a custom evaluator/resolver/formatter when built-ins fall short.
39
+ → validation-and-extension.md
40
+ - **Interpret a failing gate** — turn `ERROR <rule-id> <file>:<line>` into the exact fix, re-run.
41
+
42
+ ## Operations
43
+
44
+ The skill's logic divides by **whether the LLM adds value**:
45
+
46
+ - **Direct CLI** (`run`, `validate`, `list`) — deterministic, single-verb commands. Run them
47
+ straight: `spur rule run`, `spur rule validate`, `spur rule list`. A slash-command wrapper here
48
+ would only forward flags and add drift; **there is no command for these — use the CLI**. The skill
49
+ still drives them when asked in natural language (e.g. interpreting findings, the fix loop below).
50
+ - **Agent-driven** (`scan`, `add`, `refine`) — convert fuzzy human intent into a reliable sequence the
51
+ CLI cannot express as one verb. `scan` discovers candidate rules; `add`/`refine` author and tune
52
+ them. These are the operations worth a slash command, and the skill owns all their logic. Full
53
+ procedures: [rules/operations.md](rules/operations.md).
54
+
55
+ | Operation | Backed by | Input | Output (done-when) |
56
+ | --------- | --------- | ----- | ------------------ |
57
+ | `run` | `spur rule run` (CLI) | `[--preset <name>] [--rule <id>] [--file <path>] [--fail-on <sev>] [--stop-on-first [<sev>]] [--fix-mode none\|suggest\|auto] [--dry-run] [--verbose]` | Gate to exit 0; findings interpreted, code fixed, re-run clean (the harness loop below) |
58
+ | `validate` | `spur rule validate` (CLI) | `[file-or-preset] [--file <path>] [--preset <name>] [--kind file\|preset] [--no-schema]` | Schema + Zod verdict |
59
+ | `list` | `spur rule list` (CLI) | `[--preset <name>]` | Discovered files + source layer, or resolved rules for a preset |
60
+ | `trace` | `spur rule trace` (CLI) | `[run-id] [--preset <name>] [--status done\|failed] [--since <iso>] [--last <n>]` | Persisted rule-run history / per-run detail |
61
+ | `scan` | agent procedure | `[<path-or-glob>]` | **Propose-only** discovery: surveys code for recurring anti-patterns, clusters them, filters against the catalog, and reports ranked rule candidates (`add` new / `refine`-extend / already-covered). Authors nothing → [scan](rules/operations.md#scan) |
62
+ | `add` | agent procedure | `"<nl-description>" [--file <path>] [--preset <target>]` | **First reconciles against the existing catalog** (extend/refine an existing rule rather than duplicate, on confirmation); only a genuinely new concern is authored, then **validated AND smoke-tested both directions** (fires on bad, quiet on good); optionally wired into a preset → [add](rules/operations.md#add) |
63
+ | `refine` | agent procedure | `<rule-file-or-preset> [--intent "<goal>"] [--severity <sev>] [--scope <glob>] [--exempt <path>] [--disable <id>] [--override <id>] [--dry-run]` | Smallest change meeting the intent, re-validated and re-smoke-tested; `--dry-run` emits a diff only → [refine](rules/operations.md#refine) |
64
+
65
+ `scan`, `add`, and `refine` are not CLI verbs. `add`/`refine` compose `validate` + `run` around a
66
+ generated/edited YAML rule and both end in the same **validate-and-smoke-test** core
67
+ ([operations.md](rules/operations.md#sub-procedure-validate-and-smoke-test)) so a tightened rule
68
+ is verified exactly like an authored one. They also share the **find-existing-coverage** core
69
+ ([operations.md](rules/operations.md#sub-procedure-find-existing-coverage)): `add` runs it up
70
+ front (don't duplicate), `refine` runs it to locate a target and to catch overlap after a widening,
71
+ and `scan` runs it to filter candidates against the catalog. Behavioral rule-testing (does a rule fire
72
+ correctly?) is not a standalone operation — it **is** the verify core, invoked by `add` and `refine`.
73
+
74
+ ## The harness loop (run → interpret → fix → re-run)
75
+
76
+ ```
77
+ generate / edit code
78
+
79
+
80
+ spur rule run --preset recommended-pre-check --json ← deterministic gate
81
+
82
+ exit 0? ──yes──▶ proceed to tests / commit
83
+ │ no
84
+
85
+ parse findings[] → apply the SPECIFIC fix per finding → re-run
86
+
87
+ └──────────── loop until exit 0 ◀──────────────
88
+ ```
89
+
90
+ Two signals, two purposes: the **exit code** is the binary pass/fail (the gate); the **`findings[]`**
91
+ carry the actionable detail (what to fix). Always use `--json` when an agent consumes the result.
92
+
93
+ ### Step 1: Run
94
+
95
+ ```bash
96
+ spur rule run --json # fast inner-loop (default preset)
97
+ spur rule run --preset recommended-pre-check --fail-on error --json
98
+ spur rule run --preset recommended-post-check --fail-on error --json # final gate (after tests)
99
+ ```
100
+
101
+ `spur rule run` exits non-zero when a finding meets `--fail-on` (default `error`). A non-zero exit
102
+ means **not done**. `--stop-on-first error` fails fast while iterating; drop it for the final pass to
103
+ surface every violation.
104
+
105
+ ### Step 2: Interpret
106
+
107
+ Each finding has `ruleId`, `severity`, `message`, `filePath`, optional `line`, and `code`. Two kinds:
108
+
109
+ - **Policy violation** — code broke a rule. Fix the code.
110
+ - **Evaluator error** (`kind: "error"`, `code: "evaluator:<type>"`, `filePath: null`) — the rule
111
+ crashed (missing `rg`/`sg`/`lcov.info`, or a bad pattern). Fix the rule or the environment, **not**
112
+ the code. This distinction is first-class — never edit source to silence a broken rule.
113
+
114
+ Full JSON schema and field nuances (e.g. `line` is present on forbid-matches, absent on
115
+ require-misses): [rules/authoring-rules.md](rules/authoring-rules.md).
116
+
117
+ ### Step 3: Fix and re-run
118
+
119
+ Fix the *specific* violation the finding names — no drive-by refactors — then re-run the same
120
+ command. By default, `spur rule run` surfaces findings only; the agent makes the edit and re-runs.
121
+ Loop until exit 0.
122
+
123
+ **`--fix-mode` shortcut:** when the violation is mechanically fixable (e.g. a regex replacement),
124
+ `spur rule run --fix-mode auto` applies the fix and reports the result. The exit code still reflects
125
+ the *findings* (not whether fixes were applied), so re-run to confirm green. `--fix-mode suggest`
126
+ surfaces candidate fixes in `--json` output without writing.
127
+
128
+ ## Command surface
129
+
130
+ ```
131
+ spur rule run [--preset <name>] [--file <path>] [--rule <id>] [--fail-on <sev>] [--stop-on-first [<sev>]] [--fix-mode <none|suggest|auto>] [--dry-run] [--verbose] [--json]
132
+ spur rule validate [file-or-preset] [--file <path>] [--preset <name>] [--kind file|preset] [--no-schema] [--json]
133
+ spur rule list [--preset <name>] [--json]
134
+ spur rule trace [run-id] [--preset <name>] [--status done|failed] [--since <iso-date>] [--last <n>] [--json]
135
+ ```
136
+
137
+ Default preset is `recommended-pre-check`. `--fail-on`/`--stop-on-first` take `error|warning|info`.
138
+ List what is actually enforced before assuming — presets are layered (project shadows bundled):
139
+
140
+ ```bash
141
+ spur rule list --json # discovered files + source layer
142
+ spur rule list --preset recommended-pre-check --json # resolved rules for one preset
143
+ spur rule trace --last 10 --json # recent rule runs
144
+ spur rule trace <run-id> --json # per-run detail
145
+ ```
146
+
147
+ Repo presets: `recommended-pre-check` (inner loop), `recommended-post-check` (final, adds coverage),
148
+ `strict-check` (hardened boundaries), `rg-migration` (ripgrep-dialect guard). Rationale for the
149
+ ordering and how to compose a new preset: [rules/fine-tuning.md](rules/fine-tuning.md).
150
+
151
+ ## Behavior
152
+
153
+ This skill behaves as a **reviewer** (apply a deterministic rule set, return ranked findings) feeding
154
+ a **pipeline** (gate → interpret → fix → re-run until green). It also covers authoring/tuning the
155
+ rules the reviewer applies. It does not generate feature code; it constrains code another agent wrote.
156
+
157
+ ## Gotchas
158
+
159
+ 1. **Exit code is the source of truth, not the printed text.** A clean-looking run still exits
160
+ non-zero if a finding meets `--fail-on`. Check the exit code / `--json` summary before claiming
161
+ the gate passed.
162
+ 2. **Evaluator errors are not policy violations.** `code: "evaluator:<type>"` + `filePath: null`
163
+ means a tool is missing or the rule is misconfigured — fix the rule/environment, not the source.
164
+ 3. **Don't game the gate.** An LLM will try the cheapest path to "passed": adding `biome-ignore`,
165
+ deleting a test, lowering `--fail-on`, or excluding the offending file. Each defeats the harness.
166
+ The `no-biome-suppressions` meta-rule exists specifically to catch suppression-to-pass. Fix root
167
+ causes.
168
+ 4. **`rg` uses ripgrep dialect — no lookbehind/backreferences.** A `type: rg` rule with `(?<=...)`
169
+ or `\1` won't compile. Keep it on `type: regex`, or run the `rg-migration` preset to catch it.
170
+ `isRipgrepCompatiblePattern()` (library export) checks a pattern before promotion.
171
+ 5. **`line` is optional on findings.** Present on forbid-matches, absent on require-misses. Don't
172
+ assume every finding has a location; locate by `filePath` + `message`.
173
+ 6. **Real config shapes differ from the README's simplified examples.** `forbidden-import` uses
174
+ `forbidden: [{specifier}]` + `scope`; `coverage-gate` uses `include`/`exclude` globs. Copy from
175
+ `.spur/rules/` or authoring-rules.md, not from a half-remembered snippet.
176
+ 7. **`$schema` must be quoted** — it starts with `@`, which YAML reserves. Unquoted is a parse error.
177
+ 8. **Presets are layered.** A surprising finding may come from a shadowing project rule. Run
178
+ `spur rule list --preset <name>` to see the resolved set and its source layer.
179
+
180
+ ## Additional Resources
181
+
182
+ - [rules/operations.md](rules/operations.md) — the operation procedures
183
+ (run/scan/add/refine/validate/list), the shared find-existing-coverage and validate-and-smoke-test
184
+ cores, and the fixture convention. The entry point for slash-command delegation.
185
+ - [rules/authoring-rules.md](rules/authoring-rules.md) — add constraints: evaluator
186
+ selection, real config shapes, the JSON finding schema, smoke-testing a new rule.
187
+ - [rules/fine-tuning.md](rules/fine-tuning.md) — dial in quality: severity, glob scoping,
188
+ exemptions, preset `extends`/`disable`/`overrides`, layering, governance.
189
+ - [rules/validation-and-extension.md](rules/validation-and-extension.md) — validate files
190
+ and presets, custom evaluators/resolvers/formatters, and the CLI-vs-library capability gaps.
191
+ - `@gobing-ai/ts-rule-engine` README — authoritative library reference (every evaluator, fixer,
192
+ preset mechanism, observability event).
193
+ - `.spur/rules/` — this repo's live rule catalog; copy real config shapes from here.
194
+
195
+ ## Platform Notes
196
+
197
+ ### Claude Code
198
+ Run `spur rule` via the Bash tool. During development the CLI entry is a `.ts` file that runs only
199
+ under Bun: `bun run apps/cli/src/index.ts rule run --json`. The installed `spur` binary works once
200
+ built.
201
+
202
+ ### Codex / OpenClaw / OpenCode / Antigravity
203
+ Run `spur rule ...` via the Bash tool; parse `--json` output programmatically. Arguments are passed
204
+ directly on the command line.
205
+
206
+ ---
207
+
208
+ **Template type**: technique
209
+ **Purpose**: Operate `spur rule` across its full lifecycle as the deterministic constraint gate in LLM code delivery
@@ -0,0 +1,58 @@
1
+ ---
2
+ name: spur-cli-serve
3
+ description: "spur-cli noun reference: operate `spur serve` as the local web-server fallback - start the Hono/Cloudflare-Worker server that backs the web Task Kanban and the team supervisor API. Single verb, five flags."
4
+ see_also:
5
+ - spur-cli
6
+ ---
7
+
8
+ # spur serve - local web server
9
+
10
+ `spur serve` starts the **Spur web server** - a local Hono / Cloudflare-Worker server that serves
11
+ the web Task Kanban and exposes the team supervisor API (`/api/team/*`). It is the local fallback
12
+ when no remote server is configured.
13
+
14
+ ## Verb map
15
+
16
+ | Verb | Purpose | Key flags |
17
+ | ---- | ------- | --------- |
18
+ | `serve` | Start the Spur web server (local fallback) | `--port <n>` `--host <addr>` `--no-open` `--cwd <path>` `--json` |
19
+
20
+ **Exit codes:** `0` success, `1` error.
21
+
22
+ ## `serve` - start the web server
23
+
24
+ ```bash
25
+ spur serve # default: localhost:3000, opens browser
26
+ spur serve --port 8080 --host 0.0.0.0
27
+ spur serve --no-open # skip browser
28
+ spur serve --json # dry probe: print { port, url, pid, running } and exit
29
+ ```
30
+
31
+ Starts the server with the Hono app backed by the local SQLite database. The web Task Kanban and
32
+ the team supervisor API become available at `http://<host>:<port>`.
33
+
34
+ ### Flags
35
+
36
+ | Flag | Purpose |
37
+ |------|---------|
38
+ | `--port <n>` | Server port (env: `PORT`, default: `3000`). |
39
+ | `--host <addr>` | Bind address (env: `HOST`, default: `localhost`). |
40
+ | `--no-open` | Skip opening the browser (default: opens). |
41
+ | `--cwd <path>` | Working directory (default: current directory). |
42
+ | `--json` | Dry machine-readable probe: print `{ port, url, pid, running }` and exit. No server is started. |
43
+
44
+ `--json` is a **dry probe** - it reports the resolved port/url without starting the server
45
+ (`running: false`, `pid: null`). Use it to check what *would* start, not to launch.
46
+
47
+ ## What this skill is NOT
48
+
49
+ - **Not the team supervisor.** `spur serve` hosts the supervisor API; `spur team start` / `stop` /
50
+ `status` are the verbs that drive it. See **[team.md](team.md)**.
51
+ - **Not a production server.** This is the local fallback. Production deployment uses the Cloudflare
52
+ Worker build (`apps/server/`), not `spur serve`.
53
+
54
+ ## See also
55
+
56
+ - **`spur team` (see [team.md](team.md))** - `start`/`stop`/`status` require `spur serve` for the
57
+ supervisor API.
58
+ - **`sp:spur-cli`** SKILL.md - the facade that routes to this reference.
@@ -0,0 +1,98 @@
1
+ ---
2
+ name: task-l3-guard-cheatsheet
3
+ description: First-write formats for task lifecycle transitions, Solution citations, Review findings, verdict artifacts, and canonical sections.
4
+ see_also:
5
+ - spur-cli
6
+ - task-section-editing
7
+ ---
8
+
9
+ # Task L3 guard cheat sheet
10
+
11
+ Read this before writing `Solution`, `Testing`, or `Review`. The owning implementations are
12
+ `.spur/workflows/task-lifecycle.yaml`, `hasPopulatedPriorityTable()` in
13
+ `packages/app/src/services/task-check.ts`, the verdict normalizers in
14
+ `packages/app/src/services/task-record.ts`, and `TASK_CANONICAL_SECTIONS` in
15
+ `packages/domain/src/planning/markdown-document.ts`.
16
+
17
+ ## Lifecycle graph
18
+
19
+ ```text
20
+ backlog → todo → wip → testing → done
21
+ ↕ ↕
22
+ blocked ←→
23
+
24
+ done → wip
25
+ backlog|todo|wip|testing|blocked → cancelled
26
+ ```
27
+
28
+ - `wip → testing` runs `spur task check <wbs>`.
29
+ - `testing → done` runs `spur task check <wbs> --strict-core`, followed by the PASS-verdict gate.
30
+ - Invalid: `todo → testing`, `todo → done`, and `wip → done`.
31
+ - Normal path: `backlog → todo → wip → testing → done`.
32
+
33
+ ## Solution: `file:line`
34
+
35
+ The body needs at least one real citation with a filename or repository-relative path:
36
+
37
+ ```markdown
38
+ | Change | Evidence |
39
+ | --- | --- |
40
+ | Preserve activity during roster failure | `apps/web/src/modules/teams/SupervisorTab.tsx:218` |
41
+ ```
42
+
43
+ - Correct: `SupervisorTab.tsx:218`, `apps/web/src/modules/teams/SupervisorTab.tsx:218`.
44
+ - Wrong: `:218`, `line 218`, or a filename with no line.
45
+ - Re-read after formatting so the anchor is current.
46
+
47
+ ## Review: populated P1–P4 table
48
+
49
+ `hasPopulatedPriorityTable()` requires a markdown row containing an exact `P1`, `P2`, `P3`, or
50
+ `P4` cell plus non-placeholder content:
51
+
52
+ ```markdown
53
+ | Priority | Finding | File:Line | Disposition |
54
+ | --- | --- | --- | --- |
55
+ | P2 | Missing null guard | `src/foo.ts:42` | Fixed |
56
+ ```
57
+
58
+ Prose-only reviews and rows containing only empty/placeholder cells do not pass.
59
+
60
+ ## Verdict artifact
61
+
62
+ `.spur/run/<wbs>-verdict.json` uses arrays of normalized records:
63
+
64
+ ```json
65
+ {
66
+ "wbs": "0379",
67
+ "verdict": "PASS",
68
+ "requirements": [
69
+ { "id": "R1", "status": "MET", "evidence": "plugins/sp/skills/code-testing/SKILL.md:55" }
70
+ ],
71
+ "acceptanceCriteria": [
72
+ {
73
+ "id": "AC-1",
74
+ "status": "MET",
75
+ "evidenceType": "test",
76
+ "evidence": "bun test plugins/sp/tests: exit 0"
77
+ }
78
+ ],
79
+ "checks": [
80
+ { "name": "lint-clean", "status": "pass", "evidence": "bun run lint: exit 0" }
81
+ ],
82
+ "source": "spur-task-verdict"
83
+ }
84
+ ```
85
+
86
+ - `requirements[]`: `{ id, status, evidence }`.
87
+ - `acceptanceCriteria[]`: `{ id, status, evidenceType, evidence }`.
88
+ - `checks[]`: `{ name, status, evidence }`.
89
+ - `verdict`: `PASS`, `PARTIAL`, `FAIL`, or `UNKNOWN`.
90
+ - Use `spur task verdict`/`spur task record` when a verify answer exists.
91
+
92
+ ## Canonical section names
93
+
94
+ `Background`, `Requirements`, `Acceptance Criteria`, `Q&A`, `Design`, `Plan`, `Solution`,
95
+ `Root Cause`, `Testing`, `Review`, `References`, `History`, `Notes`.
96
+
97
+ `Verdict` is not a section. `Root Cause` is valid only for variants/statuses whose section matrix
98
+ allows it. Use `spur task sections <wbs> list --json` before adding an optional section.
@@ -0,0 +1,95 @@
1
+ ---
2
+ name: task-section-editing
3
+ description: The temp-file → --section/--from-file recipe for editing task sections, when to use record instead, and which sections to fill when.
4
+ see_also:
5
+ - spur-cli
6
+ ---
7
+
8
+ # Editing task sections
9
+
10
+ Task bodies are edited section-by-section through `spur task update --section <name> --from-file
11
+ <path>`. The write is **file-wins and crash-safe** (atomic write): the named section's body is
12
+ replaced wholesale from the file you point at. There is no inline-body flag — always stage the new
13
+ body in a file first.
14
+
15
+ For **pipeline output** (`Testing` / `Review` / safety-net `Solution`), prefer `spur task record`
16
+ over hand-assembling files — it renders the matrix-compliant tables from a verify verdict for you.
17
+ Use the manual recipe below for `Plan`, `Acceptance Criteria`, hand-authored `Solution`, and any
18
+ narrative section.
19
+
20
+ ## The recipe
21
+
22
+ 1. **Assemble the full section body** in a temp file. The body is everything *under* the `###`
23
+ heading — do not include the heading line itself; the CLI owns the heading.
24
+
25
+ ```bash
26
+ cat > /tmp/review.md <<'EOF'
27
+ **Verdict: PASS**
28
+
29
+ | # | Finding | Dim | Location | P | Disposition |
30
+ |---|---------|-----|----------|---|-------------|
31
+ | 1 | … | Correctness | src/foo.ts:42 | P2 | FIXED |
32
+ EOF
33
+ ```
34
+
35
+ 2. **Replace the section:**
36
+
37
+ ```bash
38
+ spur task update 0040 --section Review --from-file /tmp/review.md
39
+ ```
40
+
41
+ 3. The whole `### Review` body is now that file's contents. To amend rather than overwrite, read
42
+ the current body (`spur task show 0040`), edit the temp file to the full desired state, and
43
+ replace again — there is no append mode.
44
+
45
+ `--section` **requires** `--from-file` (exit `2` otherwise). Section names match the DD-08 headings
46
+ exactly: `Background`, `Requirements`, `Acceptance Criteria`, `Q&A`, `Design`, `Plan`, `Solution`, `Root Cause`, `Testing`, `Review`, `References`, `History`, `Notes` (universal sections are `History`, `References`, `Notes`; `Root Cause` is carried by the `issue` template variant).
47
+
48
+ ## `record` vs. hand-editing
49
+
50
+ `spur task record 0040 --transition testing` reads `.spur/run/0040-verdict.json` and writes both
51
+ `Testing` (per-requirement table) and `Review` (P1–P4 findings table) in the matrix-required shape,
52
+ optionally backfilling a bare `Solution` from `git diff -U0`. It never transitions to `done`.
53
+
54
+ - **Use `record`** when a verify step produced a verdict artifact — it is the pipeline's record step.
55
+ - **Use `update --section`** when you are authoring a section by hand (planning, design, narrative
56
+ solution) or amending one `record` already wrote.
57
+
58
+ The two are interchangeable on the same section: `record` writes `Review`, a later
59
+ `update --section Review` overwrites it. Both go through the same file-wins atomic write.
60
+
61
+ ## Which section, when
62
+
63
+ During a pipeline run the sections fill in roughly this order — but *what* goes in each is the
64
+ LLM's job (orchestrated by `sp:spur-dev`); this skill only owns the *mechanism*:
65
+
66
+ | Section | Filled | Holds |
67
+ | ------- | ------ | ----- |
68
+ | `Background` | at create (derived from feature `Goal` if `--feature`) | why this task exists |
69
+ | `Acceptance Criteria` | planning (present at `todo` for spec'd tasks) | the scenarios this task satisfies (matched to feature AC by title) |
70
+ | `Plan` | before `wip` | the step list |
71
+ | `Solution` | during impl (first appears at `wip`) | the approach actually taken; L3 `file:line` rule fires once it has real content |
72
+ | `Testing` | testing phase (via `record`) | what was verified and how — gated at `wip→testing` by `check` |
73
+ | `Review` | review phase (via `record`) | SECU findings + verdict — gated at `testing→done` by `check --strict-core` |
74
+
75
+ A spec'd task (`--feature` link or batch item with `background`/`requirements`) is created at `todo`
76
+ with Acceptance Criteria + Plan scaffolding present; a bare capture is created at `backlog` with
77
+ Background only.
78
+
79
+ ## Status vs. section — don't conflate
80
+
81
+ `update 0040 wip` is a lifecycle transition. `update 0040 --section …` is a body edit. They are
82
+ separate invocations and mutually exclusive in one call. A typical step does the section edit first,
83
+ then the transition:
84
+
85
+ ```bash
86
+ spur task update 0040 --section Plan --from-file /tmp/plan.md
87
+ spur task update 0040 wip
88
+ ```
89
+
90
+ The `wip→testing` and `testing→done` transitions run a `check` guard (§7.5) — fill the gated
91
+ sections (`Testing`, `Review`, `Solution`) before attempting the transition, or it will be blocked.
92
+
93
+ Before authoring pipeline output for the first time, read the
94
+ **[L3 guard format cheat sheet](l3-guard-cheatsheet.md)**. It centralizes the lifecycle graph,
95
+ Solution citation rule, Review table shape, verdict artifact schema, and canonical section names.