@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.
- package/.claude-plugin/marketplace.json +15 -0
- package/README.md +15 -1
- package/config/templates/AGENTS.md +5 -3
- package/config/workflows/task-pipeline.yaml +103 -12
- package/package.json +15 -12
- package/plugins/README.md +655 -0
- package/plugins/sp/README.md +621 -0
- package/plugins/sp/agents/expert-spur.md +109 -0
- package/plugins/sp/agents/super-coder.md +126 -0
- package/plugins/sp/agents/super-planner.md +283 -0
- package/plugins/sp/agents/super-reviewer.md +154 -0
- package/plugins/sp/commands/dev-arch.md +30 -0
- package/plugins/sp/commands/dev-brainstorm.md +40 -0
- package/plugins/sp/commands/dev-changelog.md +28 -0
- package/plugins/sp/commands/dev-daily.md +29 -0
- package/plugins/sp/commands/dev-debug.md +29 -0
- package/plugins/sp/commands/dev-dogfood.md +33 -0
- package/plugins/sp/commands/dev-featurechange.md +130 -0
- package/plugins/sp/commands/dev-find-conflict.md +51 -0
- package/plugins/sp/commands/dev-find-issue.md +76 -0
- package/plugins/sp/commands/dev-find-next.md +60 -0
- package/plugins/sp/commands/dev-fixall.md +33 -0
- package/plugins/sp/commands/dev-gitmsg.md +28 -0
- package/plugins/sp/commands/dev-gtd.md +97 -0
- package/plugins/sp/commands/dev-handover.md +26 -0
- package/plugins/sp/commands/dev-idea.md +50 -0
- package/plugins/sp/commands/dev-next.md +31 -0
- package/plugins/sp/commands/dev-parallel.md +30 -0
- package/plugins/sp/commands/dev-plan.md +46 -0
- package/plugins/sp/commands/dev-refine.md +48 -0
- package/plugins/sp/commands/dev-refineall.md +65 -0
- package/plugins/sp/commands/dev-refresh.md +32 -0
- package/plugins/sp/commands/dev-reverse.md +32 -0
- package/plugins/sp/commands/dev-review.md +31 -0
- package/plugins/sp/commands/dev-run.md +63 -0
- package/plugins/sp/commands/dev-runall.md +80 -0
- package/plugins/sp/commands/dev-simplify.md +39 -0
- package/plugins/sp/commands/dev-unit.md +29 -0
- package/plugins/sp/commands/dev-verify.md +48 -0
- package/plugins/sp/commands/dev-verifyall.md +72 -0
- package/plugins/sp/commands/dev-wrap.md +30 -0
- package/plugins/sp/commands/dev-wrapall.md +33 -0
- package/plugins/sp/commands/rule-add.md +18 -0
- package/plugins/sp/commands/rule-refine.md +18 -0
- package/plugins/sp/commands/rule-scan.md +18 -0
- package/plugins/sp/commands/spur-init.md +22 -0
- package/plugins/sp/commands/workflow-add.md +18 -0
- package/plugins/sp/commands/workflow-refine.md +18 -0
- package/plugins/sp/hooks/agent-hint.ts +60 -0
- package/plugins/sp/hooks/careful-guard.ts +147 -0
- package/plugins/sp/hooks/context-post-tool.ts +325 -0
- package/plugins/sp/hooks/context-session-start.ts +182 -0
- package/plugins/sp/hooks/context-session-stop.ts +95 -0
- package/plugins/sp/hooks/hooks.json +51 -0
- package/plugins/sp/hooks/pi/guard-extension.ts +341 -0
- package/plugins/sp/hooks/task-write-guard.ts +84 -0
- package/plugins/sp/plugin.json +8 -0
- package/plugins/sp/scripts/batch-preflight.ts +204 -0
- package/plugins/sp/scripts/daily-summary/daily-summary.ts +606 -0
- package/plugins/sp/scripts/daily-summary/logger.ts +28 -0
- package/plugins/sp/scripts/dogfood-testing/detect-pipeline-driving.ts +363 -0
- package/plugins/sp/scripts/dogfood-testing/validate-report.ts +168 -0
- package/plugins/sp/scripts/feature-sync-bounded.ts +451 -0
- package/plugins/sp/scripts/stage-registry-adapter.ts +1341 -0
- package/plugins/sp/scripts/task-size-precheck.ts +202 -0
- package/plugins/sp/scripts/validate-commands.ts +651 -0
- package/plugins/sp/scripts/validate-flag-contracts.ts +875 -0
- package/plugins/sp/skills/brainstorm/SKILL.md +361 -0
- package/plugins/sp/skills/brainstorm/agents/openai.yaml +14 -0
- package/plugins/sp/skills/brainstorm/examples/ideation-example.md +209 -0
- package/plugins/sp/skills/brainstorm/metadata.openclaw +7 -0
- package/plugins/sp/skills/brainstorm/references/grilling-interview.md +68 -0
- package/plugins/sp/skills/brainstorm/references/workflows.md +255 -0
- package/plugins/sp/skills/branch-workflow/SKILL.md +109 -0
- package/plugins/sp/skills/branch-workflow/references/branch-lifecycle.md +69 -0
- package/plugins/sp/skills/branch-workflow/references/worktree-patterns.md +100 -0
- package/plugins/sp/skills/code-implementation/SKILL.md +176 -0
- package/plugins/sp/skills/code-implementation/references/debugging.md +64 -0
- package/plugins/sp/skills/code-implementation/references/implementation-patterns.md +113 -0
- package/plugins/sp/skills/code-improvement/SKILL.md +231 -0
- package/plugins/sp/skills/code-improvement/references/deepening-signals.md +205 -0
- package/plugins/sp/skills/code-review/SKILL.md +112 -0
- package/plugins/sp/skills/code-review/references/receiving-code-review.md +70 -0
- package/plugins/sp/skills/code-review/references/review-lenses.md +117 -0
- package/plugins/sp/skills/code-review/references/self-review-checklist.md +53 -0
- package/plugins/sp/skills/code-review/references/verification-before-completion.md +68 -0
- package/plugins/sp/skills/code-simplification/SKILL.md +225 -0
- package/plugins/sp/skills/code-testing/SKILL.md +108 -0
- package/plugins/sp/skills/code-testing/references/stacks/bun-ts.md +165 -0
- package/plugins/sp/skills/code-testing/references/stacks/go.md +88 -0
- package/plugins/sp/skills/code-testing/references/stacks/python.md +117 -0
- package/plugins/sp/skills/code-testing/references/test-loop-breaker.md +37 -0
- package/plugins/sp/skills/code-testing/references/test-output-discipline.md +52 -0
- package/plugins/sp/skills/code-testing/references/unit-testing.md +212 -0
- package/plugins/sp/skills/code-verification/SKILL.md +535 -0
- package/plugins/sp/skills/code-verification/references/code-improvement.md +39 -0
- package/plugins/sp/skills/code-verification/references/secu-review.md +94 -0
- package/plugins/sp/skills/code-verification/references/verdict-schema.md +141 -0
- package/plugins/sp/skills/conflict-finding/SKILL.md +254 -0
- package/plugins/sp/skills/conflict-finding/references/authority-resolution.md +258 -0
- package/plugins/sp/skills/conflict-finding/references/comparison-protocol.md +277 -0
- package/plugins/sp/skills/conflict-finding/references/finding-contract.md +346 -0
- package/plugins/sp/skills/conflict-finding/references/remediation-routing.md +276 -0
- package/plugins/sp/skills/daily-summary/SKILL.md +171 -0
- package/plugins/sp/skills/daily-summary/agents/openai.yaml +13 -0
- package/plugins/sp/skills/doc-evolve/SKILL.md +175 -0
- package/plugins/sp/skills/doc-evolve/references/operations.md +93 -0
- package/plugins/sp/skills/dogfood-testing/SKILL.md +608 -0
- package/plugins/sp/skills/dogfood-testing/references/monitor-ledger.md +211 -0
- package/plugins/sp/skills/dogfood-testing/references/report-template.md +351 -0
- package/plugins/sp/skills/doubt-driven-development/SKILL.md +136 -0
- package/plugins/sp/skills/functional-review/SKILL.md +364 -0
- package/plugins/sp/skills/functional-review/references/verdict-schema.md +133 -0
- package/plugins/sp/skills/indexed-context/SKILL.md +164 -0
- package/plugins/sp/skills/issue-finding/SKILL.md +424 -0
- package/plugins/sp/skills/issue-finding/agents/openai.yaml +15 -0
- package/plugins/sp/skills/issue-finding/examples/expected-findings.json +27 -0
- package/plugins/sp/skills/issue-finding/examples/session-test-loop.jsonl +23 -0
- package/plugins/sp/skills/issue-finding/references/session-formats.md +121 -0
- package/plugins/sp/skills/next-feature/SKILL.md +125 -0
- package/plugins/sp/skills/next-feature/references/handoff-routing.md +92 -0
- package/plugins/sp/skills/next-feature/references/proposal-contract.md +49 -0
- package/plugins/sp/skills/next-feature/references/ranking-rubric.md +52 -0
- package/plugins/sp/skills/next-feature/references/signal-derivation.md +67 -0
- package/plugins/sp/skills/next-router/SKILL.md +181 -0
- package/plugins/sp/skills/next-router/references/messages.md +90 -0
- package/plugins/sp/skills/next-router/references/routing-table.md +216 -0
- package/plugins/sp/skills/parallel-execution/SKILL.md +148 -0
- package/plugins/sp/skills/parallel-execution/references/dispatch-surface.md +100 -0
- package/plugins/sp/skills/parallel-execution/references/fan-out-patterns.md +101 -0
- package/plugins/sp/skills/parallel-execution/references/result-synthesis.md +94 -0
- package/plugins/sp/skills/reverse-engineering/SKILL.md +375 -0
- package/plugins/sp/skills/reverse-engineering/agents/openai.yaml +18 -0
- package/plugins/sp/skills/source-driven-development/SKILL.md +124 -0
- package/plugins/sp/skills/spec-decomposition/SKILL.md +117 -0
- package/plugins/sp/skills/spec-decomposition/references/decomposition.md +539 -0
- package/plugins/sp/skills/spur-cli/SKILL.md +133 -0
- package/plugins/sp/skills/spur-cli/references/agent.md +179 -0
- package/plugins/sp/skills/spur-cli/references/features/acceptance-criteria.md +82 -0
- package/plugins/sp/skills/spur-cli/references/features/hierarchy-mece.md +177 -0
- package/plugins/sp/skills/spur-cli/references/features/roadmap-priority.md +84 -0
- package/plugins/sp/skills/spur-cli/references/features/verbs.md +122 -0
- package/plugins/sp/skills/spur-cli/references/features.md +234 -0
- package/plugins/sp/skills/spur-cli/references/init.md +119 -0
- package/plugins/sp/skills/spur-cli/references/message.md +98 -0
- package/plugins/sp/skills/spur-cli/references/rules/authoring-rules.md +212 -0
- package/plugins/sp/skills/spur-cli/references/rules/fine-tuning.md +148 -0
- package/plugins/sp/skills/spur-cli/references/rules/operations.md +228 -0
- package/plugins/sp/skills/spur-cli/references/rules/validation-and-extension.md +129 -0
- package/plugins/sp/skills/spur-cli/references/rules.md +209 -0
- package/plugins/sp/skills/spur-cli/references/serve.md +58 -0
- package/plugins/sp/skills/spur-cli/references/tasks/l3-guard-cheatsheet.md +98 -0
- package/plugins/sp/skills/spur-cli/references/tasks/section-editing.md +95 -0
- package/plugins/sp/skills/spur-cli/references/tasks/verbs.md +361 -0
- package/plugins/sp/skills/spur-cli/references/tasks.md +278 -0
- package/plugins/sp/skills/spur-cli/references/team.md +133 -0
- package/plugins/sp/skills/spur-cli/references/workflows/authoring-workflows.md +226 -0
- package/plugins/sp/skills/spur-cli/references/workflows/operations.md +211 -0
- package/plugins/sp/skills/spur-cli/references/workflows/validation-and-extension.md +129 -0
- package/plugins/sp/skills/spur-cli/references/workflows.md +355 -0
- package/plugins/sp/skills/spur-dev/SKILL.md +224 -0
- package/plugins/sp/skills/spur-dev/references/ac-style-guide.md +196 -0
- package/plugins/sp/skills/spur-dev/references/cross-cutting.md +664 -0
- package/plugins/sp/skills/spur-dev/references/decision-brief.md +80 -0
- package/plugins/sp/skills/spur-dev/references/dev-operations.md +546 -0
- package/plugins/sp/skills/spur-dev/references/done-housekeeping.md +164 -0
- package/plugins/sp/skills/spur-dev/references/execution-batch.md +727 -0
- package/plugins/sp/skills/spur-dev/references/execution-workflow.md +350 -0
- package/plugins/sp/skills/spur-dev/references/feature-link-helper.md +191 -0
- package/plugins/sp/skills/spur-dev/references/flag-glossary.md +417 -0
- package/plugins/sp/skills/spur-dev/references/gate-checklists.md +171 -0
- package/plugins/sp/skills/spur-dev/references/glossary.md +95 -0
- package/plugins/sp/skills/spur-dev/references/idea-evaluation.md +80 -0
- package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +88 -0
- package/plugins/sp/skills/spur-dev/references/planning-workflow.md +302 -0
- package/plugins/sp/skills/spur-dev/references/product-planning.md +206 -0
- package/plugins/sp/skills/spur-dev/references/section-batching.md +24 -0
- package/plugins/sp/skills/sys-architecture/SKILL.md +155 -0
- package/plugins/sp/skills/sys-architecture/references/decision-method.md +137 -0
- package/plugins/sp/skills/sys-architecture/references/upkeep-survey.md +75 -0
- package/plugins/sp/skills/sys-debugging/SKILL.md +228 -0
- package/plugins/sp/skills/sys-debugging/references/debugging-protocol.md +62 -0
- package/plugins/sp/skills/test-driven-development/SKILL.md +248 -0
- package/plugins/sp/skills/wayfinder/SKILL.md +292 -0
- 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.
|