@gobing-ai/spur 0.3.41 → 0.3.43
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 +113 -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 +83 -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 +48 -0
- package/plugins/sp/commands/dev-wrapall.md +51 -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 +203 -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 +442 -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 +151 -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 +109 -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 +280 -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 +680 -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 +790 -0
- package/plugins/sp/skills/spur-dev/references/execution-workflow.md +352 -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 +120 -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 +6035 -4963
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: monitor-ledger
|
|
3
|
+
description: "The dogfood monitor methodology + on-disk live ledger column contract + dual-write + token/cache estimation heuristic + the cache-health finding rule. The on-disk ledger is the single source of truth the report is assembled from — recorded live, per step, never reconstructed."
|
|
4
|
+
see_also:
|
|
5
|
+
- dogfood-testing
|
|
6
|
+
- report-template
|
|
7
|
+
protocol: sp:dogfood-testing@1.2
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Monitor + Ledger
|
|
11
|
+
|
|
12
|
+
The ledger is the **single source of truth** for the report. It is recorded **live on disk** — one
|
|
13
|
+
row per step, written the moment the step resolves — never reconstructed from memory at the end.
|
|
14
|
+
Reconstruction produces fiction: it cannot honestly distinguish a step that passed first-try from
|
|
15
|
+
one that took three attempts, and it loses the per-step signal that drives testee refinement.
|
|
16
|
+
|
|
17
|
+
**Disk SSOT (protocol @1.2).** Working-memory-only ledgers are a contract violation. The ledger
|
|
18
|
+
lives in the dual artifacts (see [report-template.md](report-template.md) → Always-on dual
|
|
19
|
+
artifacts):
|
|
20
|
+
|
|
21
|
+
| File | Path |
|
|
22
|
+
|------|------|
|
|
23
|
+
| Live | `.spur/run/dogfood/<run_id>.md` |
|
|
24
|
+
| Report | `docs/dogfood/YYYY-MM-DD-<testee-slug>-dogfood.md` |
|
|
25
|
+
|
|
26
|
+
## The live-ledger rule
|
|
27
|
+
|
|
28
|
+
1. **Open both artifacts in Phase 1**, before the first step runs (frontmatter `status: running` +
|
|
29
|
+
empty ledger table in each).
|
|
30
|
+
2. **Write a row the instant a step resolves** (pass, fixed, unresolved, or N/A) — not after the run.
|
|
31
|
+
3. **Dual-write every step:** append/update the row on the **live** file first, then mirror to the
|
|
32
|
+
**report** path. Do not batch rows until Phase 4. If the report write fails, continue with live
|
|
33
|
+
as SSOT, emit a P2 finding, and retry promote on finalize.
|
|
34
|
+
4. **The report reads the on-disk ledger, not your memory.** Every number in the report traces to a
|
|
35
|
+
ledger row on disk. If it is not in the ledger file, it does not go in the report.
|
|
36
|
+
5. **Cardinality (@1.2).** The ledger's data-row count MUST equal the `**Steps:** N derived, N executed` declared
|
|
37
|
+
in the report's §2 Execution Summary. N/A steps are not dropped — each gets its own row with
|
|
38
|
+
`Outcome: N/A`. A count mismatch refuses `status: complete` at finalize (see
|
|
39
|
+
6. **R2 drift row (task 0296).** A ledger row tagged `drift:external` in the `Step` column documents
|
|
40
|
+
workspace drift detected during the run — files changed by an external writer that neither the
|
|
41
|
+
driver nor testee ledger rows name. The row carries `Outcome: drift`, `Fix Applied: <drifted paths>`,
|
|
42
|
+
`Finding: P2 — workspace drift detected during run; attribution to external writer`,
|
|
43
|
+
and `Basis: <fingerprint diff>`. A drift row never changes a step's outcome and never results in
|
|
44
|
+
a `FIXED` / `PASS` outcome — it is purely documentary. Cache columns carry `—` (not estimated).
|
|
45
|
+
See [SKILL.md §Workspace-drift guard](../SKILL.md#workspace-drift-guard-r2--task-0296).
|
|
46
|
+
|
|
47
|
+
### Fast-run exemption (task 0294 R6a)
|
|
48
|
+
|
|
49
|
+
The per-step live-write mandate (rules 1–4) exists to bound information loss when a mid-run crash
|
|
50
|
+
terminates the driver before finalize. That risk is real for long runs (multi-step pipelines,
|
|
51
|
+
mutating testees); it is **marginal for fast runs** where wall-clock is short enough that an
|
|
52
|
+
operator would naturally watch the run to completion.
|
|
53
|
+
|
|
54
|
+
**Codified exemption.** A run with **total wall-clock < 3 minutes** MAY batch-write all ledger
|
|
55
|
+
rows at finalize, provided **both** of the following hold:
|
|
56
|
+
|
|
57
|
+
1. The report's §2 Execution Summary carries an explicit note:
|
|
58
|
+
`Ledger write mode: batch-finalize (fast-run exemption, total wall-clock < 3 min)`.
|
|
59
|
+
2. The driver is still prepared to reconstruct per-step ordering honestly — batched does not mean
|
|
60
|
+
fictional. If the driver cannot reconstruct attempts/outcomes per step from its own tool-call
|
|
61
|
+
history, the exemption does NOT apply and the strict per-step rule is back in force (rule 4:
|
|
62
|
+
"if it is not in the ledger file, it does not go in the report").
|
|
63
|
+
|
|
64
|
+
This matches how the 0280 fast-run actually behaved (batch-finalize, still validated `complete`)
|
|
65
|
+
and preserves the strict mandate for long runs where mid-run crash loss is the real risk. A run
|
|
66
|
+
≥ 3 min that batch-writes is a **protocol violation the driver must self-report** as a P3 finding
|
|
67
|
+
in the report's §6 Findings (no exemption applies).
|
|
68
|
+
|
|
69
|
+
## Column contract
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
| Step | Attempts | Outcome | Fix Applied | Finding | Fresh Tokens | Cached Tokens | Cache % | Basis | Wall-clock |
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
| Column | Meaning |
|
|
76
|
+
|--------|---------|
|
|
77
|
+
| `Step` | The derived step label (Phase 1) or `N` for a single-step testee. |
|
|
78
|
+
| `Attempts` | How many times the step was run (1 = first-try; >1 = retried under the fix budget). |
|
|
79
|
+
| `Outcome` | `PASS` / `FIXED` / `UNRESOLVED` / `N/A`. (`FIXED` = failed then passed within budget.) |
|
|
80
|
+
| `Fix Applied` | `file:line` + one-line summary, or `—`. |
|
|
81
|
+
| `Finding` | One-line finding surfaced at this step, or `—`. A finding does **not** change `Outcome`. |
|
|
82
|
+
| `Fresh Tokens` | Estimated fresh context for the step. Prefix with `~`. |
|
|
83
|
+
| `Cached Tokens` | Estimated reused context for the step. Prefix with `~`. |
|
|
84
|
+
| `Cache %` | `Cached Tokens / (Fresh Tokens + Cached Tokens)`, rounded to the nearest whole percent. |
|
|
85
|
+
| `Basis` | Observable basis for the estimate: command output, prior file read reused, generated text, etc. |
|
|
86
|
+
| `Wall-clock` | Elapsed time for the step. |
|
|
87
|
+
|
|
88
|
+
## Token + cache estimation heuristic
|
|
89
|
+
|
|
90
|
+
A skill **cannot read its own exact token meter** — derive an estimate and label every number
|
|
91
|
+
`~estimate`. The accepted methodology is deterministic from the ledger rows:
|
|
92
|
+
|
|
93
|
+
1. Estimate **Fresh Tokens** from new material consumed or produced by the step:
|
|
94
|
+
- text read from files or command output: `ceil(characters / 4)`, rounded to the nearest 100;
|
|
95
|
+
- generated prose/code/report text: `ceil(characters / 4)`, rounded to the nearest 100;
|
|
96
|
+
- short command/control overhead: add `~100` per tool invocation that produced non-empty output.
|
|
97
|
+
2. Estimate **Cached Tokens** only for material already present in the current session and actively
|
|
98
|
+
reused by reference in this step. Use the same `ceil(characters / 4)` basis and round to the
|
|
99
|
+
nearest 100. Do not count fresh command output, newly read files, or regenerated scaffolding as
|
|
100
|
+
cached.
|
|
101
|
+
3. Compute each row: `Cache % = round(Cached Tokens / (Fresh Tokens + Cached Tokens) * 100)`.
|
|
102
|
+
4. Compute the report aggregate from row sums:
|
|
103
|
+
`aggregate cache% = round(sum(Cached Tokens) / sum(Fresh Tokens + Cached Tokens) * 100)`.
|
|
104
|
+
|
|
105
|
+
The **trend across runs** is the signal, not the absolute value: rising cache% = the testee is
|
|
106
|
+
reusing context efficiently; falling cache% = context bloat creeping in.
|
|
107
|
+
|
|
108
|
+
> Never print a precise token number you cannot substantiate. The numbers exist to show a *trend*,
|
|
109
|
+
> not to bill anyone.
|
|
110
|
+
|
|
111
|
+
### Multi-source Cost block (report §2)
|
|
112
|
+
|
|
113
|
+
Ledger estimates alone are **confidence: LOW**. When assembling the report Cost block
|
|
114
|
+
([report-template.md](report-template.md) §2):
|
|
115
|
+
|
|
116
|
+
| Source | When to use | Confidence | Scope label |
|
|
117
|
+
|--------|-------------|------------|-------------|
|
|
118
|
+
| Ledger `chars/4` heuristic | Always | LOW | per-step trend |
|
|
119
|
+
| `ccusage` daily/session | If CLI available and returns data | MEDIUM | day or session — **not** per-step |
|
|
120
|
+
| Agent usage fields in tool results | If present (never invent) | MEDIUM | as reported by the tool |
|
|
121
|
+
|
|
122
|
+
If no external meter is available, print `Meter: n/a`. Never merge a day-level meter into a
|
|
123
|
+
per-step ledger cell as if it were measured per step.
|
|
124
|
+
|
|
125
|
+
### Chained-step rows (implement-heavy derived steps)
|
|
126
|
+
|
|
127
|
+
When a derived step is implement-heavy (it runs a pipeline leg, writes code, or otherwise mutates more
|
|
128
|
+
than its own arguments), its row is tagged `chained:<step>` in the Step column and its Fresh/Cached
|
|
129
|
+
columns reflect the **chained leg's** cost, not the driver's. The driver's monitoring cost for that
|
|
130
|
+
step stays on the driver's own row.
|
|
131
|
+
|
|
132
|
+
- Observable chained usage (subagent output in driver context, or the operator explicitly provided
|
|
133
|
+
the artifact) → estimate Fresh/Cached from that output normally.
|
|
134
|
+
- Unobservable chained usage (subagent ran in a different session, usage data never surfaced) →
|
|
135
|
+
label Fresh `~unknown`, Cached `~0`, Basis `chained-leg usage not observable from driver`. **MUST**
|
|
136
|
+
emit a P3 finding: `P3 — chained-step cost not observable` (task 0278 R3). Do not invent totals.
|
|
137
|
+
|
|
138
|
+
Never fold a chained row into the driver's row; the whole point of dogfooding a pipeline-driving
|
|
139
|
+
testee is to see the testee's own cost separately from the driver's monitoring cost. See
|
|
140
|
+
[SKILL.md §Cost segmentation for implement-heavy steps](../SKILL.md#cost-segmentation-for-implement-heavy-steps).
|
|
141
|
+
|
|
142
|
+
## Anti-fiction rule
|
|
143
|
+
|
|
144
|
+
Never reuse a convenient cache percentage such as `45%` because it "feels right." A cache percentage
|
|
145
|
+
is valid only when it can be recomputed from the ledger row sums. If the basis is missing, mark the
|
|
146
|
+
row pessimistically (`Cached Tokens = ~0`) and explain the missing basis.
|
|
147
|
+
|
|
148
|
+
## Cache-health finding rule
|
|
149
|
+
|
|
150
|
+
Cache% is the operational signal for testee-tuning:
|
|
151
|
+
|
|
152
|
+
- Any **individual step with cache% < 40%** → it is re-reading files or re-sending prompt context
|
|
153
|
+
unnecessarily. Emit a **P3** finding naming that step, **even if the step succeeded**.
|
|
154
|
+
- A run with **aggregate cache% < 50%** → the testee is a tuning candidate regardless of the
|
|
155
|
+
PASS/PARTIAL/FAIL verdict. Emit a **P3** finding: "Low cache hit rate — candidate for
|
|
156
|
+
context-window or prompt trimming."
|
|
157
|
+
|
|
158
|
+
These feed the report's §6 Findings (see [report-template.md](report-template.md)).
|
|
159
|
+
|
|
160
|
+
## Cache-conservation discipline (how to keep cache% high)
|
|
161
|
+
|
|
162
|
+
The cache-health rule above *detects* waste; this section is the mitigation. The dogfooding driver
|
|
163
|
+
(the agent running Phase 2/3) controls most of the cache% it later reports — low cache% is usually
|
|
164
|
+
the driver re-fetching data it already holds. Apply these while monitoring each step:
|
|
165
|
+
|
|
166
|
+
### Driver cache checklist (task 0278 R7)
|
|
167
|
+
|
|
168
|
+
When aggregate cache% risks falling under 50%, apply this checklist **before** re-reading:
|
|
169
|
+
|
|
170
|
+
| # | Action | Why |
|
|
171
|
+
|---|--------|-----|
|
|
172
|
+
| 1 | Reuse the Step-1 `spur task show --json` capture for the rest of the run | Avoids re-tokenizing the full task body |
|
|
173
|
+
| 2 | Do not re-Read SKILL.md / report-template after Phase 1 loaded them | Skill body is large; keep one copy in context |
|
|
174
|
+
| 3 | Prefer `--json` CLI over re-parsing freeform prose | Smaller, stable payloads |
|
|
175
|
+
| 4 | Dual-write ledger rows without re-reading the whole report each step | Append/patch; don't full-file re-load |
|
|
176
|
+
| 5 | Skip redundant `bun test` full suite between steps when a focused file suite already green | Run the broad suite once at the end |
|
|
177
|
+
| 6 | For batch testees (`verifyall` / `runall` / `refineall`): freeze `task list --json` once at resolve | Re-listing the set per task is the #1 sub-50% cache pattern on feature dogfoods |
|
|
178
|
+
| 7 | On re-verify of done tasks: re-read only cited `file:line` anchors, not full Solution blobs | Anchor-first re-verify keeps cache% above the 50% floor |
|
|
179
|
+
|
|
180
|
+
1. **Reuse CLI output already in context.** If a prior step (or a prior tool call this step)
|
|
181
|
+
captured `spur task show`/`check`/`list` output, do **not** re-invoke the same command for that
|
|
182
|
+
data — reference the prior result. Re-invocation is the #1 cause of sub-40% steps. Only re-fetch
|
|
183
|
+
when the underlying state *changed* (e.g. you just wrote a section and need the new
|
|
184
|
+
`requiredSections`).
|
|
185
|
+
2. **Don't re-ground shared scaffolding per step.** Command docs, the skill preamble, and the
|
|
186
|
+
testee's own argument-hint are loaded once into your context — they do not need to be re-read or
|
|
187
|
+
re-quoted for each step. Re-sending unchanged preamble registers as fresh tokens, not cached.
|
|
188
|
+
3. **Prefer `--json` + targeted fields over full human output.** When you must fetch, ask for the
|
|
189
|
+
smallest shape that answers the question (`--json` and read one field), not the full
|
|
190
|
+
human-formatted dump.
|
|
191
|
+
4. **Estimate `~cached` honestly against this discipline.** If *you* re-read a file or re-sent
|
|
192
|
+
scaffolding this step, that portion is **not** cached — mark cache% down. The estimate is only
|
|
193
|
+
useful as a trend if it reflects what actually happened.
|
|
194
|
+
|
|
195
|
+
The point is not to game the number — it is to drive the testee (and your own monitoring) toward
|
|
196
|
+
reusing context, which is the real cost saving the cache% signal stands for.
|
|
197
|
+
|
|
198
|
+
## Worked ledger example
|
|
199
|
+
|
|
200
|
+
```
|
|
201
|
+
| Step | Attempts | Outcome | Fix Applied | Finding | Fresh Tokens | Cached Tokens | Cache % | Basis | Wall-clock |
|
|
202
|
+
|------|----------|---------|-------------|---------|--------------|---------------|---------|-------|------------|
|
|
203
|
+
| 1 resolve | 1 | PASS | — | — | ~600 | ~400 | 40% | task JSON output + prior command docs reused | ~3s |
|
|
204
|
+
| 2 analyze | 1 | PASS | — | over-specified for refine | ~1100 | ~700 | 39% | task file read + prior task summary reused | ~5s |
|
|
205
|
+
| 3 synthesize | 2 | FIXED | spur-dev/SKILL.md:88 thread --agent | — | ~1500 | ~600 | 29% | edit diff + prior plan reused | ~8s |
|
|
206
|
+
| 4 profile | 1 | PASS | — | — | ~500 | ~350 | 41% | command output + prior profile reused | ~2s |
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
Aggregate: total = `3700 + 2050 = 5750`; cached = `2050`; cache% =
|
|
210
|
+
`round(2050 / 5750 * 100) = 36%` `[~estimate]` — below the 50% floor, so emit the P3 cache-health
|
|
211
|
+
finding.
|
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: report-template
|
|
3
|
+
description: "The dogfood report section contract + dual-path always-on delivery + mandatory summary footer + the --task sink L3 rule. The report is assembled from the on-disk live ledger and is designed to be actionable — a reader should be able to fine-tune the testee from the report alone."
|
|
4
|
+
see_also:
|
|
5
|
+
- dogfood-testing
|
|
6
|
+
- monitor-ledger
|
|
7
|
+
protocol: sp:dogfood-testing@1.2
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Dogfood Report Template
|
|
11
|
+
|
|
12
|
+
The report is the deliverable. It is assembled from the **on-disk** live ledger (never reconstructed
|
|
13
|
+
from memory) and is designed so a reader can **fine-tune the testee from the report alone** — every
|
|
14
|
+
finding carries a location and a recommended action, not just an observation.
|
|
15
|
+
|
|
16
|
+
**Protocol version:** `sp:dogfood-testing@1.2` — dual-path always-on delivery, status model, Cost
|
|
17
|
+
block with multi-source honesty. Bump this field when the contract changes. **@1.2 changes:**
|
|
18
|
+
finalize hard structure (unique §1–§6 headings; Issues requires `#### Fixed` + `#### Unresolved`);
|
|
19
|
+
mandatory summary footer mirrored at the report end (footer missing ⇒ `status: complete` refused);
|
|
20
|
+
ledger cardinality (data rows == declared executed steps); protocol string normalized to the
|
|
21
|
+
colon form — the dash form `sp-dogfood-testing@…` is rejected in new runs.
|
|
22
|
+
|
|
23
|
+
## Always-on dual artifacts (delivery contract)
|
|
24
|
+
|
|
25
|
+
Every dogfood run **always** writes **two** files — with or without `--save`:
|
|
26
|
+
|
|
27
|
+
| Artifact | Path | Role |
|
|
28
|
+
|----------|------|------|
|
|
29
|
+
| **Live** | `.spur/run/dogfood/<run_id>.md` | Mid-run SSOT; opened in Phase 1; ledger rows appended on every step resolve |
|
|
30
|
+
| **Report** | `docs/dogfood/YYYY-MM-DD-<testee-slug>-dogfood.md` | Operator artifact; same content promoted on open + every step + finalize |
|
|
31
|
+
|
|
32
|
+
`--save` is **back-compat no-op** for delivery: it still documents/prints the report path but is
|
|
33
|
+
**not required** to create the file. A run that ends with no file under `docs/dogfood/` (and no live
|
|
34
|
+
file under `.spur/run/dogfood/`) has failed the dogfood delivery contract.
|
|
35
|
+
|
|
36
|
+
### Frontmatter (canonical — every artifact MUST open with this)
|
|
37
|
+
|
|
38
|
+
```yaml
|
|
39
|
+
---
|
|
40
|
+
run_id: <uuid-or-timestamp-slug>
|
|
41
|
+
status: running | aborted | complete
|
|
42
|
+
testee: "<exact invocation string>"
|
|
43
|
+
classification: slash-command | agent-skill | cli
|
|
44
|
+
mode: observe-only | fix
|
|
45
|
+
max_retry: <n>
|
|
46
|
+
testee_agent: omitted | <name>
|
|
47
|
+
started_at: <ISO-8601>
|
|
48
|
+
finished_at: <ISO-8601 or null while running>
|
|
49
|
+
live_path: .spur/run/dogfood/<run_id>.md
|
|
50
|
+
report_path: docs/dogfood/YYYY-MM-DD-<slug>-dogfood.md
|
|
51
|
+
protocol: sp:dogfood-testing@1.2
|
|
52
|
+
workspace_fingerprint: ← optional — recorded in Phase 1 for fix-mode and mutating-`--fix` dogfoods
|
|
53
|
+
head: <`git rev-parse HEAD`>
|
|
54
|
+
porcelain_hash: <sha256 of `git status --porcelain`>
|
|
55
|
+
taken_at: <ISO-8601>
|
|
56
|
+
---
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Status model (partial-OK)
|
|
60
|
+
|
|
61
|
+
| `status` | When |
|
|
62
|
+
|----------|------|
|
|
63
|
+
| `running` | Phase 1 opened; steps still in progress |
|
|
64
|
+
| `aborted` | Finalize-or-abort after mid-run stop / incomplete narrative |
|
|
65
|
+
| `complete` | Phase 4 finished a normal end-of-run report |
|
|
66
|
+
|
|
67
|
+
A mid-run death that left only a live file with `status: running` and ledger rows is still valid
|
|
68
|
+
partial evidence. On any intentional stop, the driver MUST run finalize-or-abort and set
|
|
69
|
+
`complete` or `aborted` — never leave a deliberate stop at `running`.
|
|
70
|
+
|
|
71
|
+
Unfinished narrative sections (What We Did / Issues / Findings) use:
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
⚠ incomplete — not reached
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Never invent narrative for steps that did not run.
|
|
78
|
+
|
|
79
|
+
## Section contract
|
|
80
|
+
|
|
81
|
+
Emit these sections in order. Headings are fixed (machine-parseable); never rename or drop one.
|
|
82
|
+
Skeleton is written in Phase 1; filled as the run progresses; finalized in Phase 4.
|
|
83
|
+
|
|
84
|
+
### 1. Testee
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
## Dogfood Report — `<testee invocation>`
|
|
88
|
+
|
|
89
|
+
### 1. Testee
|
|
90
|
+
|
|
91
|
+
- **Command:** `<slash command or CLI invocation>`
|
|
92
|
+
- **Classification:** `slash command` | `agent skill` | `CLI invocation`
|
|
93
|
+
- **Exact invocation:** the underlying `Skill()` call or shell command
|
|
94
|
+
- **Repro:** `<exact string an operator can re-run>`
|
|
95
|
+
- **Testee agent:** `<value forwarded via --agent>` | `omitted (testee runs in current session)`
|
|
96
|
+
- **Mode:** `observe-only (--max-retry 0)` | `fix (--max-retry N)`
|
|
97
|
+
- **Task under test:** WBS + title (if applicable)
|
|
98
|
+
- **Run id:** `<run_id>` · **Live:** `<live_path>` · **Report:** `<report_path>`
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
When `status` is `aborted` or the report is partial, add under §1:
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
- **Delivery status:** aborted | partial ⚠ incomplete run
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### 2. Execution Summary
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
### 2. Execution Summary
|
|
111
|
+
|
|
112
|
+
- **Result:** PASS / PARTIAL / FAIL `(N fixed, N unresolved, N findings)`
|
|
113
|
+
- **Wall-clock:** ~N min `[~estimate]`
|
|
114
|
+
- **Steps:** N derived, N executed, N N/A
|
|
115
|
+
- **Fix attempts:** N (one brief label per fix)
|
|
116
|
+
|
|
117
|
+
#### Cost
|
|
118
|
+
- **Ledger estimate:** ~N total | ~N cached (~X% hit rate) `[~estimate]`
|
|
119
|
+
- **Method:** chars/4 heuristic (monitor-ledger.md); confidence: LOW
|
|
120
|
+
- **Meter:** n/a
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
**Cost honesty rules:**
|
|
124
|
+
|
|
125
|
+
- Always include ledger-derived `~estimate` total / cached / cache% with a **Method** line and
|
|
126
|
+
**confidence** (`LOW` when estimate-only; `MEDIUM` when a real meter is also present).
|
|
127
|
+
- Optional meters when available (never invent):
|
|
128
|
+
- `ccusage` session/daily delta — label scope (`day` / `session`), **not** per-step
|
|
129
|
+
- agent usage fields if present in tool results
|
|
130
|
+
- If no meter: print `Meter: n/a` explicitly.
|
|
131
|
+
- Never present an unsubstantiated precise integer as billed/metered cost.
|
|
132
|
+
- Aggregate cache% MUST equal the ledger formula (see §3); otherwise the report is invalid.
|
|
133
|
+
- **Chained-step segmentation (@1.2):** when a derived step is implement-heavy (the step runs a
|
|
134
|
+
pipeline leg, writes code, or mutates more than its own arguments), its cost MUST be a separate
|
|
135
|
+
ledger row tagged `chained:<step>` and kept out of the driver's row. If the chained leg ran in a
|
|
136
|
+
subagent/session whose usage the driver cannot read, label the row `~unknown` and emit a P3 finding.
|
|
137
|
+
See [SKILL.md §Cost segmentation for implement-heavy steps](../SKILL.md#cost-segmentation-for-implement-heavy-steps).
|
|
138
|
+
|
|
139
|
+
**Verdict rule** — `PASS` = every step ran and no unresolved issue; `PARTIAL` = ran to the end but
|
|
140
|
+
≥1 unresolved issue; `FAIL` = the run could not complete (a step blocked all downstream steps). A
|
|
141
|
+
finding alone never lowers the verdict — findings are improvements, not failures.
|
|
142
|
+
|
|
143
|
+
**The verdict grades the TESTEE, not the surrounding task.** If the testee is a
|
|
144
|
+
pipeline/command and it failed, the verdict is `FAIL` (or `PARTIAL` per the rule above) even
|
|
145
|
+
when the task was completed by other means; record the recovery under Issues/What-We-Did,
|
|
146
|
+
never in the verdict value. Only `PASS` / `PARTIAL` / `FAIL` are legal values.
|
|
147
|
+
|
|
148
|
+
### 3. Monitor Ledger
|
|
149
|
+
|
|
150
|
+
The report MUST include the live ledger table before the narrative. Do not summarize the ledger away:
|
|
151
|
+
it is the audit trail for step outcomes, fix attempts, findings, and cache math. Rows are written to
|
|
152
|
+
**disk** (both artifacts) when each step resolves — see [monitor-ledger.md](monitor-ledger.md).
|
|
153
|
+
|
|
154
|
+
```
|
|
155
|
+
### 3. Monitor Ledger
|
|
156
|
+
|
|
157
|
+
| Step | Attempts | Outcome | Fix Applied | Finding | Fresh Tokens | Cached Tokens | Cache % | Basis | Wall-clock |
|
|
158
|
+
|------|----------|---------|-------------|---------|--------------|---------------|---------|-------|------------|
|
|
159
|
+
| resolve | 1 | PASS | — | — | ~800 | ~300 | 27% | 1 command + reused task summary | ~3s |
|
|
160
|
+
|
|
161
|
+
**Cache calculation:** aggregate cache% = round((sum(Cached Tokens) / sum(Fresh Tokens + Cached Tokens)) * 100).
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Ledger rules:
|
|
165
|
+
|
|
166
|
+
- Every executed step gets exactly one row, recorded when the step resolves (**on disk**, both files).
|
|
167
|
+
- `Fresh Tokens` and `Cached Tokens` must be numbers with `~` prefixes; `Cache %` must be computed
|
|
168
|
+
from those two cells, not guessed.
|
|
169
|
+
- `Basis` is mandatory. It names the observable inputs used for the estimate: command output,
|
|
170
|
+
previously-read file reused from context, generated report text, or similar.
|
|
171
|
+
- The aggregate cache line in `#### Cost` under §2 must equal the ledger formula above. If it
|
|
172
|
+
does not, the report is invalid.
|
|
173
|
+
- **Cardinality (@1.2):** the number of ledger data rows MUST equal the `**Steps:** N derived, N executed`
|
|
174
|
+
declared in §2. Steps marked N/A are documented explicitly as their own rows (`Outcome: N/A`);
|
|
175
|
+
an unaccounted step or an extra row refuses `status: complete` at finalize.
|
|
176
|
+
- If the driver cannot make a defensible estimate for a row, write `~0` cached and explain the
|
|
177
|
+
missing basis in `Basis`; do not invent a stable percentage.
|
|
178
|
+
|
|
179
|
+
### 4. What We Did
|
|
180
|
+
|
|
181
|
+
Narrative, one numbered entry per logical action (a step, a fix, a gate check). Include `path:line`
|
|
182
|
+
references. Someone should understand the run without reading the ledger.
|
|
183
|
+
|
|
184
|
+
```
|
|
185
|
+
### 4. What We Did
|
|
186
|
+
|
|
187
|
+
1. **Action label** — what happened, what was observed, the decision made.
|
|
188
|
+
2. **Action label** — …
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
If the run aborted before narrative was written: `⚠ incomplete — not reached`.
|
|
192
|
+
|
|
193
|
+
### 5. Issues
|
|
194
|
+
|
|
195
|
+
Always include both sub-headings, with `(none)` when empty — consistent structure matters for parsing.
|
|
196
|
+
|
|
197
|
+
```
|
|
198
|
+
### 5. Issues
|
|
199
|
+
|
|
200
|
+
#### Fixed
|
|
201
|
+
|
|
202
|
+
1. **Issue title** — description.
|
|
203
|
+
- Root cause: why it happened.
|
|
204
|
+
- Fix: `file:line` + one-line summary of the change.
|
|
205
|
+
|
|
206
|
+
#### Unresolved
|
|
207
|
+
|
|
208
|
+
- (none) | each with diagnosis + everything tried.
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### 6. Findings
|
|
212
|
+
|
|
213
|
+
Findings are the **fine-tuning payload**. Each carries a severity, a `file:line`, and a concrete
|
|
214
|
+
**recommended action** — what to change, not just what's wrong. Default lists P1+P2; `--full` adds
|
|
215
|
+
P3+P4.
|
|
216
|
+
|
|
217
|
+
```
|
|
218
|
+
### 6. Findings
|
|
219
|
+
|
|
220
|
+
- **P1** — <what's wrong>. → **Action:** <concrete change>. (`file:line`, ~effort) `[feasible]`
|
|
221
|
+
- **P2** — …
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
Each finding MUST carry a **verification-feasibility tag** in brackets at the end of the line, so
|
|
225
|
+
downstream task creation does not inherit an unactionable acceptance criterion:
|
|
226
|
+
|
|
227
|
+
- `[feasible]` — the recommendation is verifiable (a test, a CLI check, an observable behavior).
|
|
228
|
+
This is the default; most findings are feasible.
|
|
229
|
+
- `[stale]` — on re-check the finding no longer holds (the code already does the right thing, the
|
|
230
|
+
condition was misread). Do **not** file as a task — close inline with evidence. Catching this at
|
|
231
|
+
report time saves a no-op implementation task downstream.
|
|
232
|
+
- `[unverifiable]` — the recommendation cannot be confirmed with existing tooling (e.g. a
|
|
233
|
+
cache-hit finding with no per-step telemetry; a perf claim with no measurement loop). If filed as
|
|
234
|
+
a task, its acceptance criterion must be reframed to what *can* be verified (e.g. "ship the
|
|
235
|
+
lever; measured proof deferred"), or the task should be deferred until the missing tooling exists.
|
|
236
|
+
Do not let it become a normal implementation task — it will ship an unverifiable "improvement."
|
|
237
|
+
|
|
238
|
+
The tag is a prompt to whoever turns findings into tasks: `[stale]` → drop, `[unverifiable]` →
|
|
239
|
+
reframe or defer, `[feasible]` → proceed. A finding without a tag is treated as `[feasible]`.
|
|
240
|
+
Severity scale:
|
|
241
|
+
- **P1** — blocks correct use or causes drift/wrong output; fix before shipping the testee.
|
|
242
|
+
- **P2** — real friction or a latent correctness gap; fix soon. **Includes mandatory workspace-drift
|
|
243
|
+
finding:** when a drift row (`drift:external`) is present in the ledger, a P2 finding naming the
|
|
244
|
+
drifted paths is mandatory in the report (not optional). The finding states the run's evidence is
|
|
245
|
+
degraded, not voided. See [SKILL.md §Workspace-drift guard](../SKILL.md#workspace-drift-guard-r2--task-0296).
|
|
246
|
+
- **P3** — efficiency / DX / observation (includes the cache-health rule below).
|
|
247
|
+
- **P4** — nice-to-have, cosmetic, or speculative.
|
|
248
|
+
|
|
249
|
+
**Cache-health rule** (from [monitor-ledger.md](monitor-ledger.md)): if aggregate cache% < 50% or any
|
|
250
|
+
step < 40%, emit a **P3** — "Low cache hit rate — candidate for context-window or prompt trimming"
|
|
251
|
+
with the offending step(s). Absolute token totals from the heuristic are trend-only (`[unverifiable]`
|
|
252
|
+
as billable cost proof is expected).
|
|
253
|
+
|
|
254
|
+
**Migration grep rule.** When dogfooding migrations or retired surfaces, distinguish intentional
|
|
255
|
+
legacy-term mentions in guidance from live routed surfaces. Pair any broad grep for old skill or
|
|
256
|
+
command names with a live-surface grep over the command and agent roots before filing a stale-routing
|
|
257
|
+
finding. A deliberate rejection note in a reference file is not a live surface.
|
|
258
|
+
|
|
259
|
+
## Phase 4 — finalize-or-abort (non-skippable terminal gate)
|
|
260
|
+
|
|
261
|
+
Before the skill may stop (success, partial, fail, observe-only end, or abort), the driver MUST:
|
|
262
|
+
|
|
263
|
+
1. Set frontmatter `status: complete` or `status: aborted` (and `finished_at`).
|
|
264
|
+
2. **Structure scrub (@1.2):** all six mandatory section headings exist **exactly once each**
|
|
265
|
+
(`### 1.` … `### 6.` — a duplicated heading refuses `complete`); §5 Issues carries both
|
|
266
|
+
`#### Fixed` and `#### Unresolved` (`(none)` when empty); unfinished narrative uses
|
|
267
|
+
`⚠ incomplete — not reached`; no leftover "run in progress" markers survive finalization.
|
|
268
|
+
3. **Ledger cardinality (@1.2):** Monitor Ledger data rows == the `**Steps:** N derived, N executed` declared in
|
|
269
|
+
§2 (N/A steps documented explicitly as rows; drift rows count separately, not toward executed
|
|
270
|
+
steps — include `drift:external` rows in the table but subtract them from the executed count in
|
|
271
|
+
§2). A mismatch refuses `complete`.
|
|
272
|
+
4. Write the Cost block (method + confidence + Meter).
|
|
273
|
+
5. **R2 drift check at finalize.** If a workspace fingerprint was recorded, re-take snapshot
|
|
274
|
+
and diff against baseline minus run-touched files. Detected drift → append `drift:external`
|
|
275
|
+
ledger row + mandatory P2 finding. See [SKILL.md §Workspace-drift guard](../SKILL.md#workspace-drift-guard-r2--task-0296).
|
|
276
|
+
6. Sync final content to **both** live and report paths.
|
|
277
|
+
7. **Footer mandatory (@1.2):** print the mandatory summary footer with **both** paths always,
|
|
278
|
+
and mirror the footer block at the **end of the report file**. A report whose body lacks the
|
|
279
|
+
footer cannot set `status: complete`.
|
|
280
|
+
8. **Self-validate (task 0278 R6):** run
|
|
281
|
+
`bun plugins/sp/scripts/dogfood-testing/validate-report.ts --file <report-path>` before
|
|
282
|
+
claiming `status: complete`. Exit 2 → `status: aborted` + list error codes under
|
|
283
|
+
`#### Unresolved` (never force complete on a non-@1.2 shape).
|
|
284
|
+
9. **Refusal rule (@1.2):** when any check above fails, set `status: aborted` and list every
|
|
285
|
+
failed check under §5 `#### Unresolved` — never force `complete`.
|
|
286
|
+
|
|
287
|
+
Any early-exit path still runs this checklist. Stopping without it is a **driver contract violation**.
|
|
288
|
+
|
|
289
|
+
## Mandatory Summary Footer
|
|
290
|
+
|
|
291
|
+
Print **after every run, inline, always** — it is the last thing the user sees.
|
|
292
|
+
|
|
293
|
+
```
|
|
294
|
+
── Dogfood Summary ──
|
|
295
|
+
Result: PASS (N fixed, N unresolved, N findings)
|
|
296
|
+
Tokens: ~N total | ~N cached (~X% hit rate) [~estimate]
|
|
297
|
+
|
|
298
|
+
Fixed issues:
|
|
299
|
+
• <label> (or: (none))
|
|
300
|
+
|
|
301
|
+
Unresolved issues:
|
|
302
|
+
• <label> (or: (none))
|
|
303
|
+
|
|
304
|
+
Findings (P1+P2):
|
|
305
|
+
• P? — <label> (or: (none))
|
|
306
|
+
|
|
307
|
+
[Live: .spur/run/dogfood/<run_id>.md]
|
|
308
|
+
[Report: docs/dogfood/YYYY-MM-DD-<slug>-dogfood.md]
|
|
309
|
+
[Task: <wbs>] ← only with --task
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
Rules:
|
|
313
|
+
- **Result** and **Tokens** lines are mandatory; always tag token numbers `[~estimate]`.
|
|
314
|
+
- List Fixed / Unresolved / Findings; print `(none)` when empty — never omit a sub-list.
|
|
315
|
+
- With `--full`, Findings include P3+P4.
|
|
316
|
+
- If PASS with zero issues and zero findings: collapse to one line `Result: PASS — no issues, no
|
|
317
|
+
findings.` (still print the Tokens line).
|
|
318
|
+
- **`[Live:]` and `[Report:]` are always printed** after a normal stop (not gated on `--save`).
|
|
319
|
+
- Print `--task` WBS only when that sink ran.
|
|
320
|
+
|
|
321
|
+
## Task sink — the `task check` L3 contract
|
|
322
|
+
|
|
323
|
+
`--task` files findings as a `review`-template task:
|
|
324
|
+
|
|
325
|
+
```bash
|
|
326
|
+
spur task create "<testee> dogfood findings" --template review --json
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
Write the **Unresolved issues** and **Findings** into the task's `#### Review Findings` table — one
|
|
330
|
+
row per item: `Severity` (`P1`–`P4`), `File`, `Finding`, `Recommendation`. That heading is a
|
|
331
|
+
sub-section of `### Background`, so:
|
|
332
|
+
|
|
333
|
+
```bash
|
|
334
|
+
spur task update <wbs> --section "Background" --from-file <path> # body starts with "#### Review Findings"
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
**Where the P-rows live, and how the L3 Review rule behaves.** The review template ships two tables:
|
|
338
|
+
`#### Review Findings` (under `### Background`) is the *input* you populate from the dogfood findings;
|
|
339
|
+
`### Review` is the *post-fix reflection* table, shipped as an **empty-cell scaffold**
|
|
340
|
+
(`| P1 | | | |`). `spur task check`'s L3 Review rule keys off `### Review`, not `#### Review Findings`:
|
|
341
|
+
|
|
342
|
+
- Write the dogfood findings into **`#### Review Findings`** (that is the `--task` sink target).
|
|
343
|
+
- Leave **`### Review`** as the shipped empty-cell scaffold. The hardened L3 rule tolerates the empty
|
|
344
|
+
scaffold **wherever `### Review` is optional** (review variant: `backlog`/`todo` — the freshly
|
|
345
|
+
created state) and only requires a *populated* P-table once `### Review` becomes **required**
|
|
346
|
+
(`wip`+). So a freshly created `review` task at `backlog`/`todo` passes `task check` with the
|
|
347
|
+
scaffold untouched — no hand-written P-row is needed, and a bare prose note in `### Review` is the
|
|
348
|
+
thing that errors (it is neither the scaffold nor a populated table).
|
|
349
|
+
|
|
350
|
+
Always verify with `spur task check <wbs> --json` before handoff; the sink path below writes only
|
|
351
|
+
`#### Review Findings` and leaves `### Review` as the scaffold.
|