@gobing-ai/spur 0.3.78 → 0.3.80
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/config/templates/AGENTS.md +26 -23
- package/config/templates/docs/00_ADR.md +13 -23
- package/config/templates/docs/01_PRD.md +5 -2
- package/config/templates/docs/02_ROADMAP.md +9 -13
- package/config/templates/docs/03_ARCHITECTURE.md +2 -2
- package/config/templates/docs/04_DESIGN.md +12 -31
- package/config/templates/docs/05_FEATURES.md +6 -18
- package/config/templates/docs/99_PROJECT_CONSTITUTION.md +162 -394
- package/package.json +9 -9
- package/plugins/sp/README.md +12 -7
- package/plugins/sp/agents/super-reviewer.md +43 -8
- package/plugins/sp/plugin.json +1 -1
- package/plugins/sp/scripts/verify-answer-lint.ts +21 -3
- package/plugins/sp/skills/conflict-finding/SKILL.md +6 -0
- package/plugins/sp/skills/daily-summary/SKILL.md +1 -1
- package/plugins/sp/skills/doc-evolve/SKILL.md +26 -40
- package/plugins/sp/skills/doc-evolve/references/operations.md +17 -30
- package/plugins/sp/skills/spur-cli/references/tasks/verbs.md +17 -1
- package/plugins/sp/skills/spur-cli/references/tasks.md +31 -1
- package/plugins/sp/skills/spur-dev/references/ac-style-guide.md +14 -0
- package/plugins/sp/skills/spur-dev/references/cross-cutting.md +3 -3
- package/plugins/sp/skills/spur-dev/references/done-housekeeping.md +12 -0
- package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +46 -4
- package/spur.js +363 -258
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gobing-ai/spur",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.80",
|
|
4
4
|
"description": "Spur CLI — local-first harness for mainstream coding agents: constraint checking, workflow orchestration, agent health, and history analytics. Bun-native; exposes the `spur` command.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"spur",
|
|
@@ -53,14 +53,14 @@
|
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@commander-js/extra-typings": "^14.0.0",
|
|
56
|
-
"@gobing-ai/ts-db": "^0.4.
|
|
57
|
-
"@gobing-ai/ts-ai-runner": "^0.4.
|
|
58
|
-
"@gobing-ai/ts-dual-workflow-engine": "^0.4.
|
|
59
|
-
"@gobing-ai/ts-infra": "^0.4.
|
|
60
|
-
"@gobing-ai/ts-llm-jsonl-importer": "^0.4.
|
|
61
|
-
"@gobing-ai/ts-rule-engine": "^0.4.
|
|
62
|
-
"@gobing-ai/ts-runtime": "^0.4.
|
|
63
|
-
"@gobing-ai/ts-utils": "^0.4.
|
|
56
|
+
"@gobing-ai/ts-db": "^0.4.62",
|
|
57
|
+
"@gobing-ai/ts-ai-runner": "^0.4.62",
|
|
58
|
+
"@gobing-ai/ts-dual-workflow-engine": "^0.4.62",
|
|
59
|
+
"@gobing-ai/ts-infra": "^0.4.62",
|
|
60
|
+
"@gobing-ai/ts-llm-jsonl-importer": "^0.4.62",
|
|
61
|
+
"@gobing-ai/ts-rule-engine": "^0.4.62",
|
|
62
|
+
"@gobing-ai/ts-runtime": "^0.4.62",
|
|
63
|
+
"@gobing-ai/ts-utils": "^0.4.62",
|
|
64
64
|
"@types/bun": "1.3.14",
|
|
65
65
|
"@types/figlet": "^1.7.0",
|
|
66
66
|
"@types/node-notifier": "8.0.5",
|
package/plugins/sp/README.md
CHANGED
|
@@ -171,10 +171,12 @@ Commands above are thin wrappers; the actual logic lives in `skills/`. The spine
|
|
|
171
171
|
dispatches five competency skills by function — design (`sp:sys-architecture`), decomposition
|
|
172
172
|
(`sp:spec-decomposition`), implementation (`sp:code-implementation`), testing (`sp:code-testing`),
|
|
173
173
|
and verification (`sp:code-verification`) — plus a CLI facade (`sp:spur-cli`, one reference per
|
|
174
|
-
`spur` noun) and standalone technique skills (`sp:next-router`, `sp:
|
|
175
|
-
`sp:
|
|
176
|
-
`sp:
|
|
177
|
-
`sp:
|
|
174
|
+
`spur` noun) and standalone technique skills (`sp:next-router`, `sp:next-feature`,
|
|
175
|
+
`sp:test-driven-development`, `sp:source-driven-development`, `sp:doubt-driven-development`,
|
|
176
|
+
`sp:brainstorm`, `sp:wayfinder`, `sp:sys-debugging`, `sp:code-review`, `sp:pr-reviewing`,
|
|
177
|
+
`sp:functional-review`, `sp:code-simplification`, `sp:code-improvement`, `sp:parallel-execution`,
|
|
178
|
+
`sp:branch-workflow`, `sp:doc-evolve`, `sp:dogfood-testing`, `sp:daily-summary`,
|
|
179
|
+
`sp:reverse-engineering`, `sp:history-anatomy`, `sp:issue-finding`, `sp:conflict-finding`,
|
|
178
180
|
`sp:indexed-context`, `sp:session-review`, `sp:redesign-web-ui`). See
|
|
179
181
|
[skills/spur-dev/SKILL.md](skills/spur-dev/SKILL.md)'s Step routing table for which skill owns which
|
|
180
182
|
pipeline step.
|
|
@@ -215,6 +217,7 @@ plugins/sp/
|
|
|
215
217
|
│ │ └── references/routing-table.md
|
|
216
218
|
│ ├── parallel-execution/ # Fan-out decision framework + patterns
|
|
217
219
|
│ │ └── references/{fan-out-patterns, result-synthesis}.md
|
|
220
|
+
│ ├── pr-reviewing/ # GitHub PR review loop backing /sp:dev-pr-review
|
|
218
221
|
│ ├── source-driven-development/ # Source-first API/contract verification (SKILL.md only)
|
|
219
222
|
│ ├── spec-decomposition/ # Feature/spec → task-batch competency
|
|
220
223
|
│ │ └── references/decomposition.md
|
|
@@ -255,6 +258,8 @@ plugins/sp/
|
|
|
255
258
|
├── agents/ # 4 specialist subagents (expert-spur, super-coder, super-planner, super-reviewer)
|
|
256
259
|
├── hooks/ # hooks.json + task-write-guard.{ts,test.ts} + context-{session-start,post-tool,session-stop}.ts
|
|
257
260
|
│ # + careful-guard.{ts,test.ts} + context-hooks.test.ts + token-estimate.test.ts
|
|
261
|
+
│ # + shared policy modules: agent-hint.ts, destructive-policy.{ts,test.ts}, task-file-policy.{ts,test.ts}
|
|
262
|
+
│ # + pi/guard-extension.{ts,test.ts} (plugin.json `extensions.pi` entry point)
|
|
258
263
|
├── scripts/ # Executable helpers, split from prompts (ADR-031) — validate-commands.ts (thin-wrapper validator), batch-preflight.ts + scripts/<skill>/
|
|
259
264
|
│ # (daily-summary: {daily-summary, logger}.ts; dogfood-testing: {detect-pipeline-driving, validate-report}.ts)
|
|
260
265
|
├── tests/ # Plugin tests — command-contract.test.ts + skill-structure.test.ts + batch-preflight.test.ts + per-skill suites
|
|
@@ -318,13 +323,13 @@ surface or run one workflow. All skills target the same five core platforms: `cl
|
|
|
318
323
|
| `daily-summary` | 1.0.0 | Daily summary report generator — orchestrates ccusage CLI + git history into structured markdown summaries |
|
|
319
324
|
| `doc-evolve` | 1.0 | Key-document evolution per `docs/99_PROJECT_CONSTITUTION.md` — drift audits, same-commit sync checks, frontmatter-contract verification, machine-appended lessons |
|
|
320
325
|
| `reverse-engineering` | 1.1 | Codebase analysis / HLD generation / audit — depth-driven reverse engineering with orthogonal mode, focus, and format controls; backs `/sp:dev-reverse` |
|
|
321
|
-
| `issue-finding` |
|
|
326
|
+
| `issue-finding` | 2.0 | Session-log forensics — multi-source discovery, bottleneck ranking, optional topic focus, CLI-gated fix task generation; **legacy path** — superseded by `history-anatomy` for indexed reporting; backs no current command; directly invocable as sp:issue-finding |
|
|
322
327
|
| `conflict-finding` | 1.0 | Authority-aware semantic audit — four-pillar (source/task/feature/authority) conflict discovery, claim-specific authority resolution, reproducible evidence, confirmed owner-routed remediation; backs `/sp:dev-find-conflict` |
|
|
323
328
|
| `next-feature` | 1.0 | Prompt-first feature frontier prioritizer — sync-first precondition, B3 actionability gate (cited, never restated), tiered rubric over measured signals, D1–D4 defect proposals conforming to the restructure map schema; backs `/sp:dev-find-next` |
|
|
324
329
|
| `pr-reviewing` | 1.0 | GitHub Codex PR review — PR prepare/reuse, `@codex review` request with per-HEAD dedupe, bounded polling, findings normalization, validated fix + re-review; spine SSOT `pr-review.yaml` + `scripts/pr-reviewing.ts`; backs `/sp:dev-pr-review` |
|
|
325
330
|
| `indexed-context` | 1.0 | Cross-agent project context — anatomy/learnings/pitfalls/buglog/memory in `.spur/context/`; hook-tracked token-ledger; graceful degradation on agents without hooks |
|
|
326
331
|
| `history-anatomy` | 1.0 | Diagnostic interpretation owner over already-imported history — daily/ad-hoc mode contract, closed finding taxonomy, twelve-section report contract, `enrich`/`validate` rubrics; no workflow launch, no JSONL fallback, no corpus mutation |
|
|
327
|
-
| `session-review` | 1.
|
|
332
|
+
| `session-review` | 1.1 | Inline review of the active coding-agent session — compact outcomes, evidence-backed resolved/open issue classification, proposal-only improvements, and next actions; no workflow, import, delegation, or mutation |
|
|
328
333
|
| `redesign-web-ui` | 1.0 | Existing-UI visual upgrade — audit generic AI fingerprints, apply in-stack polish against `DESIGN.md` / live tokens, verify behavior and viewports; does not migrate frameworks |
|
|
329
334
|
|
|
330
335
|
#### Bounded coexistence and retirement gate — `sp:issue-finding` (HA-S1 0661)
|
|
@@ -418,7 +423,7 @@ the pipeline's Phase 7 review step.
|
|
|
418
423
|
| ---------------- | ------------ | ----------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------- |
|
|
419
424
|
| `expert-spur` | expert | `sp:spur-cli` | green | "create tasks", "feature lifecycle", "add a rule", "author a workflow" |
|
|
420
425
|
| `super-coder` | builder | `sp:sys-architecture` + `sp:code-implementation` + `sp:code-testing` + `sp:sys-debugging` | blue | "implement this", "write the code", "fix this bug", "design the architecture" |
|
|
421
|
-
| `super-planner` | orchestrator | `sp:spur-dev` + `sp:dogfood-testing`
|
|
426
|
+
| `super-planner` | orchestrator | `sp:spur-dev` + `sp:parallel-execution` + `sp:dogfood-testing` + `sp:next-router` | green | "run this task end to end", "run all tasks", "run the batch", "runall" |
|
|
422
427
|
| `super-reviewer` | reviewer | `sp:code-verification` + `sp:functional-review` + `sp:code-improvement` | crimson | "review this", "check the code", "SECUA review", "run task 0042 through review" |
|
|
423
428
|
|
|
424
429
|
Each agent has:
|
|
@@ -97,7 +97,8 @@ HITL gate unless `--auto` was passed.
|
|
|
97
97
|
- [ ] Establish scope first: WBS mode (task diff) or path mode (source glob). Derive the diff
|
|
98
98
|
scope the same way `sp:code-verification` Step 3 does.
|
|
99
99
|
- [ ] Dispatch each requested dimension to its owning skill — do not inline the review logic.
|
|
100
|
-
- [ ] Merge findings into a single ranked report
|
|
100
|
+
- [ ] Merge findings into a single ranked report, emitting native priority cells
|
|
101
|
+
(`P1 (blocker)` > `P2 (major)` > `P3 (minor)` > `P4 (advisory)` — see Output Format).
|
|
101
102
|
- [ ] In pipeline mode, write the merged report to the task's `## Review` section via
|
|
102
103
|
`spur task update <wbs> --section Review --from-file`; in standalone mode, emit as output.
|
|
103
104
|
- [ ] Cite `file:line` evidence for every finding — no vague "implemented correctly."
|
|
@@ -109,6 +110,8 @@ HITL gate unless `--auto` was passed.
|
|
|
109
110
|
- [ ] Never edit `task-pipeline.yaml` or reach into a pipeline step.
|
|
110
111
|
- [ ] Never auto-approve a HITL gate unless `--auto` was passed.
|
|
111
112
|
- [ ] Never soften a FAIL to PARTIAL, or PARTIAL to PASS, to avoid surfacing.
|
|
113
|
+
- [ ] Never emit a word-only Severity cell, an empty priority scaffold, or a `##`/`###` heading
|
|
114
|
+
inside a `### Review` body — all three fail the existing checkers.
|
|
112
115
|
- [ ] Never skip a dimension the operator requested with `--focus`.
|
|
113
116
|
|
|
114
117
|
## Definition of Done Housekeeping
|
|
@@ -120,22 +123,44 @@ enforcement checklist. Reference:
|
|
|
120
123
|
|
|
121
124
|
## Output Format
|
|
122
125
|
|
|
126
|
+
### Priority vocabulary (task 0818 R3)
|
|
127
|
+
|
|
128
|
+
Emit priorities **natively** — the consumer (`hasPopulatedPriorityTable`,
|
|
129
|
+
`packages/app/src/services/task-check.ts`) requires a `P1`–`P4` cell, and a word-only severity cell
|
|
130
|
+
fails it. One explicit mapping, no transcription step anywhere downstream:
|
|
131
|
+
|
|
132
|
+
| Priority cell | Severity | Meaning |
|
|
133
|
+
| --- | --- | --- |
|
|
134
|
+
| `P1 (blocker)` | blocker | Ships broken or unsafe; blocks the verdict |
|
|
135
|
+
| `P2 (major)` | major | Real defect or structural problem; must be dispositioned |
|
|
136
|
+
| `P3 (minor)` | minor | Localized issue; fix or accept explicitly |
|
|
137
|
+
| `P4 (advisory)` | advisory | Observation, non-blocking |
|
|
138
|
+
|
|
139
|
+
Severity words stay visible in the same cell — the mapping adds the machine-readable label, it does
|
|
140
|
+
not replace the semantics.
|
|
141
|
+
|
|
142
|
+
**Section-relative headings.** In pipeline mode the report body is written *into* the task's
|
|
143
|
+
`### Review` section, so every heading inside it MUST be `####` or deeper. A `##`/`###` heading in
|
|
144
|
+
the body becomes a new top-level task section and corrupts the document. In standalone mode
|
|
145
|
+
(emitted as output, not written to a task) the same body may be rendered one level shallower.
|
|
146
|
+
|
|
123
147
|
```markdown
|
|
124
|
-
|
|
148
|
+
#### Review Report — <wbs|path>
|
|
125
149
|
|
|
126
150
|
**Scope:** <wbs diff | path glob>
|
|
127
151
|
**Dimensions:** functional, security, efficiency, correctness, usability, architecture
|
|
128
152
|
**Verdict:** PASS | PARTIAL | FAIL
|
|
129
153
|
|
|
130
|
-
|
|
154
|
+
##### Findings (ranked)
|
|
131
155
|
|
|
132
|
-
| # |
|
|
156
|
+
| # | Priority | Dimension | Finding | Location |
|
|
133
157
|
|---|----------|-----------|---------|----------|
|
|
134
|
-
| 1 | blocker | security | SQL injection in query builder | `src/api/users.ts:42` |
|
|
135
|
-
| 2 | major | architecture | Shallow pass-through UserService | `src/services/users.ts:15` |
|
|
136
|
-
| 3 | minor | correctness | Missing error branch in createUser | `src/api/users.ts:48` |
|
|
158
|
+
| 1 | P1 (blocker) | security | SQL injection in query builder | `src/api/users.ts:42` |
|
|
159
|
+
| 2 | P2 (major) | architecture | Shallow pass-through UserService | `src/services/users.ts:15` |
|
|
160
|
+
| 3 | P3 (minor) | correctness | Missing error branch in createUser | `src/api/users.ts:48` |
|
|
161
|
+
| 4 | P4 (advisory) | usability | `createUser` error text omits the field name | `src/api/users.ts:51` |
|
|
137
162
|
|
|
138
|
-
|
|
163
|
+
##### Functional Traceability
|
|
139
164
|
|
|
140
165
|
| Req | Status | Evidence |
|
|
141
166
|
|-----|--------|----------|
|
|
@@ -145,6 +170,16 @@ enforcement checklist. Reference:
|
|
|
145
170
|
**Next:** <one-line action>
|
|
146
171
|
```
|
|
147
172
|
|
|
173
|
+
**No findings.** Never invent a defect to populate the table. Emit one substantive `P4 (advisory)`
|
|
174
|
+
row that states what was reviewed and what was found — placeholder cells (empty, `—`, `n/a`) are
|
|
175
|
+
rejected by the checker, and so they should be:
|
|
176
|
+
|
|
177
|
+
```markdown
|
|
178
|
+
| # | Priority | Dimension | Finding | Location |
|
|
179
|
+
|---|----------|-----------|---------|----------|
|
|
180
|
+
| 1 | P4 (advisory) | — | No P1–P3 findings: 6 changed files reviewed across all six dimensions; R1–R3 traceable to tests | `packages/app/src/workflow/proof-input-fingerprint.ts:102-160` |
|
|
181
|
+
```
|
|
182
|
+
|
|
148
183
|
With `--json`, emit the same shape as a JSON object for machine consumption.
|
|
149
184
|
|
|
150
185
|
## Out of scope
|
package/plugins/sp/plugin.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sp",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.80",
|
|
4
4
|
"description": "Spur — a local-first harness engineering toolkit that wraps mainstream coding agents with constraint checking, workflow orchestration, and history analytics.",
|
|
5
5
|
"extensions": {
|
|
6
6
|
"pi": ["./hooks/pi/guard-extension.ts"]
|
|
@@ -282,7 +282,8 @@ function stripAcWrappers(title: string): string {
|
|
|
282
282
|
* Normalize an AC identity to its canonical key, mirroring the documented
|
|
283
283
|
* matching behavior of feature-check `rowMatchesScenario` + ac-style-guide
|
|
284
284
|
* "Four accepted id forms" (exact/bare title, `Scenario:` prefix, bracket
|
|
285
|
-
* tags, `AC-N` ordinal)
|
|
285
|
+
* tags, `AC-N` ordinal) plus the task-side bold-trajectory paragraph
|
|
286
|
+
* (0817 R3), without importing that private matcher or adopting
|
|
286
287
|
* its permissive trailing-Gherkin fallback (0804 R4). Comparison is
|
|
287
288
|
* case/quote/whitespace-insensitive. A paraphrase normalizes differently
|
|
288
289
|
* and still fails.
|
|
@@ -307,7 +308,7 @@ function normalizeAcTitle(title: string): string {
|
|
|
307
308
|
* A checklist-declared spelling always wins over the positional alias.
|
|
308
309
|
*/
|
|
309
310
|
interface AcIdentityIndex {
|
|
310
|
-
/** normalized canonical title → a declared spelling (label, token, or
|
|
311
|
+
/** normalized canonical title → a declared spelling (label, token, title, or bold trajectory). */
|
|
311
312
|
readonly byTitle: Map<string, string>;
|
|
312
313
|
/** AC-N → task scenario title at that 1-based ordinal. */
|
|
313
314
|
readonly taskScenarios: string[];
|
|
@@ -331,6 +332,19 @@ function buildAcIdentityIndex(taskContent: string, featureContent: string | null
|
|
|
331
332
|
const leading = label.split(/\s+/)[0] ?? '';
|
|
332
333
|
if (leading && leading !== label) declareIdentity(leading);
|
|
333
334
|
}
|
|
335
|
+
// Bold-trajectory form (task 0817 R3): answers may cite an AC by a bare
|
|
336
|
+
// `**AC id**` paragraph (house style for long/complex ids). Only whole-line
|
|
337
|
+
// bold spans count — the line-anchored lazy regex rejects lines with two
|
|
338
|
+
// spans, keeping interpolated bold text out of the index. The head (text
|
|
339
|
+
// before the first colon) is declared like a checklist label, mirroring
|
|
340
|
+
// the `(?::|$)` label extraction above.
|
|
341
|
+
for (const m of section.matchAll(/^\*\*(.+?)\*\*\s*$/gm)) {
|
|
342
|
+
const inner = (m[1] ?? '').trim();
|
|
343
|
+
if (!inner) continue;
|
|
344
|
+
declareIdentity(inner);
|
|
345
|
+
const head = inner.split(':')[0]?.trim() ?? '';
|
|
346
|
+
if (head && head !== inner) declareIdentity(head);
|
|
347
|
+
}
|
|
334
348
|
const scenarioTitles = (content: string): string[] =>
|
|
335
349
|
[...content.matchAll(/^[ \t]*Scenario:\s*(.+)\s*$/gm)].map((m) => (m[1] ?? '').trim()).filter((t) => t !== '');
|
|
336
350
|
const taskScenarios = scenarioTitles(sectionBetween(taskContent, 'Acceptance Criteria'));
|
|
@@ -348,6 +362,10 @@ type AcIdentityResolution = { ok: true; canonical: string } | { ok: false; error
|
|
|
348
362
|
* alias — accepted only against a real scenario ordinal, and refused with an
|
|
349
363
|
* actionable diagnostic when task and feature ordinals disagree. Undeclared
|
|
350
364
|
* `ACn` tokens, paraphrases and invented ordinals never resolve.
|
|
365
|
+
* `ACn` tokens, paraphrases and invented ordinals never resolve.
|
|
366
|
+
*
|
|
367
|
+
* Declared forms recognized in the index include the bold-trajectory
|
|
368
|
+
* `**AC id**` paragraph (task 0817 R3); the AC-N failure hint names it.
|
|
351
369
|
*/
|
|
352
370
|
function resolveAcIdentity(rowId: string, index: AcIdentityIndex): AcIdentityResolution {
|
|
353
371
|
const canonical = index.byTitle.get(normalizeAcTitle(rowId));
|
|
@@ -365,7 +383,7 @@ function resolveAcIdentity(rowId: string, index: AcIdentityIndex): AcIdentityRes
|
|
|
365
383
|
ok: false,
|
|
366
384
|
error:
|
|
367
385
|
`AC id "${rowId}" uses the AC-${n} positional alias but no scenario exists at that ordinal ` +
|
|
368
|
-
'(task scenario list and linked-feature scenario list) — cite the exact scenario title or
|
|
386
|
+
'(task scenario list and linked-feature scenario list) — cite the exact scenario title, checklist label, or a bare `**AC id**` paragraph',
|
|
369
387
|
};
|
|
370
388
|
}
|
|
371
389
|
if (candidates.length > 1) {
|
|
@@ -94,6 +94,12 @@ Resolve `<scope>` and `--pillar`; confirm the repository root; establish **audit
|
|
|
94
94
|
numbered-document mutation of any kind. With `--resolve`, no write happens until a repair set is
|
|
95
95
|
presented, explicitly confirmed, and freshness-revalidated.
|
|
96
96
|
|
|
97
|
+
Validate every enum flag against the domain declared by the command surface
|
|
98
|
+
(`plugins/sp/commands/dev-find-conflict.md`): `--pillar` ∈ `source|tasks|features|authority|all`,
|
|
99
|
+
`--mode` ∈ `adaptive|full`, `--agent` ∈ `inline|auto|name`. An out-of-domain value **refuses** the
|
|
100
|
+
audit before any discovery work — report the received value, the flag's valid domain, and stop;
|
|
101
|
+
never silently coerce or ignore it. Only `<scope>` is free-form and exempt from this check.
|
|
102
|
+
|
|
97
103
|
### Step 2 — Discover local authority
|
|
98
104
|
|
|
99
105
|
Read entry/process rules (`AGENTS.md`, `docs/99_PROJECT_CONSTITUTION.md`) before interpreting any
|
|
@@ -166,6 +166,6 @@ Read the skill file and follow the workflow manually.
|
|
|
166
166
|
## Additional Resources
|
|
167
167
|
|
|
168
168
|
- **Script source:** [scripts/daily-summary/daily-summary.ts](../../scripts/daily-summary/daily-summary.ts) — CLI implementation
|
|
169
|
-
- **Tests:** [tests/daily-summary.test.ts](tests/daily-summary.test.ts) — unit coverage for parsing, date ranges, markdown output
|
|
169
|
+
- **Tests:** [tests/daily-summary/daily-summary.test.ts](../../tests/daily-summary/daily-summary.test.ts) — unit coverage for parsing, date ranges, markdown output
|
|
170
170
|
- **Related skills:** `sp:dev-handover` (blocker handoff), `sp:dev-changelog` (commit-based changelog), `sp:spur-cli` (task management)
|
|
171
171
|
- **Upstream CLI:** [ccusage](https://github.com/ryoppippi/ccusage) — AI agent token usage reporter
|
|
@@ -4,7 +4,7 @@ description: "Evolve docs/00-05 + AGENTS.md per docs/99_PROJECT_CONSTITUTION.md:
|
|
|
4
4
|
license: Apache-2.0
|
|
5
5
|
metadata:
|
|
6
6
|
author: spur
|
|
7
|
-
version: "1.
|
|
7
|
+
version: "1.1"
|
|
8
8
|
platforms: "claude-code,codex,openclaw,opencode,antigravity"
|
|
9
9
|
interactions:
|
|
10
10
|
- reviewer
|
|
@@ -30,17 +30,17 @@ this skill applies it.
|
|
|
30
30
|
|
|
31
31
|
**Read `docs/99_PROJECT_CONSTITUTION.md` first.** It is the single source of truth for *how* these
|
|
32
32
|
files are maintained (authority §2, doc map §4.1, frontmatter contracts §4.3, sync triggers §5,
|
|
33
|
-
per-file edit rules §6, the audit §7,
|
|
33
|
+
per-file edit rules §6, the audit §7, lesson routing §8). This skill is a runbook for executing §5/§7/§8;
|
|
34
34
|
when the two disagree, the constitution wins and this skill is the bug.
|
|
35
35
|
|
|
36
36
|
## Operations
|
|
37
37
|
|
|
38
38
|
| Operation | What it does | Constitution authority | Deterministic helper |
|
|
39
39
|
| --------- | ------------ | ---------------------- | -------------------- |
|
|
40
|
-
| **drift-audit** | Reality (code/shipped) vs. what a key file says, and cross-doc contradictions | §7
|
|
41
|
-
| **sync-check** | Did a change touch the docs its trigger obligates in the same commit? | §5 (triggers
|
|
40
|
+
| **drift-audit** | Reality (code/shipped) vs. what a key file says, and cross-doc contradictions | §7 | `rg` the real CLI/config surface; diff vs `04`/`AGENTS.md`/`00` |
|
|
41
|
+
| **sync-check** | Did a change touch the docs its trigger obligates in the same commit? | §5 (applicable triggers) | git diff of code/config vs. the matching doc edit |
|
|
42
42
|
| **contract-verify** | Each doc's frontmatter matches its §4.1 row; `updated_at` is plausible | §4.3 | parse frontmatter; compare `owns`/`authority` vs §4.1; `git log` recency |
|
|
43
|
-
| **lesson-append** |
|
|
43
|
+
| **lesson-append** | Record a useful lesson in existing project context; deduplicate; propose governance changes separately | §8 | format-check the line; `rg` for an equivalent before adding |
|
|
44
44
|
|
|
45
45
|
No thin `dev-docs` command wrapper exists (`dev-operations.md §7`). Invoke this skill directly for
|
|
46
46
|
an audit or a lesson, or reach it via `/sp:dev-plan`'s docs step and `/sp:spur-init`'s `customize`.
|
|
@@ -84,48 +84,40 @@ stubs filled or deliberately documented; `bun run lint` passes where applicable.
|
|
|
84
84
|
Walk the §7 checklist. Each item pairs a detection command with the doc it validates:
|
|
85
85
|
|
|
86
86
|
```bash
|
|
87
|
-
# Real CLI surface vs.
|
|
87
|
+
# Real CLI surface vs. owning non-UI contracts
|
|
88
88
|
rg -n "\.command\('" apps/cli/src/commands/ # the true verb list
|
|
89
|
-
rg -n '^#### `spur ' docs/
|
|
89
|
+
rg -n '^#### `spur ' docs/design/ # documented commands
|
|
90
90
|
# → diff the two sets; a verb in code but not in 04 is T3 drift.
|
|
91
91
|
|
|
92
92
|
# 05 status rows vs. reality
|
|
93
|
-
|
|
93
|
+
cat docs/features/INDEX.md # generated feature states
|
|
94
94
|
# → spot-check each ✅/🔶 against code; confirm no ⏳ quietly shipped.
|
|
95
95
|
|
|
96
96
|
# 02 phase bullets name real things (no dead names)
|
|
97
97
|
# 03 module descriptions vs. the real tree
|
|
98
|
-
|
|
98
|
+
rg --files apps packages # real modules
|
|
99
99
|
# Frontmatter contracts (see contract-verify) + updated_at recency
|
|
100
100
|
git log -1 --format='%ci' -- docs/04_DESIGN.md # last touch vs. recent surface changes
|
|
101
101
|
```
|
|
102
102
|
|
|
103
|
-
**Repair protocol (§7
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
103
|
+
**Repair protocol (§7):** fix the authoritative statement first, then affected detail/index/entry
|
|
104
|
+
files. Preserve ADR numbers, original titles/dates and decision history; editorial condensation
|
|
105
|
+
follows §6.1, while actual reversals need a superseding decision. Record findings in a task/report.
|
|
106
|
+
Routine lessons go to existing learning/context storage (§8); no automatic constitution edits.
|
|
107
107
|
|
|
108
108
|
Output a **drift report**: per finding, `{ doc, what code says, what the doc says, authority, repair
|
|
109
109
|
}`. A clean report lists the checks run and that each returned no delta.
|
|
110
110
|
|
|
111
111
|
## sync-check (§5)
|
|
112
112
|
|
|
113
|
-
|
|
113
|
+
Read the live constitution §5; it owns the trigger table. Classify each changed fact, identify
|
|
114
|
+
its owner, and inspect the diff to confirm required synchronization. Update an index or AGENTS.md
|
|
115
|
+
only when its own facts changed. A satellite edit with an unchanged index pointer is synchronized.
|
|
114
116
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
| makes a new cross-cutting decision (or reverses one) | **T1** | `00` first (dated), then `03`, `01` if scope shifts |
|
|
120
|
-
| would contradict an existing ADR | **T2** | **stop** — add the superseding ADR entry first |
|
|
121
|
-
| completes/reorders a phase | **T5** | `02` (the real shipped name) |
|
|
122
|
-
| adds/cuts/defers scope | **T6** | `01` + placement in `02` |
|
|
123
|
-
| changes the doc map or process | **T7** | this file → re-sync `AGENTS.md` (§4.4) → siblings |
|
|
124
|
-
| plans a multi-wave batch | **T8** | schedule "doc sync" as an explicit work item |
|
|
125
|
-
|
|
126
|
-
Detection is a diff read: list the changed code/config paths, map each to its trigger, then confirm
|
|
127
|
-
the obligated doc was edited in the same change. A surface change with no `04` edit is the canonical
|
|
128
|
-
miss (the one this whole §5 table exists to prevent).
|
|
117
|
+
T1 applies only to real architectural choices passing §6.1. Feature approvals, task completion,
|
|
118
|
+
bugfixes restoring an existing contract and verification receipts do not justify ADR entries.
|
|
119
|
+
T7 applies only to operator-authorized governance corrections under §6.8; a routine doc edit or
|
|
120
|
+
lesson does not justify touching the constitution. Portable changes include in-scope init templates.
|
|
129
121
|
|
|
130
122
|
## contract-verify (§4.3)
|
|
131
123
|
|
|
@@ -140,19 +132,13 @@ stale given recent commits?"
|
|
|
140
132
|
|
|
141
133
|
## lesson-append (§8)
|
|
142
134
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
- [YYYY-MM-DD] <project>: <lesson — what went wrong / what to do instead>
|
|
147
|
-
```
|
|
135
|
+
Read constitution §8 for the existing project's destination. Record a useful, deduplicated
|
|
136
|
+
lesson in existing learning/context storage or a dated report, with evidence. Do not append
|
|
137
|
+
lessons to the constitution. Do not create a second learning ledger when one already exists.
|
|
148
138
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
promoted into a §6 rule (or §5 trigger) and removed from §8. Lessons are the inbox; §5/§6 are the
|
|
153
|
-
law.
|
|
154
|
-
- Lessons carry project provenance (this file is byte-identical across projects except §8 + the §3
|
|
155
|
-
tool column) — a lesson from one project is a warning, not yet a law, for the others.
|
|
139
|
+
A recurring lesson may justify proposing a document-governance correction; apply it only within
|
|
140
|
+
operator-authorized §6.8 scope. Task receipts remain in task records. Fresh project templates
|
|
141
|
+
contain neither inherited lessons nor fabricated decisions/status claims.
|
|
156
142
|
|
|
157
143
|
## What this skill is NOT
|
|
158
144
|
|
|
@@ -15,41 +15,33 @@ it enforces; the skill never invents process.
|
|
|
15
15
|
|
|
16
16
|
| Operation | Authority § | What "done" means |
|
|
17
17
|
| --------- | ----------- | ----------------- |
|
|
18
|
-
| drift-audit | §7 | the
|
|
19
|
-
| sync-check | §5 (
|
|
18
|
+
| drift-audit | §7 | the affected §7 checks run, each backed by a command; report lists deltas (or the zero-delta commands) |
|
|
19
|
+
| sync-check | §5 (applicable §5 triggers) | every changed surface mapped to its trigger; the obligated doc confirmed edited in the same change |
|
|
20
20
|
| contract-verify | §4.3 (+ §4.1) | each doc's frontmatter `owns`/`authority` matches its §4.1 row; `updated_at` plausible |
|
|
21
|
-
| lesson-append | §8 | a
|
|
21
|
+
| lesson-append | §8 | a deduplicated lesson in existing learning/context storage, never appended to 99 |
|
|
22
22
|
|
|
23
23
|
## drift-audit — §7 checklist → detection commands
|
|
24
24
|
|
|
25
25
|
| §7 item | Detection (deterministic) | Authoritative doc |
|
|
26
26
|
| ------- | ------------------------- | ----------------- |
|
|
27
|
-
| Real CLI surface vs docs |
|
|
28
|
-
|
|
|
27
|
+
| Real CLI surface vs docs | Compare source-local help/registrations with owning `docs/design/` contracts | `04` satellites |
|
|
28
|
+
| Feature state matches evidence | Read the feature tool's generated index, then inspect affected acceptance evidence | `05` / feature records |
|
|
29
29
|
| Every shipped surface has a `01` scope row | surface set (above) vs `rg` of `01` scope table | `01` |
|
|
30
30
|
| `02` phase bullets name real things | read `02` current-phase bullets; grep each name in code/docs | `02` |
|
|
31
|
-
| `03` modules vs real tree | `
|
|
31
|
+
| `03` modules vs real tree | `rg --files apps packages` vs `03` module map | `03` |
|
|
32
32
|
| `04` covers every command/flag/config/schema | the verb/flag/config set vs `04` | `04` |
|
|
33
33
|
| `AGENTS.md` doc map == §4.1 | diff the two tables | `AGENTS.md` (§4.4) |
|
|
34
34
|
| frontmatter matches §4.1 + `updated_at` plausible | see contract-verify | each doc (§4.3) |
|
|
35
35
|
|
|
36
36
|
**Judgment:** is a candidate real drift (vs. an intentional, documented exception)? Which doc is
|
|
37
|
-
authoritative? What is the *minimal* repair (
|
|
37
|
+
authoritative? What is the *minimal* repair (preserve decision history and condense only editorial noise under §6.1)?
|
|
38
38
|
|
|
39
|
-
## sync-check —
|
|
39
|
+
## sync-check — applicable §5 triggers → obligations
|
|
40
40
|
|
|
41
|
-
Read the
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
```bash
|
|
47
|
-
# Surface changed in this diff?
|
|
48
|
-
git diff --name-only | rg 'apps/cli/src/commands/|packages/.*/schema|config/'
|
|
49
|
-
# Was 04 / AGENTS.md touched in the same diff?
|
|
50
|
-
git diff --name-only | rg 'docs/04_DESIGN.md|^AGENTS.md'
|
|
51
|
-
# Both non-empty → likely synced; surface-changed-but-no-04 → T3 drift.
|
|
52
|
-
```
|
|
41
|
+
Read the diff and the live constitution §5. Map changed facts to their owning document and
|
|
42
|
+
check that contract, not merely whether a filename appears in the diff. Unchanged index pointers
|
|
43
|
+
and entry guidance need no edits. T7 additionally requires the governance reason and existing
|
|
44
|
+
operator authorization under §6.8; include affected templates.
|
|
53
45
|
|
|
54
46
|
## contract-verify — §4.3
|
|
55
47
|
|
|
@@ -65,15 +57,10 @@ Compare `owns`/`authority` against the §4.1 row (verbatim in meaning; §4.1 win
|
|
|
65
57
|
|
|
66
58
|
## lesson-append — §8
|
|
67
59
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
1. Identify the per-file `### Lessons for <doc>` section (or the cross-cutting one).
|
|
73
|
-
2. `rg` that section for an equivalent lesson — if found, **bump its date**, don't duplicate.
|
|
74
|
-
3. Append the formatted line. If the lesson restates an existing §6 rule, it's already law — skip.
|
|
75
|
-
4. If it has recurred, **promote** it to a §6 rule / §5 trigger and remove from §8 (the only
|
|
76
|
-
sanctioned deletion).
|
|
60
|
+
1. Resolve the existing learning/context destination from the project's conventions.
|
|
61
|
+
2. Search for an equivalent lesson; skip duplicates and routine completion receipts.
|
|
62
|
+
3. Record the useful lesson with evidence outside the constitution.
|
|
63
|
+
4. Propose any governance correction separately; recurrence does not authorize a §6.8 edit.
|
|
77
64
|
|
|
78
65
|
## Drift-report shape
|
|
79
66
|
|
|
@@ -84,7 +71,7 @@ Checks run: <n> (§7 items) · Findings: <m>
|
|
|
84
71
|
|
|
85
72
|
| # | Doc | Reality says | Doc says | Authority | Trigger | Repair |
|
|
86
73
|
|---|-----|--------------|----------|-----------|---------|--------|
|
|
87
|
-
| 1 | 04_DESIGN |
|
|
74
|
+
| 1 | 04_DESIGN | Changed command contract | Satellite describes old behavior | 04 | T3 | update its owning satellite under §6.5 |
|
|
88
75
|
|
|
89
76
|
Zero-finding checks: <list the §7 items that returned no delta, with the command used>
|
|
90
77
|
```
|
|
@@ -67,6 +67,20 @@ frontmatter scalar.
|
|
|
67
67
|
wholesale. No inline-body flag. Section names: `Background`, `Requirements`, `Acceptance Criteria`, `Q&A`, `Design`, `Plan`, `Solution`, `Testing`, `Review`, `References`, `History`, `Notes`.
|
|
68
68
|
- **Frontmatter** (`--feature <id>`, `--priority <p>`): sets the scalar frontmatter field on an
|
|
69
69
|
existing task — the only post-create path, allow-listed to `feature_id` / `parent_wbs` / `priority`.
|
|
70
|
+
- **AC controls** (`--ac-altitude <graduating|task-local>`, `--ac-numbering task-local`) — independent
|
|
71
|
+
of each other (task 0818 R5). `--ac-altitude task-local` skips the **DD-09 feature-AC subset** rule
|
|
72
|
+
because the task's scenarios are intentionally not the feature's ship criteria; `--ac-numbering
|
|
73
|
+
task-local` opts the task into the **Requirements↔AC coverage** check inside the task. Setting one
|
|
74
|
+
never implies the other. `graduating` remains the default and DD-09 stays enforced for graduating
|
|
75
|
+
tasks. Use it for an issue/fix-batch task that is genuinely linked to a feature but whose
|
|
76
|
+
regression scenarios sit below that feature's ship criteria, and record the rationale in the task
|
|
77
|
+
body:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
# One frontmatter flag per call — `update` sets a single field and ignores the rest.
|
|
81
|
+
bun run apps/cli/src/index.ts task update 0818 --feature D6 --json
|
|
82
|
+
bun run apps/cli/src/index.ts task update 0818 --ac-altitude task-local --json
|
|
83
|
+
```
|
|
70
84
|
|
|
71
85
|
Exit code `2` when neither mode's required args are supplied (e.g. `--section` without `--from-file`,
|
|
72
86
|
or no status and no `--section`/frontmatter flag).
|
|
@@ -183,7 +197,9 @@ traceability. Bare = whole corpus; with a WBS = one task. The matrix is loaded f
|
|
|
183
197
|
|
|
184
198
|
**L4 traceability** resolves `feature_id` / `parent_wbs` / `dependencies` edges and checks **AC
|
|
185
199
|
coverage** (DD-09): a task's scenarios must be a subset of its linked feature's AC by normalized
|
|
186
|
-
title — orphans warn by default.
|
|
200
|
+
title — orphans warn by default. A task declaring `ac_altitude: task-local` is exempt from that
|
|
201
|
+
subset rule only (`--ac-altitude`, above); every graduating task is still enforced, and the exemption
|
|
202
|
+
does not touch `ac_numbering`'s Requirements↔AC coverage or any other layer.
|
|
187
203
|
|
|
188
204
|
`--json` emits an array of per-task results:
|
|
189
205
|
|
|
@@ -157,13 +157,43 @@ spur task update 0040 --section Review --from-file /tmp/review.md
|
|
|
157
157
|
first, then point `--from-file` at it.
|
|
158
158
|
|
|
159
159
|
**Frontmatter set** (the only post-create path to scalar fields, allow-listed to
|
|
160
|
-
`feature_id`/`parent_wbs`/`priority
|
|
160
|
+
`feature_id`/`parent_wbs`/`priority`, plus the two AC controls below):
|
|
161
161
|
|
|
162
162
|
```bash
|
|
163
163
|
spur task update 0040 --feature H2
|
|
164
164
|
spur task update 0040 --priority P1
|
|
165
165
|
```
|
|
166
166
|
|
|
167
|
+
### AC altitude — `--ac-altitude` (task 0818 R5)
|
|
168
|
+
|
|
169
|
+
`--ac-altitude` and `--ac-numbering` are **independent** controls that are easy to confuse:
|
|
170
|
+
|
|
171
|
+
| Flag | Controls | Default | `task-local` means |
|
|
172
|
+
| --- | --- | --- | --- |
|
|
173
|
+
| `--ac-altitude <graduating\|task-local>` | DD-09 **feature-AC subset** rule (task scenarios ⊆ linked feature AC) | `graduating` | the task's scenarios are deliberately **not** feature ship criteria — skip the subset rule |
|
|
174
|
+
| `--ac-numbering <task-local>` | **Requirements↔AC coverage** inside the task | off | opt the task into the R-to-AC coverage check |
|
|
175
|
+
|
|
176
|
+
Setting one says nothing about the other: a `task-local`-altitude task can still be under full
|
|
177
|
+
R-to-AC coverage, and usually should be.
|
|
178
|
+
|
|
179
|
+
**The standing pattern for an issue or fix-batch task.** Link it to the feature it substantively
|
|
180
|
+
belongs to — do not leave it orphaned and do not relink unrelated corpus to silence a diagnostic.
|
|
181
|
+
Then, *only* when its regression scenarios intentionally do not represent that feature's ship
|
|
182
|
+
criteria, declare `--ac-altitude task-local` and record the rationale in the task body (Background
|
|
183
|
+
or Design), so the choice is auditable rather than inferred:
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
# source-local CLI (before `bun link`, or when pinning to this checkout).
|
|
187
|
+
# One frontmatter flag per call: `update` applies a single field, so a second
|
|
188
|
+
# frontmatter flag in the same invocation is silently ignored.
|
|
189
|
+
bun run apps/cli/src/index.ts task update 0818 --feature D6 --json
|
|
190
|
+
bun run apps/cli/src/index.ts task update 0818 --ac-altitude task-local --json
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
`graduating` stays the default, and DD-09 stays enforced for every graduating task — this flag
|
|
194
|
+
expresses a real altitude distinction, not a gate escape hatch. Ordinary orphan warnings are
|
|
195
|
+
unchanged, and no checker policy changes.
|
|
196
|
+
|
|
167
197
|
The section-write-then-replace pattern is the workflow agents use to fill in `Plan` / `Solution` /
|
|
168
198
|
`Testing` / `Review` during a run. See
|
|
169
199
|
[tasks/section-editing.md](tasks/section-editing.md) for the full recipe. For pipeline
|
|
@@ -113,6 +113,20 @@ Any of the four may additionally carry a **bracket tag** in any position — `[d
|
|
|
113
113
|
`Scenario: [advisory] Foo`. Tags are stripped before matching (0398 R7), so tagging never breaks
|
|
114
114
|
the linkage.
|
|
115
115
|
|
|
116
|
+
Task-side, `verify-answer-lint` additionally accepts a fifth declared id source — a **bold-trajectory
|
|
117
|
+
paragraph**: a whole-line `**AC id…**` paragraph inside the task's `### Acceptance Criteria`
|
|
118
|
+
block (task 0817 R3). The id up to its first `:` and the paragraph's full spelling are both
|
|
119
|
+
declared; two bold spans on one line are not a declaration (an interpolated bold id stays
|
|
120
|
+
unmatchable):
|
|
121
|
+
|
|
122
|
+
```markdown
|
|
123
|
+
### Acceptance Criteria
|
|
124
|
+
|
|
125
|
+
**AC-0817-HERM-SKIP: unpinned project-config resolution is suppressed.**
|
|
126
|
+
|
|
127
|
+
| AC-0817-HERM-SKIP | MET | test | `tests/loader.test.ts:962` | ← declared
|
|
128
|
+
```
|
|
129
|
+
|
|
116
130
|
### The id is exactly the scenario title — no Gherkin body appended
|
|
117
131
|
|
|
118
132
|
An AC row id must be **exactly** the scenario title (plus any of the four forms above), with the
|
|
@@ -634,9 +634,9 @@ CLI-gated corpus artifact. The `wrapup-pipeline.yaml` `learning-capture` step wr
|
|
|
634
634
|
|
|
635
635
|
- **Not CLI-gated.** The file is written directly by the wrap-up pipeline's `learning-capture`
|
|
636
636
|
agent.run step. It does not go through `spur task update` or `spur feature update`.
|
|
637
|
-
- **Not a validated corpus.** The file is a working scratchpad.
|
|
638
|
-
|
|
639
|
-
not
|
|
637
|
+
- **Not a validated corpus.** The file is a working scratchpad. Deduplicate reusable lessons in
|
|
638
|
+
existing project learning/context storage. Constitution §8 routes lessons outside that file;
|
|
639
|
+
doc-sync does not promote lessons into governance without operator-authorized §6.8 scope.
|
|
640
640
|
- **Append-only within a session.** New entries are appended; existing entries are not rewritten.
|
|
641
641
|
- **Grouped by date and task.** Each entry has a date and task WBS header so the operator can
|
|
642
642
|
trace a learning back to its source task.
|