@gobing-ai/spur 0.3.61 → 0.3.63
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/config.global.yaml +64 -57
- package/config/corpus-baseline.json +601 -49
- package/config/plugin-scripts.json +2 -2
- package/config/rules/boundary/config-loading-ownership.yaml +21 -0
- package/config/workflows/history-anatomy.yaml +395 -0
- package/package.json +9 -9
- package/plugins/sp/README.md +19 -6
- package/plugins/sp/commands/dev-find-issue.md +25 -46
- package/plugins/sp/commands/dev-idea.md +3 -3
- package/plugins/sp/commands/dev-run.md +22 -3
- package/plugins/sp/lib/artifact-digest.generated.d.mts +7 -0
- package/plugins/sp/lib/artifact-digest.generated.mjs +48 -0
- package/plugins/sp/plugin.json +1 -1
- package/plugins/sp/references/environment-lens.md +66 -0
- package/plugins/sp/references/roles.md +5 -5
- package/plugins/sp/scripts/history-anatomy-cache.mjs +818 -0
- package/plugins/sp/scripts/history-anatomy-cache.ts +1014 -0
- package/plugins/sp/skills/dogfood-testing/references/report-template.md +30 -0
- package/plugins/sp/skills/history-anatomy/SKILL.md +67 -0
- package/plugins/sp/skills/history-anatomy/references/modes.md +82 -0
- package/plugins/sp/skills/history-anatomy/references/operations.md +80 -0
- package/plugins/sp/skills/history-anatomy/references/report-contract.md +183 -0
- package/plugins/sp/skills/spur-cli/references/agent.md +15 -6
- package/plugins/sp/skills/spur-cli/references/message.md +4 -2
- package/plugins/sp/skills/spur-dev/references/cross-cutting.md +6 -4
- package/plugins/sp/skills/spur-dev/references/dev-operations.md +2 -2
- package/plugins/sp/skills/spur-dev/references/execution-batch.md +14 -1
- package/plugins/sp/skills/spur-dev/references/execution-workflow.md +7 -0
- package/plugins/sp/skills/spur-dev/references/flag-glossary.md +25 -13
- package/spur.js +1958 -1133
- package/web/_astro/{BoardApp.CBIzcvqi.js → BoardApp.CKolAjUz.js} +102 -102
- package/web/_astro/BoardApp.DXD--ybM.js +1 -0
- package/web/_astro/{TaskDetail.D2N60cfE.js → TaskDetail.Bre7G4gC.js} +1 -1
- package/web/_astro/{arc.D-EfJJwf.js → arc.7luwOGiC.js} +1 -1
- package/web/_astro/{architectureDiagram-3BPJPVTR.CgvTTzqp.js → architectureDiagram-3BPJPVTR.F6KaHXp-.js} +1 -1
- package/web/_astro/{blockDiagram-GPEHLZMM.CnOohvvn.js → blockDiagram-GPEHLZMM.CCGHeRVi.js} +1 -1
- package/web/_astro/{c4Diagram-AAUBKEIU.BFcBGUy_.js → c4Diagram-AAUBKEIU.CpqewGmd.js} +1 -1
- package/web/_astro/channel.DxfOFf1l.js +1 -0
- package/web/_astro/{chunk-2J33WTMH.C-6MR-XY.js → chunk-2J33WTMH.CB9vKa5F.js} +1 -1
- package/web/_astro/{chunk-4BX2VUAB.BN4LP5AR.js → chunk-4BX2VUAB.ifGXoUA3.js} +1 -1
- package/web/_astro/{chunk-55IACEB6.tUJ_CTtZ.js → chunk-55IACEB6.VIaRo7l8.js} +1 -1
- package/web/_astro/{chunk-727SXJPM.BNCk-sxv.js → chunk-727SXJPM.DzPE41OS.js} +1 -1
- package/web/_astro/{chunk-AQP2D5EJ.BkpFIbNa.js → chunk-AQP2D5EJ.UF2QRXYF.js} +1 -1
- package/web/_astro/{chunk-FMBD7UC4.DcSZ87PN.js → chunk-FMBD7UC4.D2zXKa1R.js} +1 -1
- package/web/_astro/{chunk-ND2GUHAM.BkLvHFFf.js → chunk-ND2GUHAM.Cb9bDyvx.js} +1 -1
- package/web/_astro/{chunk-QZHKN3VN.HOdgszax.js → chunk-QZHKN3VN.nUKFBiLD.js} +1 -1
- package/web/_astro/{classDiagram-4FO5ZUOK.CWfRiY6b.js → classDiagram-4FO5ZUOK.DZg9K9mO.js} +1 -1
- package/web/_astro/{classDiagram-v2-Q7XG4LA2.CWfRiY6b.js → classDiagram-v2-Q7XG4LA2.DZg9K9mO.js} +1 -1
- package/web/_astro/{cose-bilkent-S5V4N54A.C6j4PxoN.js → cose-bilkent-S5V4N54A.D9STo90d.js} +1 -1
- package/web/_astro/{dagre-BM42HDAG.BATZG1II.js → dagre-BM42HDAG.D3IbwhHz.js} +1 -1
- package/web/_astro/{diagram-2AECGRRQ.B0f5yY6x.js → diagram-2AECGRRQ.BWTDxBe9.js} +1 -1
- package/web/_astro/{diagram-5GNKFQAL.Bewupqv0.js → diagram-5GNKFQAL.XnXlonHG.js} +1 -1
- package/web/_astro/{diagram-KO2AKTUF.C23r1tB2.js → diagram-KO2AKTUF.CywOngCO.js} +1 -1
- package/web/_astro/{diagram-LMA3HP47.DUErdBOR.js → diagram-LMA3HP47.DY1D21Iu.js} +1 -1
- package/web/_astro/{diagram-OG6HWLK6.BubmwAjb.js → diagram-OG6HWLK6.DQxb59KA.js} +1 -1
- package/web/_astro/{erDiagram-TEJ5UH35.BE_Qs5mv.js → erDiagram-TEJ5UH35.CF2U-pQZ.js} +1 -1
- package/web/_astro/{flowDiagram-I6XJVG4X.COWdbzon.js → flowDiagram-I6XJVG4X.BJK4M3in.js} +1 -1
- package/web/_astro/{ganttDiagram-6RSMTGT7.5EGYC4MK.js → ganttDiagram-6RSMTGT7.BSniMzdB.js} +1 -1
- package/web/_astro/{gitGraphDiagram-PVQCEYII.bUUV7iEw.js → gitGraphDiagram-PVQCEYII.Dxg-yRov.js} +1 -1
- package/web/_astro/index.BVXdIsZV.css +1 -0
- package/web/_astro/{infoDiagram-5YYISTIA.CbiInFvz.js → infoDiagram-5YYISTIA.BY4CgO_n.js} +1 -1
- package/web/_astro/{ishikawaDiagram-YF4QCWOH.CB7lrSsJ.js → ishikawaDiagram-YF4QCWOH.BmWDZtwF.js} +1 -1
- package/web/_astro/{journeyDiagram-JHISSGLW.rhGZgWt8.js → journeyDiagram-JHISSGLW.CpB1YWDP.js} +1 -1
- package/web/_astro/{kanban-definition-UN3LZRKU.DPeZD_lP.js → kanban-definition-UN3LZRKU.k-fukQX9.js} +1 -1
- package/web/_astro/{linear.l60Nyp5b.js → linear.BNNCobvI.js} +1 -1
- package/web/_astro/{mermaid.core.DmtMJcmL.js → mermaid.core.DnpzzuPU.js} +4 -4
- package/web/_astro/{mindmap-definition-RKZ34NQL.Cc47AcCn.js → mindmap-definition-RKZ34NQL.D9NnlLBu.js} +1 -1
- package/web/_astro/{pieDiagram-4H26LBE5.B8cN-S9g.js → pieDiagram-4H26LBE5.CKhoMiyC.js} +1 -1
- package/web/_astro/{quadrantDiagram-W4KKPZXB.DY1FN89L.js → quadrantDiagram-W4KKPZXB.BkAygRlm.js} +1 -1
- package/web/_astro/{requirementDiagram-4Y6WPE33.CnM6VbV8.js → requirementDiagram-4Y6WPE33.CX8ibmwc.js} +1 -1
- package/web/_astro/{sankeyDiagram-5OEKKPKP.B9DcGfNV.js → sankeyDiagram-5OEKKPKP.Dvurpa0Y.js} +1 -1
- package/web/_astro/{sequenceDiagram-3UESZ5HK.ymxaNlAY.js → sequenceDiagram-3UESZ5HK.veO8c2tk.js} +1 -1
- package/web/_astro/{stateDiagram-AJRCARHV.DDOJ3d8P.js → stateDiagram-AJRCARHV.DpMr4CO3.js} +1 -1
- package/web/_astro/{stateDiagram-v2-BHNVJYJU.Ck0Nb_KY.js → stateDiagram-v2-BHNVJYJU.CKjso86_.js} +1 -1
- package/web/_astro/{timeline-definition-PNZ67QCA.BNOvZwAN.js → timeline-definition-PNZ67QCA.DayoPp_2.js} +1 -1
- package/web/_astro/{vennDiagram-CIIHVFJN.D3k5ivSF.js → vennDiagram-CIIHVFJN.XNHf04O9.js} +1 -1
- package/web/_astro/{wardley-L42UT6IY.BylaxVqn.js → wardley-L42UT6IY.CpM_031g.js} +1 -1
- package/web/_astro/{wardleyDiagram-YWT4CUSO.HLNtFUm9.js → wardleyDiagram-YWT4CUSO.lIAjSkZJ.js} +1 -1
- package/web/_astro/{xychartDiagram-2RQKCTM6.B-WooKSU.js → xychartDiagram-2RQKCTM6.D8_2K6U1.js} +1 -1
- package/web/index.html +2 -2
- package/plugins/sp/commands/dev-history-load.md +0 -63
- package/plugins/sp/scripts/history-load.mjs +0 -268
- package/plugins/sp/scripts/history-load.ts +0 -400
- package/web/_astro/BoardApp.BtRfVADq.js +0 -1
- package/web/_astro/channel.kIu33Gui.js +0 -1
- package/web/_astro/index.Cestp9nh.css +0 -1
|
@@ -237,6 +237,36 @@ downstream task creation does not inherit an unactionable acceptance criterion:
|
|
|
237
237
|
|
|
238
238
|
The tag is a prompt to whoever turns findings into tasks: `[stale]` → drop, `[unverifiable]` →
|
|
239
239
|
reframe or defer, `[feasible]` → proceed. A finding without a tag is treated as `[feasible]`.
|
|
240
|
+
|
|
241
|
+
**Optional class tag (environment lens, task 0686).** A finding line may carry one closed class
|
|
242
|
+
tag — `environment` | `testee` | `waste` — positioned immediately after the em dash and distinct
|
|
243
|
+
from the trailing feasibility tag:
|
|
244
|
+
|
|
245
|
+
```
|
|
246
|
+
- **P2** — [environment] <what's wrong>. → **Action:** <concrete change>. (`file:line`, ~effort) `[feasible]`
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
Omitting the class preserves the current line shape; untagged findings remain valid and the
|
|
250
|
+
protocol stays `sp:dogfood-testing@1.2` (the validator gains no required field; the cache-health
|
|
251
|
+
P3 above needs no class).
|
|
252
|
+
|
|
253
|
+
- `testee` — a defect in the testee's contract (the protocol the run grades). Bounded fix-mode
|
|
254
|
+
may repair it, unchanged.
|
|
255
|
+
- `environment` — a steering/placement/check-shaped observation projected from the
|
|
256
|
+
[environment-improvement lens](../../../references/environment-lens.md), which owns the
|
|
257
|
+
category table and the placement rule. **Proposal-only:** even under `--max-retry N`, bounded
|
|
258
|
+
retries never `Edit` or `Write` `AGENTS.md`, `CLAUDE.md`, skills, rules, numbered docs, or
|
|
259
|
+
plugin references for an environment-tagged finding — it stays a recommended action here.
|
|
260
|
+
- `waste` — a token/tool-waste diagnostic with no missing environment affordance behind it.
|
|
261
|
+
|
|
262
|
+
Class, not the cited file path, decides whether bounded fix may mutate. A session mistake a
|
|
263
|
+
linter, typechecker, test, or filesystem gate could have caught is `environment`, and its
|
|
264
|
+
recommended action proposes a new-or-tighter automated check — never another sentence in an
|
|
265
|
+
always-loaded steering file. Missed coding standards are `environment` owned by a review path
|
|
266
|
+
(`sp:code-verification`, `sp:code-review`, or pipeline review) — never the implementer skill;
|
|
267
|
+
navigation friction and dead always-loaded instructions are likewise `environment`, not
|
|
268
|
+
`testee`.
|
|
269
|
+
|
|
240
270
|
Severity scale:
|
|
241
271
|
|
|
242
272
|
- **P1** — blocks correct use or causes drift/wrong output; fix before shipping the testee.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: history-anatomy
|
|
3
|
+
description: "Independent owner of diagnostic interpretation over already-imported history — the daily/ad-hoc mode contract, a closed finding taxonomy, the twelve-section report contract, and the enrich/validate rubrics. Triggers: history-anatomy, run the daily report, ad-hoc diagnosis, find issues over history."
|
|
4
|
+
license: Apache-2.0
|
|
5
|
+
version: 1.0.0
|
|
6
|
+
metadata:
|
|
7
|
+
author: spur
|
|
8
|
+
platforms: "claude-code,codex,openclaw,opencode,antigravity,pi"
|
|
9
|
+
category: analysis-core
|
|
10
|
+
interactions:
|
|
11
|
+
- pipeline
|
|
12
|
+
- inversion
|
|
13
|
+
pipeline_steps:
|
|
14
|
+
- report
|
|
15
|
+
- identify
|
|
16
|
+
- propose
|
|
17
|
+
- generate
|
|
18
|
+
openclaw:
|
|
19
|
+
emoji: "🩺"
|
|
20
|
+
see_also:
|
|
21
|
+
- sp:issue-finding
|
|
22
|
+
- sp:spur-cli
|
|
23
|
+
- sp:spur-dev
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
# sp:history-anatomy
|
|
27
|
+
|
|
28
|
+
Owns **interpretation only** over already-imported history. It decides which arguments are legal
|
|
29
|
+
in which mode, what counts as evidence, how findings are keyed and graded, and what a published
|
|
30
|
+
report must contain, plus the rubrics its `enrich` and `validate` operations follow. It never
|
|
31
|
+
launches a workflow, never reprocesses raw history files, and never mutates the corpus, docs, or sources —
|
|
32
|
+
all orchestration lives in `history-anatomy.yaml` (0660), not here.
|
|
33
|
+
|
|
34
|
+
This body routes to the three references; the procedure lives there (the BODY_BUDGET shape — a
|
|
35
|
+
fresh skill cannot be added to the BASELINE exemption map).
|
|
36
|
+
|
|
37
|
+
**Choose the mode first.** The single entry is `--mode daily|ad-hoc` (default `daily`):
|
|
38
|
+
`references/modes.md`.
|
|
39
|
+
|
|
40
|
+
**Then hold the report to the contract.** Every report must contain the twelve sections and every
|
|
41
|
+
finding the full field set, with evidence rules and an explicit comparability verdict:
|
|
42
|
+
`references/report-contract.md`.
|
|
43
|
+
|
|
44
|
+
**Then apply the operations.** The workflow calls `enrich` to author the model half, and
|
|
45
|
+
`validate` to gate a candidate report; neither operation launches a workflow:
|
|
46
|
+
`references/operations.md`.
|
|
47
|
+
|
|
48
|
+
## Primary directive
|
|
49
|
+
|
|
50
|
+
- The artifact is the only evidence plane. A dimension the forensics artifact cannot support is a
|
|
51
|
+
**telemetry gap** reported as `not available` — never a raw history-file fallback.
|
|
52
|
+
- Every causal claim needs **two independent signals** (or one labelled hypothesis with a
|
|
53
|
+
confirmation path). Every finding carries at least one evidence anchor. No anchor, no finding.
|
|
54
|
+
- The report never states a trend, delta, or percentage it cannot support — an insufficient or
|
|
55
|
+
materially different baseline renders `not comparable`, with no fabricated comparison.
|
|
56
|
+
- Findings are keyed on a **stable key**, never the prose title, so rewording never reclassifies
|
|
57
|
+
recurrence.
|
|
58
|
+
- Remediation options are **proposals only**: an owner surface, expected impact, a verification
|
|
59
|
+
method, and reversibility. No applied change, diff, or command the report claims to have run.
|
|
60
|
+
|
|
61
|
+
## Read the references
|
|
62
|
+
|
|
63
|
+
| Reference | Owns |
|
|
64
|
+
| --- | --- |
|
|
65
|
+
| [`references/modes.md`](references/modes.md) | The daily/ad-hoc mode matrix, bounds normalization, the DST-aware calendar-day rule, and the fail-loud message shape. |
|
|
66
|
+
| [`references/report-contract.md`](references/report-contract.md) | The twelve sections (in order), the per-finding field set, the closed category vocabulary, the stable-key grammar, the evidence rules, comparison semantics, recurrence classes, and the positive-pattern / remediation standards. |
|
|
67
|
+
| [`references/operations.md`](references/operations.md) | The `enrich` and `validate` operation rubrics; neither launches a workflow. |
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Mode contract — `sp:history-anatomy` (HA-S1, 0658)
|
|
2
|
+
|
|
3
|
+
The skill resolves exactly two modes. Everything else fails loud. This matrix is the enforcement
|
|
4
|
+
surface the workflow (0660) and the skill share; keep the vocabulary frozen.
|
|
5
|
+
|
|
6
|
+
## Mode vocabulary (frozen)
|
|
7
|
+
|
|
8
|
+
- Modes: `daily` | `ad-hoc`.
|
|
9
|
+
- Unsupported value literal: `not available`.
|
|
10
|
+
|
|
11
|
+
## Resolution rule
|
|
12
|
+
|
|
13
|
+
`--mode <value>` selects the mode. If `--mode` is omitted, the resolved mode is **`daily`** and the
|
|
14
|
+
resolved window is the **current local calendar day**.
|
|
15
|
+
|
|
16
|
+
## `--mode daily` (default)
|
|
17
|
+
|
|
18
|
+
| Allowed | Behavior |
|
|
19
|
+
| --- | --- |
|
|
20
|
+
| (none) | Default window = the current local calendar day. |
|
|
21
|
+
| `--date <YYYY-MM-DD>` | Selects that local calendar day as the window. |
|
|
22
|
+
|
|
23
|
+
Rejected arguments (each fails loud, naming the offending argument):
|
|
24
|
+
|
|
25
|
+
| Argument | Why rejected |
|
|
26
|
+
| --- | --- |
|
|
27
|
+
| focus text (positional) | Daily mode has no focus string. |
|
|
28
|
+
| `--since` / `--until` | Daily always uses the calendar-day window. |
|
|
29
|
+
| `--output` | Daily always writes to the run directory (see 0660). |
|
|
30
|
+
|
|
31
|
+
A daily invocation must print the normalized **inclusive ISO bounds** and the timezone used, so the
|
|
32
|
+
wall-clock window is auditable.
|
|
33
|
+
|
|
34
|
+
## `--mode ad-hoc`
|
|
35
|
+
|
|
36
|
+
Requires a **non-empty focus** and **two ordered inclusive bounds**.
|
|
37
|
+
|
|
38
|
+
| Argument | Rule |
|
|
39
|
+
| --- | --- |
|
|
40
|
+
| focus (positional) | Required; a missing or empty focus fails loud. |
|
|
41
|
+
| `--since <iso>` | Required; the inclusive lower bound. |
|
|
42
|
+
| `--until <iso>` | Required; must be present with `--since`; must not be earlier than `--since`. |
|
|
43
|
+
| `--output <path>` | Optional; when present, writes to that explicit path. When absent, writes to the run directory. |
|
|
44
|
+
|
|
45
|
+
Rejected arguments (each fails loud, naming the offending argument):
|
|
46
|
+
|
|
47
|
+
| Argument | Why rejected |
|
|
48
|
+
| --- | --- |
|
|
49
|
+
| `--date` | Ad-hoc windows are explicit bounds, not a single date. |
|
|
50
|
+
| `--recompute` | Ad-hoc never recomputes a cache (0660 owns the cache branch). |
|
|
51
|
+
|
|
52
|
+
## Bounds normalization
|
|
53
|
+
|
|
54
|
+
Normalize both bounds to inclusive ISO-8601 instants. The report prints the normalized bounds and
|
|
55
|
+
the timezone used.
|
|
56
|
+
|
|
57
|
+
## DST-aware calendar-day rule
|
|
58
|
+
|
|
59
|
+
`--date <YYYY-MM-DD>` must span the **full local calendar day including any DST shift** — it is
|
|
60
|
+
never a fixed 24-hour offset from local midnight.
|
|
61
|
+
|
|
62
|
+
- Resolve the local timezone (the operator's configured zone; state it in the report).
|
|
63
|
+
- The interval runs from the day's first local instant to the day's last local instant.
|
|
64
|
+
- On a 23-hour or 25-hour daylight-saving day, the interval is that actual length, not 24 hours.
|
|
65
|
+
- The bounds are NOT computed as `midnight + 24h`.
|
|
66
|
+
|
|
67
|
+
This is what makes a daily report's window reproducible across DST transitions.
|
|
68
|
+
|
|
69
|
+
## Fail-loud message shape
|
|
70
|
+
|
|
71
|
+
Every rejection names the offending argument and the rule it violated, e.g.:
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
--mode daily rejects "focus text" (daily mode has no focus string)
|
|
75
|
+
--mode ad-hoc requires a non-empty focus
|
|
76
|
+
--mode ad-hoc: --until is missing --since
|
|
77
|
+
--mode ad-hoc: --until (2026-08-01T00:00:00Z) is earlier than --since (2026-08-02T00:00:00Z)
|
|
78
|
+
--mode ad-hoc rejects --date (ad-hoc uses explicit --since/--until bounds)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
A combined conflict (e.g. `--mode daily --since X`) reports **each** offending argument it can
|
|
82
|
+
attribute; at minimum it names the first conflicting one.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Operations — `sp:history-anatomy` (HA-S1, 0658)
|
|
2
|
+
|
|
3
|
+
The skill exposes exactly two operations, invoked by `history-anatomy.yaml` (0660):
|
|
4
|
+
|
|
5
|
+
- `enrich` — the model is given the rendered forensics artifacts (current + baseline) and authors
|
|
6
|
+
the model half of the report.
|
|
7
|
+
- `validate` — the model is given a candidate report and independently checks its evidence claims
|
|
8
|
+
against the artifacts.
|
|
9
|
+
|
|
10
|
+
Both are **skill operations**, not workflows. **Neither operation launches a workflow** — that is
|
|
11
|
+
the recursion guard. This is why the rubric lives here, single-sourced, rather than being
|
|
12
|
+
duplicated into the YAML: the rubric cannot recurse.
|
|
13
|
+
|
|
14
|
+
## Invocation contract
|
|
15
|
+
|
|
16
|
+
| Operation | Input | Output |
|
|
17
|
+
| --- | --- | --- |
|
|
18
|
+
| `enrich` | current forensics artifact + baseline artifact (plain `HistoryArtifact` JSON) | the model-authored report sections (Baseline comparison, Findings, Recurrence ledger, Remediation options, Performance analysis, Workflow and process improvements, Report-only advisories, Positive patterns) meeting the report contract |
|
|
19
|
+
| `validate` | a candidate report + the current/baseline artifacts | a PASS / FAIL verdict with per-finding and per-section evidence checks, naming any failing rule |
|
|
20
|
+
|
|
21
|
+
Freeze these operation names and this input/output contract — 0660 consumes them verbatim.
|
|
22
|
+
|
|
23
|
+
## `enrich` rubric
|
|
24
|
+
|
|
25
|
+
Given the current and baseline artifacts, author the model half of the report. Apply, in order:
|
|
26
|
+
|
|
27
|
+
1. **Scope and provenance** + **Executive summary** + **Evidence ledger** are populated from the
|
|
28
|
+
artifact and rendered deterministically (or stated as the artifact's own data). The model
|
|
29
|
+
authors only the sections listed as model-authored.
|
|
30
|
+
2. **Baseline comparison** — apply the comparison semantics: daily → immediately preceding local
|
|
31
|
+
calendar day; ad-hoc → immediately preceding equal-duration window. If baseline coverage is
|
|
32
|
+
insufficient or materially different, emit `not comparable` and **no** trend/delta/percentage.
|
|
33
|
+
3. **Findings** — each with the full per-finding field set (key, category, impact, trend,
|
|
34
|
+
observation, inference, confidence, contradictions, evidenceAnchor, severity, reproCommand,
|
|
35
|
+
ownerSurface). Categories from the closed vocabulary; stable keys of the form
|
|
36
|
+
`<category>:<owner-surface>:<signal>`. Severity is the closed P1/P2/P3 vocabulary and is
|
|
37
|
+
orthogonal to confidence; reproCommand reproduces the observation verbatim; ownerSurface names
|
|
38
|
+
the concrete owning surface (file/package/command), consistent with the key's middle segment.
|
|
39
|
+
4. **Recurrence ledger** — classify every finding against the baseline on the **stable key**.
|
|
40
|
+
5. **Telemetry gaps** — every dimension the artifact cannot support, rendered `not available`.
|
|
41
|
+
6. **Remediation options** — proposals only (owner surface, expected impact, verification method,
|
|
42
|
+
reversibility), plus the printed `spur task create` handoff invocation carrying the finding's
|
|
43
|
+
stable key for accepted proposals. No applied change/diff/auto-write to the corpus.
|
|
44
|
+
7. **Report-only advisories** — repeated identical tool-and-argument signatures surfaced with
|
|
45
|
+
repetition counts; proposes no automatic interruption (report-only, 0680 R5).
|
|
46
|
+
8. **Positive patterns** — same evidence standard as problems.
|
|
47
|
+
|
|
48
|
+
Run-cost note (0680 R6): Performance analysis reports what this run's chained `agent.run`
|
|
49
|
+
stages cost using the pairing analytics fold (totalCostUsd / meanDurationMs per pairing); a
|
|
50
|
+
pairing without cost signal renders `not available`, never zero.
|
|
51
|
+
|
|
52
|
+
Never fabricate a value, a trend, an anchor, or an applied fix. Never launch a workflow.
|
|
53
|
+
|
|
54
|
+
## `validate` rubric
|
|
55
|
+
|
|
56
|
+
Given a candidate report and the artifacts, independently verify:
|
|
57
|
+
|
|
58
|
+
- **Twelve-section completeness and order** — all twelve section names present in the frozen
|
|
59
|
+
order; none renamed/omitted.
|
|
60
|
+
- **Per-finding fields** — every finding (problem and positive) carries key, category, impact,
|
|
61
|
+
trend, observation, inference, confidence, contradictions, evidenceAnchor, severity (P1/P2/P3),
|
|
62
|
+
reproCommand, ownerSurface; category in the closed vocabulary; stable-key grammar. A finding
|
|
63
|
+
missing any triage field FAILs (the deterministic gate enforces the same set).
|
|
64
|
+
- **Remediation handoff** — each accepted-proposal handoff carries a `spur task create`
|
|
65
|
+
invocation naming the finding's stable key; no auto-written tasks.
|
|
66
|
+
- **Evidence anchors** — every finding has at least one verifiable anchor; no anchor → FAIL.
|
|
67
|
+
- **Causality gate** — a causal claim with one signal must be labelled a hypothesis with a
|
|
68
|
+
confirmation path; otherwise FAIL.
|
|
69
|
+
- **Inference names observations** — an inference that does not name its supporting observations
|
|
70
|
+
FAILs.
|
|
71
|
+
- **Comparability** — a `not comparable` baseline must state no trend/delta/percentage; a stated
|
|
72
|
+
trend must be supported by a comparable baseline.
|
|
73
|
+
- **Recurrence integrity** — classification is consistent with the stable keys (a rewording must
|
|
74
|
+
not flip a recurring finding to new).
|
|
75
|
+
- **Positive patterns** — held to the same standard; an anchor-less entry FAILs.
|
|
76
|
+
- **Remediation** — proposals only; any applied change, diff, or command the report claims to have
|
|
77
|
+
run FAILs.
|
|
78
|
+
|
|
79
|
+
Emit `PASS` only when every rule holds. On FAIL, name the section, the finding key, and the rule
|
|
80
|
+
violated. Never launch a workflow.
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
# Report contract — `sp:history-anatomy` (HA-S1, 0658)
|
|
2
|
+
|
|
3
|
+
The published report is the skill's contract. This reference owns the twelve sections (in order),
|
|
4
|
+
the per-finding field set, the closed category vocabulary, the stable-key grammar, the evidence
|
|
5
|
+
rules, comparison semantics, recurrence classes, and the positive-pattern / remediation standards.
|
|
6
|
+
|
|
7
|
+
## Twelve required sections (in order, frozen)
|
|
8
|
+
|
|
9
|
+
1. Scope and provenance
|
|
10
|
+
2. Executive summary
|
|
11
|
+
3. Baseline comparison
|
|
12
|
+
4. Findings
|
|
13
|
+
5. Recurrence ledger
|
|
14
|
+
6. Telemetry gaps
|
|
15
|
+
7. Remediation options
|
|
16
|
+
8. Performance analysis
|
|
17
|
+
9. Workflow and process improvements
|
|
18
|
+
10. Report-only advisories (0680 R5)
|
|
19
|
+
11. Positive patterns
|
|
20
|
+
12. Evidence ledger
|
|
21
|
+
|
|
22
|
+
These names are consumed verbatim by 0659's structure gate and 0660's validation stage. Do not
|
|
23
|
+
rename, reorder, omit, or restate them.
|
|
24
|
+
|
|
25
|
+
## Closed category vocabulary (frozen)
|
|
26
|
+
|
|
27
|
+
- Categories: `reliability` | `repetition` | `workflow` | `performance` | `coverage` |
|
|
28
|
+
`telemetry` | `positive`.
|
|
29
|
+
|
|
30
|
+
Every finding's category is drawn from this closed set. No category is invented — explicit
|
|
31
|
+
`category` values outside it fail the structure gate (`finding-invalid-category:<value>`), and so
|
|
32
|
+
do stable keys whose first segment falls outside it (`finding-invalid-key-category:<value>`,
|
|
33
|
+
task 0686). Environment-lens retro category names are encoded only in `<signal>` or the
|
|
34
|
+
owner-surface segment — never as a category. The authoritative seven-name projection table lives
|
|
35
|
+
in the [environment-improvement mapping](../../../references/environment-lens.md), which this
|
|
36
|
+
reference defers to rather than restates.
|
|
37
|
+
|
|
38
|
+
## Stable finding key (frozen)
|
|
39
|
+
|
|
40
|
+
Each finding carries a stable key of the form:
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
<category>:<owner-surface>:<signal>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
- `category` — one of the closed vocabulary above.
|
|
47
|
+
- `owner-surface` — the surface that would own a change (e.g. a module, command, or skill; free
|
|
48
|
+
text is allowed but must be stable across runs).
|
|
49
|
+
- `signal` — a concise, stable machine-readable identifier of the finding.
|
|
50
|
+
|
|
51
|
+
The key is the recurrence identity. Rewording a finding's title must **never** reclassify it.
|
|
52
|
+
|
|
53
|
+
## Per-finding field set
|
|
54
|
+
|
|
55
|
+
Every finding — problem and positive alike — carries the full field set:
|
|
56
|
+
|
|
57
|
+
| Field | Requirement |
|
|
58
|
+
| --- | --- |
|
|
59
|
+
| `key` | Stable `<category>:<owner-surface>:<signal>` key. |
|
|
60
|
+
| `category` | From the closed vocabulary, matching the key's first segment. |
|
|
61
|
+
| `impact` | What the situation costs or enables (qualitative, or a concrete number where supported). |
|
|
62
|
+
| `trend` | `new` / `recurring` / `regressed` / `improved` / `resolved` / `not-comparable` (see recurrence). |
|
|
63
|
+
| `observation` | What the artifacts show — evidence, not interpretation. |
|
|
64
|
+
| `inference` | What the observation is reasoned to mean; names its supporting observations. |
|
|
65
|
+
| `confidence` | Per-finding: `high` / `medium` / `low`. Never one blanket report-level score. |
|
|
66
|
+
| `contradictions` | Any contradicting signal shown beside the finding, not silently reconciled. |
|
|
67
|
+
| `evidenceAnchor` | At least one anchor to the forensics artifact or cited `file:line`. An entry with no anchor is invalid. |
|
|
68
|
+
| `severity` | Closed vocabulary `P1` / `P2` / `P3` — how much the finding matters. Orthogonal to `confidence`: severity orders work, confidence says how sure we are (0680 R1). The structure gate fails a finding without one. |
|
|
69
|
+
| `reproCommand` | The invocation that reproduces the observation — one command a reader can run verbatim (0680 R2). Gate-enforced. |
|
|
70
|
+
| `ownerSurface` | The concrete surface that owns the fix (a file path, package, or command), consistent with the key's `<owner-surface>` segment but named as a target rather than a slug (0680 R3). Gate-enforced. |
|
|
71
|
+
|
|
72
|
+
## Evidence rules
|
|
73
|
+
|
|
74
|
+
Enforcement rail for every claim:
|
|
75
|
+
|
|
76
|
+
1. **Causality needs two independent signals.** A causal claim supported by two or more
|
|
77
|
+
independent signals passes. Exactly one signal is not causation — it must be labelled a
|
|
78
|
+
**hypothesis** with a stated confirmation path.
|
|
79
|
+
2. **A process/workflow change needs recurrence** across two independent sessions, or a single
|
|
80
|
+
**high-impact contract violation cited at `file:line`**.
|
|
81
|
+
3. **Unsupported dimensions read `not available`** and are mirrored into the telemetry-gaps
|
|
82
|
+
section. Never a fabricated value, never a raw history-file fallback.
|
|
83
|
+
4. **Focus biases ranking, not collection.** A focus string changes finding ranking and emphasis;
|
|
84
|
+
it never suppresses material off-topic findings within the window.
|
|
85
|
+
5. **Every inference names its supporting observations.** An inference that does not name its
|
|
86
|
+
observations fails validation.
|
|
87
|
+
6. **Every finding has an evidence anchor.** No anchor, no finding — no row may be dropped because
|
|
88
|
+
it "lacks evidence" while still appearing in a summary.
|
|
89
|
+
|
|
90
|
+
## Comparison semantics
|
|
91
|
+
|
|
92
|
+
The baseline comparison states an explicit comparability verdict.
|
|
93
|
+
|
|
94
|
+
- **Daily** compares against the **immediately preceding local calendar day**.
|
|
95
|
+
- **Ad-hoc** compares against the **immediately preceding equal-duration window**.
|
|
96
|
+
- **Insufficient or materially different coverage** renders **`not comparable`**.
|
|
97
|
+
- A `not comparable` baseline states no trend, no delta, and no percentage. An unsupported
|
|
98
|
+
comparison is never fabricated.
|
|
99
|
+
|
|
100
|
+
## Recurrence ledger
|
|
101
|
+
|
|
102
|
+
Every finding is classified against the baseline using the **stable key**:
|
|
103
|
+
|
|
104
|
+
- `new` — not present in the baseline.
|
|
105
|
+
- `recurring` — present in the baseline with comparable severity.
|
|
106
|
+
- `regressed` — present but worse (severity, count, or impact increased).
|
|
107
|
+
- `improved` — present but better.
|
|
108
|
+
- `resolved` — present in the baseline but absent now.
|
|
109
|
+
- `not-comparable` — the baseline was `not comparable`.
|
|
110
|
+
|
|
111
|
+
Matching is on the stable key, never the prose title. Rewording a title between two runs must not
|
|
112
|
+
reclassify a recurring finding as new.
|
|
113
|
+
|
|
114
|
+
## Positive patterns
|
|
115
|
+
|
|
116
|
+
Positive entries are held to the **same evidence standard as problems**: they carry observation,
|
|
117
|
+
inference, confidence, and at least one evidence anchor. An entry without an anchor is invalid. The
|
|
118
|
+
section renders successful workflows, resolved past issues that stay resolved, and healthy,
|
|
119
|
+
repeating behavior worth keeping.
|
|
120
|
+
|
|
121
|
+
## Remediation options (proposals only)
|
|
122
|
+
|
|
123
|
+
Each option is a **proposal** that names:
|
|
124
|
+
|
|
125
|
+
- **owner surface** — who would apply it.
|
|
126
|
+
- **expected impact** — what it is expected to change.
|
|
127
|
+
- **verification method** — how the change would be confirmed.
|
|
128
|
+
- **reversibility** — whether and how it can be rolled back.
|
|
129
|
+
|
|
130
|
+
The report must contain **no applied change, no diff, and no command it claims to have run**. The
|
|
131
|
+
skill never applies a fix; it proposes one.
|
|
132
|
+
|
|
133
|
+
### Remediation handoff route (0680 R4)
|
|
134
|
+
|
|
135
|
+
For each proposal an operator accepts, the report supplies — printed in the report itself, never
|
|
136
|
+
executed — the `spur task create` invocation that lands it, carrying the proposal's finding
|
|
137
|
+
`key` in the task body so the next report classifies that finding as `resolved`. Auto-writing
|
|
138
|
+
to the task corpus from a model-authored report would bypass the CLI-gated write contract; the
|
|
139
|
+
operator remains the gate.
|
|
140
|
+
|
|
141
|
+
### Report-only advisories (0680 R5)
|
|
142
|
+
|
|
143
|
+
Section 10 is the standing home for observations that inform workflow hygiene but must never
|
|
144
|
+
trigger automatic interruption: repeated identical tool-and-argument signatures are surfaced
|
|
145
|
+
here with their repetition counts, proposing at most human-decided process changes. Nothing in
|
|
146
|
+
this section may drive automated behavior.
|
|
147
|
+
|
|
148
|
+
### Run-cost reporting (0680 R6)
|
|
149
|
+
|
|
150
|
+
Performance analysis states what the run itself cost: per-pairing `totalCostUsd` /
|
|
151
|
+
`meanDurationMs` figures flow from the pairing analytics fold (0679 repaired the payload
|
|
152
|
+
paths), so chained `agent.run` stages are reportable instead of "~unknown". Where no cost
|
|
153
|
+
signal exists for a pairing it renders `not available`, never zero.
|
|
154
|
+
|
|
155
|
+
## Projected candidates — section 9 (environment lens, task 0686)
|
|
156
|
+
|
|
157
|
+
Section 9 (Workflow and process improvements) stays additive report grammar: unprojected numbered
|
|
158
|
+
prose remains valid and gains no required fields. A candidate **projected** through the
|
|
159
|
+
[environment-improvement lens](../../../references/environment-lens.md) is a bullet beginning with
|
|
160
|
+
a backticked stable key (retro name in `<signal>` or owner surface, closed category first — e.g.
|
|
161
|
+
`workflow:agents-md:navigation`) and carries four bold fields, the same names remediation options
|
|
162
|
+
use:
|
|
163
|
+
|
|
164
|
+
```text
|
|
165
|
+
- `workflow:agents-md:navigation` — **owner surface:** `AGENTS.md` see_also. **expected impact:**
|
|
166
|
+
shorter file hunt. **verification method:** subsequent daily report key `resolved` or absent.
|
|
167
|
+
**reversibility:** revert the pointer.
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
A projected candidate cites its section-4 finding `key` when one exists. Reports remain
|
|
171
|
+
proposal-only: no applied change, no diff, and no command the report claims to have run.
|
|
172
|
+
|
|
173
|
+
## Evidence ledger
|
|
174
|
+
|
|
175
|
+
The final section lists, for every finding, the artifact anchor(s) and any cited `file:line`,
|
|
176
|
+
so a reader can verify the report's claims against the evidence plane.
|
|
177
|
+
|
|
178
|
+
## Truthfulness invariants
|
|
179
|
+
|
|
180
|
+
- `not available` is the true rendering for an unsupported dimension, never a masked gap.
|
|
181
|
+
- `not comparable` is the true rendering for an unsupported comparison, never a computed delta.
|
|
182
|
+
- No bounded leaderboard length is presented as a population total (see 0657 / ADR-080: the
|
|
183
|
+
coverage section reads `artifact.population` and renders `top N of M`).
|
|
@@ -23,9 +23,9 @@ that before using `run` for fan-out dispatch.
|
|
|
23
23
|
| ---- | ------- | --------- |
|
|
24
24
|
| `run <prompt>` | Execute a prompt or slash command via a coding agent | `--agent <name>` `--spec <id>` `--model <name>` `--mode <mode>` `--continue` `--cwd <path>` `--drain` `--json` |
|
|
25
25
|
| `loop` | Persistent self-draining inbox loop for a team member (supervisor-managed) | `--spec <id>` `--agent <id>` `--poll <ms>` |
|
|
26
|
-
| `wait <specId
|
|
26
|
+
| `wait [<specId>]` | Identity-pinned wait for an occupant run to reach a lifecycle state (G4 wave 2; `--role` selector per 0685) | `--role <name>` `--run <runId>` `--until <state>...` `--timeout <ms>` `--json` |
|
|
27
27
|
| `list` | List detected coding agents, or team agent specs with `--specs` | `--specs` `--json` |
|
|
28
|
-
| `doctor [agent]` | Check agent readiness | `--json` |
|
|
28
|
+
| `doctor [agent]` | Check agent readiness | `--json` `--probe-health` `--force-refresh` |
|
|
29
29
|
| `create <id>` | Write a team agent spec to `.spur/agents/<id>.yaml` | `--type` `--tags` `--model` `--autonomy` `--system-prompt` `--name` `--workspace` `--purpose` `--auto-start` `--no-identity-preamble` `--json` |
|
|
30
30
|
| `edit <id>` | Open an agent spec in `$EDITOR`, or print its path | - |
|
|
31
31
|
| `delete <id>` | Remove an agent spec | `--force` |
|
|
@@ -108,12 +108,18 @@ into `run` with `--drain` -> else sleep for `--poll` ms.
|
|
|
108
108
|
spur agent wait reviewer # default --until idle
|
|
109
109
|
spur agent wait reviewer --run R3 --until invoke-exit
|
|
110
110
|
spur agent wait reviewer --until working --until invoke-exit --timeout 30000 --json
|
|
111
|
+
spur agent wait --role reviewer # role-addressed: resolves to exactly one instance
|
|
111
112
|
```
|
|
112
113
|
|
|
113
114
|
`wait` pins an occupant's identity (`specId` + `runId` + `generation`) from the snapshot at wait
|
|
114
115
|
start, then polls until the first satisfied `--until` (OR). `--run` pins an explicit run; default
|
|
115
116
|
is the spec's latest run. Replacement, generation bump, or disappearance fails fast; a non-working
|
|
116
117
|
occupant that makes no progress inside the stall budget fails `wait_stalled`.
|
|
118
|
+
Addressing takes `<specId>` **or** `--role` — never both. `--role` resolves against materialized
|
|
119
|
+
instances (vocabulary = `AGENT_ROLE_NAMES` ∪ executor names); zero/multi matches are hard errors
|
|
120
|
+
naming `count=0` + candidates `none` or `count=N` + candidate ids
|
|
121
|
+
(`selector_unmatched` / `selector_ambiguous`, exit 1), an unknown name
|
|
122
|
+
exits 2 naming the accepted vocabulary. Resolution collapses onto the same identity pin.
|
|
117
123
|
|
|
118
124
|
### Flags
|
|
119
125
|
|
|
@@ -149,12 +155,15 @@ lists team agent specs (`.spur/agents/*.yaml`).
|
|
|
149
155
|
|
|
150
156
|
```bash
|
|
151
157
|
spur agent doctor # all detected agents
|
|
152
|
-
spur agent doctor claude # one agent
|
|
153
|
-
spur agent doctor
|
|
158
|
+
spur agent doctor claude # one agent (executor/agent name → detail block)
|
|
159
|
+
spur agent doctor coder # pipeline role id → eligible ladder with ELECTED marker
|
|
160
|
+
spur agent doctor --json # machine-readable (role selector: elected-first ordering)
|
|
154
161
|
```
|
|
155
162
|
|
|
156
|
-
Checks whether each agent is installed and ready to run.
|
|
157
|
-
|
|
163
|
+
Checks whether each agent is installed and ready to run. Text mode renders a capability table —
|
|
164
|
+
`STATUS EXECUTOR AGENT MODEL TIER VERSION ROLES` where TIER is the executor's *capability* tier
|
|
165
|
+
(`cheap|standard|capable-*`), MODEL the pinned config model (`—` when undeclared), and ROLES lists
|
|
166
|
+
candidate pipeline roles with `*` on the elected one. Exit `1` if any checked agent is not ready.
|
|
158
167
|
|
|
159
168
|
## `create` - author a team agent spec
|
|
160
169
|
|
|
@@ -19,7 +19,7 @@ use it well*.
|
|
|
19
19
|
|
|
20
20
|
| Verb | Purpose | Key flags |
|
|
21
21
|
| ---- | ------- | --------- |
|
|
22
|
-
| `send <body>` | Enqueue a message for an agent | `--to <id>` `--from <id>` `--wait` `--until <state>` `--timeout <ms>` `--json` |
|
|
22
|
+
| `send <body>` | Enqueue a message for an agent | `--to <id>` `--role <name>` `--from <id>` `--wait` `--until <state>` `--timeout <ms>` `--json` |
|
|
23
23
|
| `inbox` | List messages addressed to an agent | `--agent <id>` `--json` |
|
|
24
24
|
| `reply <msg-id> <body>` | Thread a reply to a message | `--json` |
|
|
25
25
|
| `watch` | Follow an agent inbox - surface new messages as they arrive | `--agent <id>` `--interval <ms>` `--json` |
|
|
@@ -34,6 +34,7 @@ spur message send "Please review PR 42" --to reviewer
|
|
|
34
34
|
spur message send "Task 0040 is blocked" --to worker-1 --from operator
|
|
35
35
|
spur message send "Done" --to planner --json
|
|
36
36
|
spur message send "Review 0042" --to reviewer --wait --until invoke-exit --timeout 30000
|
|
37
|
+
spur message send "Start the pass" --role reviewer # resolves to exactly one instance
|
|
37
38
|
```
|
|
38
39
|
|
|
39
40
|
Enqueues a durable message addressed to `--to <id>`. The recipient drains it on its next `agent run
|
|
@@ -47,7 +48,8 @@ wait; enqueue is **not** rolled back if the wait later fails.
|
|
|
47
48
|
|
|
48
49
|
| Flag | Purpose |
|
|
49
50
|
| ------ | --------- |
|
|
50
|
-
| `--to <id>` |
|
|
51
|
+
| `--to <id>` | Recipient agent id. Mutually exclusive with `--role`; exactly one of the two is required. |
|
|
52
|
+
| `--role <name>` | Address by Layer-1 role or executor name. Must resolve to exactly one materialized instance; zero (`count=0`, candidates `none`) or multi (`count=N` + candidates) matches are hard errors (exit 1); unknown name exits 2 naming the accepted vocabulary (`AGENT_ROLE_NAMES` ∪ executor names). Resolution yields the same spec-id path as `--to`; `--wait` snapshots that occupant pin. (0685 R6 / ADR-075 amendment) |
|
|
51
53
|
| `--from <id>` | Sender id (default: `operator`). |
|
|
52
54
|
| `--wait` | Block until the recipient reaches `--until` (snapshots occupant before send). |
|
|
53
55
|
| `--until <state>` | Wait target: `injected` \| `invoke-exit` (repeatable OR). Default `invoke-exit`. |
|
|
@@ -185,11 +185,13 @@ recovery (0482 R1). To confirm recovery is wired, watch the run log for
|
|
|
185
185
|
`Escalating: <executor> (tier <t>) failed with resource-exhaustion; retrying on <executor>` — that
|
|
186
186
|
line, not quota state, is the signal that the fallback ladder fired.
|
|
187
187
|
|
|
188
|
-
Do not read provider quota from `spur agent doctor`. The doctor resolves provider keys from
|
|
188
|
+
Do not read provider auth or quota from `spur agent doctor`. The doctor resolves provider keys from
|
|
189
189
|
`${PROVIDER}_API_KEY` env vars and cannot see an agent-owned credential store (e.g. omp's models
|
|
190
|
-
config), so
|
|
191
|
-
and
|
|
192
|
-
|
|
190
|
+
config), so it historically degraded to `status: usable · auth: no · model: unknown` for GLM-style
|
|
191
|
+
executors and was useless as a preflight gate. Feature B4 removed the auth signal from the surface
|
|
192
|
+
entirely (no column, no `authenticated` in `--json`) precisely so nothing can read it by mistake;
|
|
193
|
+
the precheck probe classifies on usability alone. Exhaustion is detected mid-run by the escalation
|
|
194
|
+
classifier, not by any preflight probe.
|
|
193
195
|
|
|
194
196
|
### Explicit subprocess surfaces are unchanged
|
|
195
197
|
|
|
@@ -68,7 +68,7 @@ each would be scope creep for one-liner procedures.
|
|
|
68
68
|
| 2 | review | `dev-review` | `Skill()` | `sp:code-verification` (`review`) + `sp:functional-review` + `sp:code-improvement` | `[<wbs\|path>] [--agent <inline\|auto\|name>] [--focus <dims>] [--fix (deprecated)]` |
|
|
69
69
|
| 3 | verify | `dev-verify` | `Skill()` | `sp:code-verification` (`verify`) | `<wbs> [--agent <inline\|auto\|name>] [--fix <none\|blockers-first\|all>] [--focus <lens>] [--bdd] [--auto] [--force] [--next] [--skip-shippable]` |
|
|
70
70
|
| 3a | verifyall | `dev-verifyall` | `Skill()` → agent | `sp:spur-dev` (`verifyall`) | `--tasks <selector> [--feature <id>] [--agent <inline\|auto\|name>] [--fix <none\|blockers-first\|all>] [--focus <lens>] [--bdd] [--auto] [--force] [--next] [--json] [--skip-shippable] [--worktree [<name>]]` |
|
|
71
|
-
| 4 | run | `dev-run` | `Skill()` | `sp:spur-dev` (`run` / `implement`) | `<wbs> [--mode <full\|implement>] [--agent <inline\|auto\|name>] [--auto] [--next] [--wrap] [--continue]` |
|
|
71
|
+
| 4 | run | `dev-run` | `Skill()` | `sp:spur-dev` (`run` / `implement`) | `<wbs> [--mode <full\|implement>] [--agent <inline\|auto\|name>] [--auto] [--next] [--wrap] [--continue] [--worktree [<name>]]` |
|
|
72
72
|
| 5 | refine | `dev-refine` | `Skill()` | `sp:spur-dev` (`refine`) | `<wbs> [--focus <mode>] [--description <text>] [--depth <standard\|ready>] [--agent <inline\|auto\|name>] [--auto] [--next]` |
|
|
73
73
|
| 5a | refineall | `dev-refineall` | `Skill()` | `sp:spur-dev` (`refineall`) | `--feature <id> \| --tasks <selector> [--focus <mode>] [--description <text>] [--depth <standard\|ready>] [--agent <inline\|auto\|name>] [--auto] [--keep-going] [--status <s>] [--json] [--worktree [<name>]]` |
|
|
74
74
|
| 6 | plan | `dev-plan` | `Skill()` | `sp:spur-dev` (`plan`) | `"<description>" [--feature <id>] [--parent <feature-id>] [--agent <inline\|auto\|name>] [--skip-design] [--auto] [--approve-taste]` |
|
|
@@ -140,7 +140,7 @@ must not be changed without updating the backing skill.
|
|
|
140
140
|
### 4. run
|
|
141
141
|
|
|
142
142
|
- **Purpose:** Run a task through the execution pipeline (full) or execute a single pipeline step (implement).
|
|
143
|
-
- **Inputs:** `<wbs>` (required). `--mode <full|implement>` selects the execution mode. `implement` invokes `sp:code-implementation` inline by default. Interactive `full` with omitted `--agent` or explicit `--agent inline` reads `task-pipeline.yaml` and drives its actions/guards in the host session — host-controlled and non-subprocess; **omitted** `--agent` keeps 0508 eligibility (eligible `agent.run` stages dispatch once to a native subagent, host fallback), while explicit `--agent inline` is the zero-dispatch carve-out (every stage executes in the invoking session). `--agent auto`, a name, or headless invocation launches the workflow subprocess. `--agent <inline|auto|name>` selects the execution surface (see [SSOT](cross-cutting.md#inline-default-execution-surface)). `--auto` skips the HITL approve gate / confirmations and propagates down the `--next` chain. `--next` controls chaining only and never changes the mode; a pipeline implement stage must invoke `/sp:dev-run <wbs> --mode implement`. On implement success with `--next`, transition `todo → wip → testing` through the FSM (guards honored — no `--no-lifecycle`) + chain to `/sp:dev-verify <wbs> --auto --next`. On a guard failure, stop as review-pending. **Partial-deliverable rule:** if the task ships only part of its requirements (e.g. an R1/R2 split with the rest in a follow-up task), the `## Solution` section must state that explicitly and the verify verdict will record the scope. `--wrap` hands off to `/sp:dev-wrap <wbs>` after the main step; the `--agent` selector is preserved into that handoff when supplied (omission remains omission), and the wrap hop reports its own trigger-3 subprocess override per the wrap contract.
|
|
143
|
+
- **Inputs:** `<wbs>` (required). `--mode <full|implement>` selects the execution mode. `implement` invokes `sp:code-implementation` inline by default. Interactive `full` with omitted `--agent` or explicit `--agent inline` reads `task-pipeline.yaml` and drives its actions/guards in the host session — host-controlled and non-subprocess; **omitted** `--agent` keeps 0508 eligibility (eligible `agent.run` stages dispatch once to a native subagent, host fallback), while explicit `--agent inline` is the zero-dispatch carve-out (every stage executes in the invoking session). `--agent auto`, a name, or headless invocation launches the workflow subprocess. `--agent <inline|auto|name>` selects the execution surface (see [SSOT](cross-cutting.md#inline-default-execution-surface)). `--auto` skips the HITL approve gate / confirmations and propagates down the `--next` chain. `--next` controls chaining only and never changes the mode; a pipeline implement stage must invoke `/sp:dev-run <wbs> --mode implement`. On implement success with `--next`, transition `todo → wip → testing` through the FSM (guards honored — no `--no-lifecycle`) + chain to `/sp:dev-verify <wbs> --auto --next`. On a guard failure, stop as review-pending. **Partial-deliverable rule:** if the task ships only part of its requirements (e.g. an R1/R2 split with the rest in a follow-up task), the `## Solution` section must state that explicitly and the verify verdict will record the scope. `--worktree [<name>]` runs the full pipeline inside an isolated git worktree (create or reuse; FF-merge on success, retain on failure) — the batch lifecycle in [execution-batch.md § Worktree isolation](execution-batch.md#worktree-isolation---worktree-name) applied to a batch of one; rejected with `--mode implement`. `--wrap` hands off to `/sp:dev-wrap <wbs>` after the main step; the `--agent` selector is preserved into that handoff when supplied (omission remains omission), and the wrap hop reports its own trigger-3 subprocess override per the wrap contract.
|
|
144
144
|
- **Backing:** `sp:spur-dev` skill — `run` operation for the full pipeline (the spine drives it); `sp:code-implementation` competency skill for the implement step (the spine dispatches to it).
|
|
145
145
|
- **Modes:**
|
|
146
146
|
- **`full`** (default): Drive the full pipeline — precheck → implement → test → review → approve(HITL) → verify → record → done. Interactive omit/inline uses [inline-pipeline-driver.md](inline-pipeline-driver.md) (host-controlled; eligible stages may use a native subagent); explicit/headless executor selection invokes `spur workflow run task-pipeline.yaml --vars '{"wbs":"<wbs>"}'` (with `profile: auto` when `--auto`). Both monitor/surface HITL and preserve the YAML gates. `--next` never changes this mode.
|
|
@@ -421,6 +421,15 @@ isolated git worktree instead of the operator's working directory. This section
|
|
|
421
421
|
lifecycle for the sequential batch loop. Per-task worktrees and `--mode parallel` isolation stay out
|
|
422
422
|
of scope (task 0142 Slice A); `--worktree --mode parallel` is rejected.
|
|
423
423
|
|
|
424
|
+
**Single-task `dev-run` (batch of one).** `/sp:dev-run <wbs> --worktree [<name>]` runs this same
|
|
425
|
+
lifecycle with a one-task loop: WT-1…WT-6 apply unchanged, the marker's `command` is `dev-run` and
|
|
426
|
+
its `selector` is the `<wbs>` (so WT-6's command+selector fallback resolves the resume), and the
|
|
427
|
+
derived branch/directory slug is the WBS — `sp/run-<wbs>-<short-id>`. The WT-4 success condition
|
|
428
|
+
"no failed task" reads as "the task reached terminal `done` with no failed stage"; a failing gate, a
|
|
429
|
+
non-PASS verify verdict, or a HITL pause that ends the run take the WT-5 retention path. Only the
|
|
430
|
+
full pipeline is eligible — `--worktree --mode implement` is rejected (WT-7), because that mode is
|
|
431
|
+
the pipeline's implement stage and already runs in the driver's tree.
|
|
432
|
+
|
|
424
433
|
One flag, two modes (see the glossary entry for the ownership rule). Bare `--worktree` is **create
|
|
425
434
|
mode** (cut a fresh branch + sibling tree). `--worktree <name>` is **reuse mode** (attach to a tree
|
|
426
435
|
that already exists); name resolution (§ WT-2 below) runs before WT-1. The deltas each mode applies
|
|
@@ -714,9 +723,13 @@ fallback, because `<name>` was explicit and unambiguous intent.
|
|
|
714
723
|
### WT-7 — Exclusions (R8)
|
|
715
724
|
|
|
716
725
|
- **`dev-next`** does not get `--worktree` — it dispatches a single step; per-step isolation is not
|
|
717
|
-
worth the worktree cost.
|
|
726
|
+
worth the worktree cost. `dev-run` is different: it drives a whole task pipeline, so it does get
|
|
727
|
+
the flag.
|
|
718
728
|
- **`--mode parallel`** is rejected when combined with `--worktree` — per-task worktrees and
|
|
719
729
|
parallel isolation remain task 0142 Slice A.
|
|
730
|
+
- **`--mode implement`** is rejected when combined with `--worktree` on `dev-run` — that mode *is*
|
|
731
|
+
the pipeline's implement stage (bug-742) and runs in whatever tree the driver set up; a second
|
|
732
|
+
worktree would split one task's evidence across two trees.
|
|
720
733
|
- **No** create-with-name (`--worktree <name>` never creates; an unresolvable name is an error),
|
|
721
734
|
no `--worktree-keep` variant, no auto-cleanup of stale worktrees or markers from prior runs.
|
|
722
735
|
|
|
@@ -100,6 +100,13 @@ cache-conservation discipline (`plugins/sp/skills/dogfood-testing/references/mon
|
|
|
100
100
|
> - Without `--auto`: warn the operator before calling `spur workflow run` and prompt for confirmation or a plan-item override via `--vars '{"maxImplementPlanItems":"<count>"}'`.
|
|
101
101
|
> - With `--auto`: automatically append `"maxImplementPlanItems": "<count>"` to `--vars` and log a single-line notice (e.g. `Notice: task <wbs> has N plan items (>8 default cap); injecting maxImplementPlanItems override`).
|
|
102
102
|
|
|
103
|
+
**`--worktree [<name>]` wraps Step 2, on either surface.** When `/sp:dev-run --mode full` carries
|
|
104
|
+
[`--worktree`](flag-glossary.md#flag-worktree), create or adopt the worktree *before* launching the
|
|
105
|
+
pipeline, `cd` into it (`spur workflow run` and the inline driver both resolve cwd from the process),
|
|
106
|
+
and merge-or-retain after the run reports. The lifecycle is
|
|
107
|
+
[execution-batch.md § Worktree isolation](execution-batch.md#worktree-isolation---worktree-name)
|
|
108
|
+
applied to a batch of one. Rejected with `--mode implement`.
|
|
109
|
+
|
|
103
110
|
**Choose the surface before execution.** In an interactive `/sp:dev-run --mode full` invocation,
|
|
104
111
|
omit/`--agent inline` selects the [inline pipeline driver](inline-pipeline-driver.md). Read the YAML
|
|
105
112
|
at invocation time, allocate the inline run id/session provenance, record `task run-link`, and walk
|