@gobing-ai/spur 0.4.16 → 0.4.18
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/workflows/task-pipeline.yaml +6 -6
- package/package.json +1 -1
- package/plugins/sp/README.md +3 -3
- package/plugins/sp/agents/super-reviewer.md +3 -1
- package/plugins/sp/commands/dev-find-conflict.md +18 -6
- package/plugins/sp/plugin.json +1 -1
- package/plugins/sp/skills/conflict-finding/SKILL.md +46 -16
- package/plugins/sp/skills/conflict-finding/references/comparison-protocol.md +4 -2
- package/plugins/sp/skills/conflict-finding/references/finding-contract.md +2 -2
- package/plugins/sp/skills/conflict-finding/references/remediation-routing.md +22 -3
- package/plugins/sp/skills/fleet-join/SKILL.md +2 -0
- package/plugins/sp/skills/spur-dev/references/cross-cutting.md +3 -2
- package/plugins/sp/skills/spur-dev/references/dev-operations.md +1 -1
- package/plugins/sp/skills/spur-dev/references/flag-glossary.md +8 -7
- package/spur.js +34 -4
|
@@ -661,12 +661,12 @@ states:
|
|
|
661
661
|
# which this pointer names.
|
|
662
662
|
input: >-
|
|
663
663
|
/sp:dev-review --tasks ${vars.wbs} --auto --focus ${vars.reviewFocus} Answer contract (full: super-reviewer Output
|
|
664
|
-
Format). Two artifacts: the `## Review` section (
|
|
665
|
-
(
|
|
666
|
-
(deriveVerifyConfidence), never the section's disposition level. End with one `Verdict: PASS|PARTIAL|FAIL` line
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
664
|
+
Format). Two artifacts: the `## Review` section (deriveReviewConfidence) and your captured answer
|
|
665
|
+
(`spur task verdict` input). The answer has one `Confidence: HIGH|MEDIUM|LOW` line, EVIDENCE-derived
|
|
666
|
+
(deriveVerifyConfidence), never the section's disposition level. End with one `Verdict: PASS|PARTIAL|FAIL` line after `| Req | Status | Evidence |` (one row per requirement; MET | PARTIAL | UNMET) and `| AC | Status |
|
|
667
|
+
Evidence Type | Evidence |` (one row per AC; MET | PARTIAL | UNMET | N/A). Evidence types (`+` ok): test
|
|
668
|
+
| command | static-ref | manual-review | llm-judge | n/a. Evidence cells cite a repo-root-relative `path:line`
|
|
669
|
+
(never `/tmp`: out-of-repo blocks done) or a named check. AC rows
|
|
670
670
|
key on the task's identities or a declared `AC-N` alias; a linked scenario covers its task and a task-local criterion
|
|
671
671
|
needs no feature credit. Open P1-P3 blocks completion.
|
|
672
672
|
# The captured review answer is the run's certification input (and the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gobing-ai/spur",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.18",
|
|
4
4
|
"description": "Spur CLI — local-first harness for mainstream coding agents: constraint checking, workflow orchestration, agent health, and history analytics. Bun-native; exposes the `spur` command.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"spur",
|
package/plugins/sp/README.md
CHANGED
|
@@ -319,7 +319,7 @@ surface or run one workflow. All skills target the same five core platforms: `cl
|
|
|
319
319
|
|
|
320
320
|
| Skill | Ver | Domain |
|
|
321
321
|
| --------------------------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
322
|
-
| `spur-dev` | 1.
|
|
322
|
+
| `spur-dev` | 1.2 | Thin orchestration spine — drives planning→execution, gates, HITL, and dispatches competencies; never inlines implementation/testing/decomposition/review |
|
|
323
323
|
| `spur-cli` | 1.0 | CLI facade — one reference per `spur` noun (`task`, `feature`, `rule`, `workflow`), each with verb tables, flag guides, `--json` shapes, and write-contract rules |
|
|
324
324
|
| `sys-architecture` | 1.0 | Architecture / ADR judgment — module boundaries, data flow, transport/storage/auth choices, build-vs-extend decisions |
|
|
325
325
|
| `spec-decomposition` | 1.0 | Feature/spec → validated task-batch decomposition — scenario-to-task mapping, variant selection, granularity sizing, batch-JSON production |
|
|
@@ -348,10 +348,10 @@ surface or run one workflow. All skills target the same five core platforms: `cl
|
|
|
348
348
|
| `conflict-finding` | 1.0 | Authority-aware semantic audit — four-pillar (source/task/feature/authority) conflict discovery, claim-specific authority resolution, reproducible evidence, confirmed owner-routed remediation; backs `/sp:dev-find-conflict` |
|
|
349
349
|
| `fleet-join` | 1.0 | Guest fleet occupancy — join as a live guest occupant, loop `spur agent wait --inbox` to pull work, reply through `spur message reply`, then leave; G73 (task 1081) |
|
|
350
350
|
| `next-feature` | 1.0 | Prompt-first feature frontier prioritizer — sync-first precondition, B3 actionability gate (cited, never restated), tiered rubric over measured signals, D1–D4 defect proposals conforming to the restructure map schema; backs `/sp:dev-find-next` |
|
|
351
|
-
| `pr-reviewing` |
|
|
351
|
+
| `pr-reviewing` | 2.0.0 | GitHub Codex PR review — PR prepare/reuse, `@codex review` request with per-HEAD dedupe, bounded polling, findings normalization, validated fix + re-review; direct `spur builder pr-status`/`pr-check`/`pr-open`/`pr-review` sequence; backs `/sp:dev-pr-review` |
|
|
352
352
|
| `indexed-context` | 1.0 | Cross-agent project context — anatomy/learnings/pitfalls/buglog/memory in `.spur/context/`; hook-tracked token-ledger; graceful degradation on agents without hooks |
|
|
353
353
|
| `history-anatomy` | 1.0 | Diagnostic interpretation owner over already-imported history — daily/ad-hoc mode contract, closed finding taxonomy, twelve-section report contract, `enrich`/`validate` rubrics; no workflow launch, no JSONL fallback, no corpus mutation |
|
|
354
|
-
| `session-review` | 1.
|
|
354
|
+
| `session-review` | 1.3.0 | Inline review of the active coding-agent session — compact outcomes, evidence-backed resolved/open issue classification, proposal-only improvements, and next actions; no workflow, import, delegation, or mutation |
|
|
355
355
|
| `spur-composer` | 1.0 | Cross-noun composition — workflow catalog selection, the ephemeral→project→shared ladder, ADR-115 budgets, trace-driven rule tuning; applies accepted `spur-doctor` proposals through `spur` verbs; never judges its own output and never runs a recurring loop |
|
|
356
356
|
| `spur-doctor` | 1.0 | Cross-noun evaluation — read-only CLI evidence per noun (task/feature/rule/workflow/agent spec), reflection over `history-anatomy` findings through a closed action-class map, and a proposal table; writes nothing; diagnoses artifacts, not runtime environments (`spur agent doctor`'s job) |
|
|
357
357
|
| `spur-check` | 1.0 | Two-tier check primitive (ADR-124) — light changed-scope checks during development, the full `spur self exec check` chain at the quality boundary, and the fingerprint-bound `<wbs>-check-receipt.json` with the `status` reuse rule; composes with `/sp:dev-fixall --gate-log` |
|
|
@@ -265,7 +265,9 @@ this exact shape:
|
|
|
265
265
|
One row per declared requirement (`MET | PARTIAL | UNMET`, none omitted or merged) and one row per
|
|
266
266
|
acceptance criterion (`MET | PARTIAL | UNMET | N/A`), with the evidence-type token alone in its own
|
|
267
267
|
cell — `test | command | static-ref | manual-review | llm-judge | n/a`, or a `+` compound when more
|
|
268
|
-
than one kind applies. Evidence cells cite a repo-relative `path:line` or a named test/command.
|
|
268
|
+
than one kind applies. Evidence cells cite a repo-root-relative `path:line` or a named test/command.
|
|
269
|
+
An absolute path outside the repo (`/tmp/<report>.md:12`) is an unresolved anchor that blocks the
|
|
270
|
+
done projection (`L4.anchor-unresolved`); cite the owning source or a corpus artifact instead. AC
|
|
269
271
|
identities stay the task's own (checklist label, title, bold head, `Scenario:` prefix, bracket tag or
|
|
270
272
|
declared `AC-N` alias): a linked feature's scenario title covers the task that implements it, and a
|
|
271
273
|
task-local criterion is legal as-is — it needs no feature credit.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: "Authority-aware semantic audit across source, task files, feature files, and project authority files — discover conflicts, resolve claim-specific authority, collect reproducible evidence, and route confirmed repairs through owner surfaces. Triggers: find conflict, conflict audit, semantic conflict, authority mismatch, stale projection."
|
|
3
3
|
role: reviewer
|
|
4
|
-
argument-hint: "[<scope>] [--pillar <source|tasks|features|authority|all>] [--mode <adaptive|full>] [--resolve] [--agent <inline|auto|name>] [--json]"
|
|
4
|
+
argument-hint: "[--tasks <selector> | --feature <id>[,<id>] | --scope <path>[,<path>]] [--pillar <source|tasks|features|authority|all>] [--mode <adaptive|full>] [--resolve] [--auto] [--agent <inline|auto|name>] [--json]"
|
|
5
5
|
allowed-tools: ["Bash", "Read", "Write", "Grep", "Glob", "Skill"]
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -15,10 +15,14 @@ owner-routed remediation.
|
|
|
15
15
|
|
|
16
16
|
| Flag | Description | Default |
|
|
17
17
|
| ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- | --------------- |
|
|
18
|
-
|
|
|
18
|
+
| `--tasks <selector>` | Audit a task set — batch selector grammar ([execution-batch.md § Step 1](../skills/spur-dev/references/execution-batch.md#step-1--selector-resolution-r1)): comma WBS list or `feature:<id>`. Resolved once and frozen; the tasks seed one audit (below). | — |
|
|
19
|
+
| `--feature <id>[,<id>]` | Sugar for the union of the `feature:<id>` sets plus the feature records themselves — resolved once, frozen, audited as one seed set. | — |
|
|
20
|
+
| `--scope <path>[,<path>]` | Audit the tracked files under one or more paths: paths must exist (exit 2 otherwise), are normalized, duplicates dropped and nested paths collapse to the ancestor (`--scope apps,apps/cli` → `apps`). | — |
|
|
21
|
+
| `[<wbs\|path>]` | **Deprecated positional alias** (one release): a `^\d{4}$` token with a resolvable task → `--tasks <wbs>`; an existing path → `--scope <path>`; otherwise exit 2. Prints a deprecation warning naming the replacement. | — |
|
|
19
22
|
| `--pillar` `<source\|tasks\|features\|authority\|all>` | Limit the internal audit to one pillar; the minimum authorities needed to judge it still load. | all |
|
|
20
23
|
| `--mode` `<adaptive\|full>` | Scan protocol — adaptive reuses fresh indexed context and discloses skipped areas; full forces a cold comprehensive scan. | adaptive |
|
|
21
24
|
| `--resolve` | Enable the proposal, confirmation, and owner-routed remediation workflow. Its absence guarantees no source/corpus/numbered-doc mutation. | off |
|
|
25
|
+
| `--auto` | Under `--resolve`, pre-approve the eligible repair set instead of pausing at the confirmation gate (see the skill's Step 10). Authority decisions still pause. Requires `--resolve` (exit 2 otherwise). | off |
|
|
22
26
|
| `--agent` `<inline\|auto\|name>` | Who runs the model-bearing analysis. | omit |
|
|
23
27
|
| `--json` | Emit the same result envelope as Markdown as JSON. | off |
|
|
24
28
|
|
|
@@ -28,13 +32,21 @@ For shared semantics, see the [flag glossary](../skills/spur-dev/references/flag
|
|
|
28
32
|
|
|
29
33
|
```
|
|
30
34
|
/sp:dev-find-conflict
|
|
31
|
-
/sp:dev-find-conflict docs/00_ADR.md
|
|
35
|
+
/sp:dev-find-conflict --scope docs/00_ADR.md
|
|
32
36
|
/sp:dev-find-conflict --pillar authority
|
|
33
|
-
/sp:dev-find-conflict --pillar tasks --mode full
|
|
34
|
-
/sp:dev-find-conflict
|
|
35
|
-
/sp:dev-find-conflict
|
|
37
|
+
/sp:dev-find-conflict --tasks 0486,0487 --pillar tasks --mode full
|
|
38
|
+
/sp:dev-find-conflict --feature H11,H12 --resolve
|
|
39
|
+
/sp:dev-find-conflict --scope apps/cli,docs/design --resolve --auto --json
|
|
36
40
|
```
|
|
37
41
|
|
|
42
|
+
Target selection: **at most one** of `--tasks`, `--feature`, `--scope` per invocation — more than
|
|
43
|
+
one (a positional beside an explicit selector counts as a second kind) → exit 2 naming the
|
|
44
|
+
conflicting selectors. None → the whole project (the audit's natural default, unlike `dev-review`).
|
|
45
|
+
The target set is resolved once and frozen through the shared batch resolver — no find-conflict
|
|
46
|
+
parser; status pseudo-lists and `ready` are rejected (they select work to do, not artifacts to
|
|
47
|
+
audit). The frozen objects seed **one** audit, not one audit per object, so conflicts *between*
|
|
48
|
+
selected objects (two tasks, a task and a feature) stay visible.
|
|
49
|
+
|
|
38
50
|
Audit mode is read-only with respect to source, corpus, and numbered documentation. Findings are
|
|
39
51
|
presented before any repair. Approved repairs route through the artifact owner's existing harness
|
|
40
52
|
surface (`spur task` / `spur feature`, `sp:doc-evolve`, the Spur development lifecycle, or
|
package/plugins/sp/plugin.json
CHANGED
|
@@ -57,24 +57,29 @@ dependency, or dedicated subagent.
|
|
|
57
57
|
- Code review — use `sp:code-review` / `sp:code-verification`.
|
|
58
58
|
- General documentation drift maintenance — use `sp:doc-evolve`.
|
|
59
59
|
- Performing repairs automatically — this skill only audits and (with `--resolve`) proposes
|
|
60
|
-
confirmed, owner-routed repairs; it never mutates without explicit confirmation
|
|
60
|
+
confirmed, owner-routed repairs; it never mutates without explicit confirmation (interactive, or
|
|
61
|
+
the operator's explicit `--auto` pre-approval of eligible items).
|
|
61
62
|
|
|
62
63
|
## Arguments
|
|
63
64
|
|
|
64
65
|
| Argument | Description | Default |
|
|
65
66
|
| ---------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- |
|
|
66
|
-
|
|
|
67
|
+
| `--tasks <selector>` | Task set (comma WBS list or `feature:<id>`, batch selector grammar) seeding the audit. | — |
|
|
68
|
+
| `--feature <id>[,<id>]` | Union of the `feature:<id>` task sets plus the feature records themselves, seeding the audit. | — |
|
|
69
|
+
| `--scope <path>[,<path>]` | Tracked files under one or more existing paths, seeding the audit. | — |
|
|
70
|
+
| `[<wbs\|path>]` | Deprecated positional alias for `--tasks <wbs>` / `--scope <path>` (one release). | — |
|
|
67
71
|
| `--pillar <source\|tasks\|features\|authority\|all>` | Limit the internal audit to one pillar; the minimum authorities needed to judge it still load. | `all` |
|
|
68
72
|
| `--mode <adaptive\|full>` | Scan protocol — `adaptive` reuses fresh, provenance-verifiable indexed context and discloses skipped areas; `full` forces a cold comprehensive scan. | `adaptive` |
|
|
69
73
|
| `--resolve` | Enable the proposal, confirmation, and owner-routed remediation workflow. Its absence guarantees no source/corpus/numbered-doc mutation. | off |
|
|
74
|
+
| `--auto` | Under `--resolve`, pre-approve the eligible repair set at the confirmation gate (Step 10). Requires `--resolve`. | off |
|
|
70
75
|
| `--agent <inline\|auto\|name>` | Who runs the model-bearing analysis. `inline` is the default; `--agent auto`/a named executor isolates the analysis. Not a dedicated subagent. | `inline` |
|
|
71
76
|
| `--json` | Emit the same result envelope as Markdown as JSON. Never implies deterministic semantic reasoning. | off |
|
|
72
77
|
|
|
73
78
|
## The 10-Step Audit Protocol
|
|
74
79
|
|
|
75
80
|
```
|
|
76
|
-
|
|
77
|
-
→ PARSE & GUARD resolve
|
|
81
|
+
target + flags
|
|
82
|
+
→ PARSE & GUARD resolve + freeze the target set; confirm repository root; set audit-only vs resolve mode
|
|
78
83
|
→ DISCOVER AUTHORITY read entry/process rules; build the claim-specific authority matrix
|
|
79
84
|
→ PREFLIGHT git, rg, spur task/feature --json, relevant spur … check, doc-evolve audit
|
|
80
85
|
→ INVENTORY four-pillar inventory: pillar, identity, path, anchor, freshness, scan status
|
|
@@ -84,13 +89,35 @@ scope + flags
|
|
|
84
89
|
→ CROSS-PILLAR all six applicable boundaries
|
|
85
90
|
→ CLASSIFY lifecycle, supersession, abstraction-level, intentional-deprecation challenges
|
|
86
91
|
→ REPORT order by severity then confidence; coverage, unresolved authority, scan cost
|
|
87
|
-
→ REMEDIATE only with --resolve and explicit confirmation + freshness recheck
|
|
92
|
+
→ REMEDIATE only with --resolve and explicit (or --auto pre-) confirmation + freshness recheck
|
|
88
93
|
```
|
|
89
94
|
|
|
90
95
|
### Step 1 — Parse and guard
|
|
91
96
|
|
|
92
|
-
Resolve
|
|
93
|
-
`--resolve` mode.
|
|
97
|
+
Resolve the target and `--pillar`; confirm the repository root; establish **audit-only** versus
|
|
98
|
+
`--resolve` mode.
|
|
99
|
+
|
|
100
|
+
**Target selection.** At most one of `--tasks`, `--feature`, `--scope` (a deprecated positional
|
|
101
|
+
beside an explicit selector counts as a second kind) — more than one refuses the audit naming the
|
|
102
|
+
conflicting selectors. None → the whole project. Resolve the set **once** and freeze it:
|
|
103
|
+
|
|
104
|
+
- `--tasks` / `--feature` go through the shared batch resolver
|
|
105
|
+
([execution-batch.md § Step 1](../spur-dev/references/execution-batch.md#step-1--selector-resolution-r1));
|
|
106
|
+
`--feature <id>[,<id>]` is sugar for the union of the `feature:<id>` sets, and the feature records
|
|
107
|
+
join the seed set. Status pseudo-lists and `ready` are refused. An unresolvable WBS/feature refuses
|
|
108
|
+
the audit.
|
|
109
|
+
- `--scope` paths must exist; normalize them, drop duplicates, collapse nested paths to the ancestor.
|
|
110
|
+
- Deprecated positional: a `^\d{4}$` token with a resolvable task → `--tasks <wbs>`; an existing path
|
|
111
|
+
→ `--scope <path>`; anything else refuses. Emit a deprecation warning naming the replacement.
|
|
112
|
+
|
|
113
|
+
The frozen objects **seed one audit** — they are the starting nodes of the candidate graph (Step 5),
|
|
114
|
+
not the boundary of what may be read: the authorities and counterpart artifacts needed to judge them
|
|
115
|
+
still load. One audit, not one per object, so conflicts *between* selected objects stay visible.
|
|
116
|
+
Every finding names the seed object(s) it traces to; `coverage` accounts per seed object.
|
|
117
|
+
|
|
118
|
+
`--auto` without `--resolve` refuses the audit (it has no gate to skip in audit mode).
|
|
119
|
+
|
|
120
|
+
Without `--resolve`, the run is strictly read-only: no source, corpus, or
|
|
94
121
|
numbered-document mutation of any kind. With `--resolve`, no write happens until a repair set is
|
|
95
122
|
presented, explicitly confirmed, and freshness-revalidated.
|
|
96
123
|
|
|
@@ -98,7 +125,7 @@ Validate every enum flag against the domain declared by the command surface
|
|
|
98
125
|
(`plugins/sp/commands/dev-find-conflict.md`): `--pillar` ∈ `source|tasks|features|authority|all`,
|
|
99
126
|
`--mode` ∈ `adaptive|full`, `--agent` ∈ `inline|auto|name`. An out-of-domain value **refuses** the
|
|
100
127
|
audit before any discovery work — report the received value, the flag's valid domain, and stop;
|
|
101
|
-
never silently coerce or ignore it.
|
|
128
|
+
never silently coerce or ignore it.
|
|
102
129
|
|
|
103
130
|
### Step 2 — Discover local authority
|
|
104
131
|
|
|
@@ -157,8 +184,9 @@ findings, evidence, authority provenance, coverage, unresolved decisions, and re
|
|
|
157
184
|
|
|
158
185
|
### Step 10 — Remediate only when requested
|
|
159
186
|
|
|
160
|
-
With `--resolve`: present the proposed repair set, obtain explicit confirmation,
|
|
161
|
-
|
|
187
|
+
With `--resolve`: present the proposed repair set, obtain explicit confirmation (or, under
|
|
188
|
+
`--auto`, the pre-approval of the eligible subset — [remediation-routing.md §2.2a](references/remediation-routing.md#22a---auto-pre-approval)),
|
|
189
|
+
revalidate evidence freshness, then route each approved repair through its verified owner surface. Report the completed,
|
|
162
190
|
failed, and untouched sets; never silently roll forward past a partial failure. See
|
|
163
191
|
[references/remediation-routing.md](references/remediation-routing.md).
|
|
164
192
|
|
|
@@ -173,7 +201,7 @@ items; no mutation.
|
|
|
173
201
|
{
|
|
174
202
|
"schema_version": 1,
|
|
175
203
|
"command": "dev-find-conflict",
|
|
176
|
-
"scope": "docs/00_ADR.md",
|
|
204
|
+
"scope": "scope:docs/00_ADR.md",
|
|
177
205
|
"mode": "adaptive",
|
|
178
206
|
"pillars": ["authority"],
|
|
179
207
|
"authority_map": {},
|
|
@@ -226,10 +254,10 @@ Thin wrapper: `Skill(skill="sp:conflict-finding", args="$ARGUMENTS")`.
|
|
|
226
254
|
|
|
227
255
|
```
|
|
228
256
|
/sp:dev-find-conflict
|
|
229
|
-
/sp:dev-find-conflict docs/00_ADR.md
|
|
230
|
-
/sp:dev-find-conflict --pillar tasks --mode full
|
|
231
|
-
/sp:dev-find-conflict
|
|
232
|
-
/sp:dev-find-conflict
|
|
257
|
+
/sp:dev-find-conflict --scope docs/00_ADR.md
|
|
258
|
+
/sp:dev-find-conflict --tasks 0486,0487 --pillar tasks --mode full
|
|
259
|
+
/sp:dev-find-conflict --feature H11 --resolve
|
|
260
|
+
/sp:dev-find-conflict --scope apps/cli --resolve --auto --json
|
|
233
261
|
```
|
|
234
262
|
|
|
235
263
|
## Common rationalizations
|
|
@@ -240,6 +268,7 @@ Thin wrapper: `Skill(skill="sp:conflict-finding", args="$ARGUMENTS")`.
|
|
|
240
268
|
| "Lower-numbered docs always win." | Authority is claim-specific; the constitution's precedence applies only within its stated boundary. |
|
|
241
269
|
| "Code is always right." | Code is authoritative for what currently happens, not automatically for what should happen. |
|
|
242
270
|
| "`--resolve` authorizes automatic repair." | It opens the proposal/confirmation workflow; every repair still needs explicit confirmation and a freshness check, then the owner surface. |
|
|
271
|
+
| "`--auto` approves everything." | It pre-approves only eligible items (resolved authority, `high` confidence, verified owner surface); authority decisions still pause; freshness still applies. |
|
|
243
272
|
| "Adaptive can reuse any context." | Reuse requires freshness + verifiable provenance; absent/stale/unverifiable context degrades to a cold scan or an explicit incomplete-coverage result. |
|
|
244
273
|
|
|
245
274
|
## Red flags
|
|
@@ -248,7 +277,8 @@ Thin wrapper: `Skill(skill="sp:conflict-finding", args="$ARGUMENTS")`.
|
|
|
248
277
|
- Forcing an ambiguous/missing authority through a global ranking instead of an unresolved HITL item.
|
|
249
278
|
- Silently omitting a selected pillar or a tool failure (no coverage accounting).
|
|
250
279
|
- Claiming "comprehensive" when `coverage.complete` is false.
|
|
251
|
-
- Any mutation in audit mode, or automatic mutation merely because `--resolve` is present.
|
|
280
|
+
- Any mutation in audit mode, or automatic mutation merely because `--resolve` is present (without `--auto`).
|
|
281
|
+
- Under `--auto`, applying an ineligible item or settling a `needs-authority-decision` item.
|
|
252
282
|
- Editing a derived projection before correcting a defective authority, or changing a correct authority merely to repair its stale projection.
|
|
253
283
|
- Adding a production analyzer, index/cache/database, dependency, or dedicated subagent in v1.
|
|
254
284
|
|
|
@@ -76,8 +76,10 @@ Join keys, in priority order:
|
|
|
76
76
|
|
|
77
77
|
Construction protocol:
|
|
78
78
|
|
|
79
|
-
1. **Seed from
|
|
80
|
-
|
|
79
|
+
1. **Seed from the frozen target.** Every object in the `--tasks` / `--feature` / `--scope` set is
|
|
80
|
+
a seed, plus every artifact whose identity or content references one of them (its WBS, feature
|
|
81
|
+
ID, or path). Multiple seeds share one graph, so edges between seeds are compared too. No
|
|
82
|
+
selector → the whole project is the seed set.
|
|
81
83
|
2. **Grow by shared keys.** For each seed, add an edge to any artifact sharing one of the keys
|
|
82
84
|
above for the _same subject_. A key matches only when it refers to the same subject, not merely
|
|
83
85
|
the same string in an unrelated context (see normalize).
|
|
@@ -218,7 +218,7 @@ inventory, findings, unresolved, coverage, cost, remediation, errors
|
|
|
218
218
|
{
|
|
219
219
|
"schema_version": 1,
|
|
220
220
|
"command": "dev-find-conflict",
|
|
221
|
-
"scope": "docs/00_ADR.md",
|
|
221
|
+
"scope": "scope:docs/00_ADR.md",
|
|
222
222
|
"mode": "adaptive",
|
|
223
223
|
"pillars": ["authority"],
|
|
224
224
|
"authority_map": {},
|
|
@@ -236,7 +236,7 @@ inventory, findings, unresolved, coverage, cost, remediation, errors
|
|
|
236
236
|
| ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
237
237
|
| `schema_version` | integer, `1`. The envelope contract version — not a semantic-reasoning version. |
|
|
238
238
|
| `command` | string, `dev-find-conflict`. |
|
|
239
|
-
| `scope` | string. The
|
|
239
|
+
| `scope` | string. The frozen target as `<kind>:<id>[,<id>]` — `tasks:0486,0487`, `feature:H11,H12`, `scope:apps,docs` — or `"<project>"` when no selector was given. |
|
|
240
240
|
| `mode` | string, `adaptive` \| `full`. |
|
|
241
241
|
| `pillars` | string[]. The pillars actually audited (subset of `source`, `tasks`, `features`, `authority`). |
|
|
242
242
|
| `authority_map` | object. Claim-type → authoritative artifact/rule, with each precedence edge citing its project rule or fallback (see [./authority-resolution.md](authority-resolution.md)). |
|
|
@@ -13,7 +13,8 @@ opt-in, gated workflow. This file is the SSOT for *when a write is allowed*, *wh
|
|
|
13
13
|
|
|
14
14
|
The governing rule, carried through everything below: **no mutation in audit mode, and no automatic
|
|
15
15
|
mutation merely because `--resolve` is present.** Every write requires (a) a presented repair set,
|
|
16
|
-
(b) explicit operator confirmation
|
|
16
|
+
(b) explicit operator confirmation (interactive, or the explicit `--auto` pre-approval of eligible
|
|
17
|
+
items — §2.2a), (c) a freshness revalidation of the supporting evidence, and
|
|
17
18
|
(d) dispatch through the artifact owner's verified harness surface. Ambiguity or partial failure is
|
|
18
19
|
reported, never silently continued.
|
|
19
20
|
|
|
@@ -23,7 +24,7 @@ reported, never silently continued.
|
|
|
23
24
|
|-----------|-----------|
|
|
24
25
|
| Audit mode is read-only | Without `--resolve`, no source, corpus (task/feature), or numbered-document mutation of any kind. |
|
|
25
26
|
| `--resolve` is not a write | It only *opens* the proposal → confirmation → owner-routed workflow. It never authorizes automatic repair. |
|
|
26
|
-
| Confirmation precedes every write | No repair executes until the operator explicitly approves the specific proposed repair set. |
|
|
27
|
+
| Confirmation precedes every write | No repair executes until the operator explicitly approves the specific proposed repair set — interactively, or by `--auto` pre-approval of its eligible subset (§2.2a). |
|
|
27
28
|
| Freshness precedes mutation | The supporting evidence anchors are re-read and compared against the finding's fingerprint before any write. |
|
|
28
29
|
| Owner surface, not raw edits | Each approved repair routes through the artifact's owner (Spur CLI, `sp:doc-evolve`, Spur dev lifecycle, Superskill lifecycle) — never a direct file write where an owner surface exists. |
|
|
29
30
|
| Idempotent and partial-failure aware | Already-matching artifacts resolve without a write; one repair's failure neither marks others successful nor silently rolls forward. |
|
|
@@ -93,6 +94,23 @@ is:
|
|
|
93
94
|
A declined or deferred repair is left **untouched** and reported as such; it is not re-attempted
|
|
94
95
|
implicitly in the same run.
|
|
95
96
|
|
|
97
|
+
### 2.2a `--auto` pre-approval
|
|
98
|
+
|
|
99
|
+
`--auto` (only valid with `--resolve`) is the operator's explicit, up-front confirmation of the
|
|
100
|
+
**eligible** subset of the repair set — it replaces the interactive pause for that subset only. The
|
|
101
|
+
repair set is still presented (§2.1) before anything is applied. An item is eligible only when all
|
|
102
|
+
hold:
|
|
103
|
+
|
|
104
|
+
- `status` is `open` — never `needs-authority-decision` (authority is resolved, not ambiguous/missing);
|
|
105
|
+
- `confidence` is `high`;
|
|
106
|
+
- `repair_owner` resolves to a verified owner surface in §3 (no manual/unknown owner).
|
|
107
|
+
|
|
108
|
+
Ineligible items are the HITL that remains: authority decisions and medium/low-confidence repairs
|
|
109
|
+
**still pause** for the operator, exactly as without `--auto`. In a non-interactive run (no operator
|
|
110
|
+
to answer), they are recorded `deferred` and left untouched. The remediation report marks each
|
|
111
|
+
approved item `approved_by: auto` or `approved_by: operator`, so the audit trail distinguishes the two.
|
|
112
|
+
`--auto` never skips freshness revalidation (§2.3), owner routing (§3), or partial-failure handling (§5).
|
|
113
|
+
|
|
96
114
|
### 2.3 Revalidate evidence freshness
|
|
97
115
|
|
|
98
116
|
Between the audit and any write, the world may have changed. Immediately before dispatching each
|
|
@@ -245,6 +263,7 @@ These are the explicit boundaries for remediation. Each is a hard violation, not
|
|
|
245
263
|
| Anti-pattern | Why it is prohibited |
|
|
246
264
|
|--------------|----------------------|
|
|
247
265
|
| **Automatic mutation merely because `--resolve` is present** | `--resolve` only opens the workflow; it never authorizes automatic repair. Confirmation + freshness + owner surface are all required. |
|
|
266
|
+
| **`--auto` beyond its eligible subset** | `--auto` pre-approves only §2.2a-eligible items; applying an authority decision or a medium/low-confidence repair under it is a violation. |
|
|
248
267
|
| **Changing correct authority for projection drift** | A stale projection is repaired against its governing contract. Correct authority only when defective and authorized; then update affected projections. |
|
|
249
268
|
| **Broad cleanup outside confirmed findings** | Only the artifacts named by confirmed, freshness-checked findings are touched. No opportunistic refactors or doc "improvements" while repairing. |
|
|
250
269
|
| **Ambiguity silently resolved** | Ambiguous/missing authority stops for an operator decision; it is never forced through a global ranking or a guessed owner. |
|
|
@@ -260,7 +279,7 @@ Before dispatching any write, confirm each of the following:
|
|
|
260
279
|
|
|
261
280
|
- [ ] Audit mode performed **no** governed mutation; the report is a pure envelope.
|
|
262
281
|
- [ ] `--resolve` was present, and the **repair set was presented** (keyed by finding ID + fingerprint).
|
|
263
|
-
- [ ] The operator **explicitly confirmed** the specific selected repair set.
|
|
282
|
+
- [ ] The operator **explicitly confirmed** the specific selected repair set, or `--auto` pre-approved only §2.2a-eligible items.
|
|
264
283
|
- [ ] Evidence **freshness revalidated** per finding at dispatch; `stale-evidence` items returned to audit.
|
|
265
284
|
- [ ] Each approved repair routed through its **owner surface** (§3), never a raw write where an owner exists.
|
|
266
285
|
- [ ] **Idempotent** already-matching items marked `resolved` without a write.
|
|
@@ -5,6 +5,8 @@ description: >-
|
|
|
5
5
|
"join the fleet", "become a fleet guest", "pull fleet inbox work in this session", or when a
|
|
6
6
|
session should receive fleet messages without being supervised. Runs `spur agent join`, then
|
|
7
7
|
loops `spur agent wait --inbox`, and releases the lease with `spur agent leave`.
|
|
8
|
+
metadata:
|
|
9
|
+
version: "1.0"
|
|
8
10
|
---
|
|
9
11
|
# fleet-join — a live session as a fleet guest (G73, task 1081)
|
|
10
12
|
|
|
@@ -131,8 +131,9 @@ surface instead of spawning a subprocess; a subprocess fallback happens only whe
|
|
|
131
131
|
|
|
132
132
|
**Interactive task pipelines invert control into the host session (ADR-047 amendment).**
|
|
133
133
|
`dev-run --mode full` and sequential `dev-runall` with omitted `--agent` or explicit `--agent
|
|
134
|
-
inline`
|
|
135
|
-
workflow run`
|
|
134
|
+
inline` run the existing `task-pipeline.yaml` on the host executor — the engine loop above
|
|
135
|
+
(`spur workflow run … executor=host` → work item → `spur workflow continue`), with no subprocess —
|
|
136
|
+
and never redirect silently to `agent.default`. Interactive **omit** is
|
|
136
137
|
**host-controlled and non-subprocess**, but no longer guarantees host-context execution for every
|
|
137
138
|
model stage (task 0508): an eligible `agent.run` stage — pure-slash input, non-interactive state,
|
|
138
139
|
native subagent with shared-worktree read/write/shell capability, and a task above the
|
|
@@ -156,7 +156,7 @@ must not be changed without updating the backing skill.
|
|
|
156
156
|
### 4. run
|
|
157
157
|
|
|
158
158
|
- **Purpose:** Run a task through the execution pipeline (full) or execute a single pipeline step (implement).
|
|
159
|
-
- **Inputs:** `<wbs>` (required). `--mode <full|implement>` selects the execution mode. `implement` invokes `sp:code-implementation` inline by default. Interactive `full` resolves the selector uniformly (task 0687): omit ≡ explicit `--agent inline`; full mode
|
|
159
|
+
- **Inputs:** `<wbs>` (required). `--mode <full|implement>` selects the execution mode. `implement` invokes `sp:code-implementation` inline by default. Interactive `full` resolves the selector uniformly (task 0687): omit ≡ explicit `--agent inline`; full mode runs `task-pipeline.yaml` on the host executor (`spur workflow run … executor=host` → work item → `spur workflow continue`) — host-controlled and non-subprocess, with 0508 eligibility applying to the resolved-inline selector (eligible `agent.run` stages dispatch once to a native subagent, host fallback)). `--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`. `--no-summary` skips the [execution summary](#execution-summary) printed after a full-mode run. `--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.
|
|
160
160
|
- **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).
|
|
161
161
|
- **Modes:**
|
|
162
162
|
- **`full`** (default): Drive the full pipeline — precheck → implement → gate ⇄ remediate → review → done, with the repair, stop and approval routes taken from decision rows ([decision-points.md](decision-points.md)). Interactive omit/inline runs `spur workflow run task-pipeline.yaml --vars '{"wbs":"<wbs>","executor":"host"}'` and performs each returned work item (eligible stages may use a native subagent); explicit/headless executor selection runs the same definition without the `executor` var (with `profile: auto` when `--auto`). Both monitor/surface HITL and preserve the YAML gates. `--next` never changes this mode.
|
|
@@ -219,8 +219,8 @@ or irreversible HITL gates.
|
|
|
219
219
|
|
|
220
220
|
Scope the operation to all tasks under a feature id (`^[A-Z][1-9]*$`). On feature-advancing
|
|
221
221
|
commands (`dev-wrapall`) it also advances the feature through legal lifecycle edges with guards
|
|
222
|
-
honored. On `dev-review` it takes a comma list (`--feature <id>[,<id>]`) —
|
|
223
|
-
the `feature:<id>` sets, resolved once and frozen.
|
|
222
|
+
honored. On `dev-review` and `dev-find-conflict` it takes a comma list (`--feature <id>[,<id>]`) —
|
|
223
|
+
sugar for the union of the `feature:<id>` sets, resolved once and frozen.
|
|
224
224
|
|
|
225
225
|
### `--check <cmd>` — validation command for iterate-and-check loops
|
|
226
226
|
|
|
@@ -250,9 +250,10 @@ all dimensions.
|
|
|
250
250
|
**Anchor:** `#flag-scope`.
|
|
251
251
|
|
|
252
252
|
Limit the operation to a file or directory path (`dev-arch`, `dev-debug`, `dev-fixall`,
|
|
253
|
-
`dev-gitmsg`, `dev-gtd`, `dev-refactor`, `dev-review`, `dev-simplify`) to
|
|
254
|
-
On `dev-review` it takes a comma list of paths —
|
|
255
|
-
one advisory sub-review per
|
|
253
|
+
`dev-find-conflict`, `dev-gitmsg`, `dev-gtd`, `dev-refactor`, `dev-review`, `dev-simplify`) to
|
|
254
|
+
bound the working set. On `dev-review` and `dev-find-conflict` it takes a comma list of paths —
|
|
255
|
+
normalized, nested and duplicate paths merged; `dev-review` runs one advisory sub-review per
|
|
256
|
+
surviving path, `dev-find-conflict` seeds one audit with all of them.
|
|
256
257
|
|
|
257
258
|
### `--all` — widen the operation to everything in its domain
|
|
258
259
|
|
|
@@ -275,9 +276,9 @@ is the contract; divergence between `--dry-run` and the real run is a bug.
|
|
|
275
276
|
|
|
276
277
|
**Anchor:** `#flag-tasks`.
|
|
277
278
|
|
|
278
|
-
Batch operation (`dev-refineall`, `dev-review`, `dev-runall`, `dev-verifyall`). An
|
|
279
|
+
Batch operation (`dev-find-conflict`, `dev-refineall`, `dev-review`, `dev-runall`, `dev-verifyall`). An
|
|
279
280
|
explicit selector — WBS list, status pseudo-list (`todo`, `wip`), `feature:<id>`, or `ready` —
|
|
280
|
-
resolving to the set the batch runs over. On `dev-review` the selector is restricted to the
|
|
281
|
+
resolving to the set the batch runs over. On `dev-review` and `dev-find-conflict` the selector is restricted to the
|
|
281
282
|
review-safe forms: comma WBS list and `feature:<id>` — status pseudo-lists and `ready` are
|
|
282
283
|
rejected (they select work to do, not work to review). Required on `dev-runall` and
|
|
283
284
|
`dev-verifyall`, where `--feature` is an optional restrictor. On `dev-refineall` it is instead
|
package/spur.js
CHANGED
|
@@ -120938,11 +120938,16 @@ async function persistWorktreeRuns(input) {
|
|
|
120938
120938
|
if (fromStat === undefined || !fromStat.isDirectory()) {
|
|
120939
120939
|
throw new Error(`persist-out: source worktree does not exist or is not a directory: ${input.fromWorkdir}`);
|
|
120940
120940
|
}
|
|
120941
|
+
const fs = createNodeFileSystem2();
|
|
120942
|
+
const fromReal = fs.realPath?.(fromDir) ?? fromDir;
|
|
120943
|
+
const toReal = fs.realPath?.(toDir) ?? toDir;
|
|
120944
|
+
if (fromReal === toReal) {
|
|
120945
|
+
throw new Error(`persist-out: source and destination are the same tree (${fromDir}) \u2014 run it from the invoking tree, or the evidence is copied onto itself and lost with the worktree`);
|
|
120946
|
+
}
|
|
120941
120947
|
const fromRunDir = join67(fromDir, ".spur", "run");
|
|
120942
120948
|
const toRunDir = join67(toDir, ".spur", "run");
|
|
120943
120949
|
const fromRecordsDir = runStoragePaths(fromDir).recordsDir;
|
|
120944
120950
|
const toRecordsDir = runStoragePaths(toDir).recordsDir;
|
|
120945
|
-
const fs = createNodeFileSystem2();
|
|
120946
120951
|
const fromEvidence = runStoragePaths(fromDir).evidenceDir;
|
|
120947
120952
|
const toEvidence = runStoragePaths(toDir).evidenceDir;
|
|
120948
120953
|
const evidenceCopies = [];
|
|
@@ -146882,7 +146887,7 @@ import { createRequire as createRequire3 } from "module";
|
|
|
146882
146887
|
var CLI_CONFIG = {
|
|
146883
146888
|
binaryName: "spur",
|
|
146884
146889
|
binaryLabel: "spur",
|
|
146885
|
-
binaryVersion: "0.4.
|
|
146890
|
+
binaryVersion: "0.4.18",
|
|
146886
146891
|
configDir: ".spur",
|
|
146887
146892
|
configFile: ".spur/config.yaml",
|
|
146888
146893
|
databaseFile: ".spur/spur.db"
|
|
@@ -156730,7 +156735,7 @@ init_dist5();
|
|
|
156730
156735
|
import { homedir as homedir17 } from "os";
|
|
156731
156736
|
import { basename as basename20, join as join94, relative as relative19, resolve as resolve37 } from "path";
|
|
156732
156737
|
// ../server/package.json
|
|
156733
|
-
var version3 = "0.4.
|
|
156738
|
+
var version3 = "0.4.18";
|
|
156734
156739
|
|
|
156735
156740
|
// ../server/src/modules/health/index.ts
|
|
156736
156741
|
var startedAt = Date.now();
|
|
@@ -161784,6 +161789,7 @@ function registerWorkflowCleanCommand(workflow, context) {
|
|
|
161784
161789
|
}
|
|
161785
161790
|
|
|
161786
161791
|
// ../../packages/app/src/workflow/commit-guard.ts
|
|
161792
|
+
init_src();
|
|
161787
161793
|
init_dist5();
|
|
161788
161794
|
import { mkdirSync as mkdirSync23, readFileSync as readFileSync28, renameSync as renameSync10, writeFileSync as writeFileSync20 } from "fs";
|
|
161789
161795
|
import { join as join100 } from "path";
|
|
@@ -161954,6 +161960,26 @@ function commitGuardStage(run, paths, options = {}) {
|
|
|
161954
161960
|
foreign
|
|
161955
161961
|
};
|
|
161956
161962
|
}
|
|
161963
|
+
function foreignSessionOwner(cwd) {
|
|
161964
|
+
try {
|
|
161965
|
+
const raw = JSON.parse(readFileSync28(join100(cwd, ".spur", "context", ".session.json"), "utf8"));
|
|
161966
|
+
const sessionId = typeof raw.owner?.sessionId === "string" ? raw.owner.sessionId : "";
|
|
161967
|
+
if (sessionId === "")
|
|
161968
|
+
return null;
|
|
161969
|
+
const current = currentHostSessionId();
|
|
161970
|
+
if (current === "" || current === sessionId)
|
|
161971
|
+
return null;
|
|
161972
|
+
return { host: typeof raw.owner?.host === "string" ? raw.owner.host : "unknown", sessionId };
|
|
161973
|
+
} catch {
|
|
161974
|
+
return null;
|
|
161975
|
+
}
|
|
161976
|
+
}
|
|
161977
|
+
function currentHostSessionId() {
|
|
161978
|
+
const transcript = getEnvVar("PI_SESSION_FILE") ?? "";
|
|
161979
|
+
const stem = transcript.replace(/\.jsonl$/, "").split("/").pop() ?? "";
|
|
161980
|
+
const pi = stem.includes("_") ? stem.split("_").pop() ?? "" : "";
|
|
161981
|
+
return pi !== "" ? pi : (getEnvVar("CLAUDE_CODE_SESSION_ID") ?? "").trim();
|
|
161982
|
+
}
|
|
161957
161983
|
function commitGuardCheck(run, options = {}) {
|
|
161958
161984
|
try {
|
|
161959
161985
|
const context = runContext(run, options);
|
|
@@ -161961,7 +161987,11 @@ function commitGuardCheck(run, options = {}) {
|
|
|
161961
161987
|
return missingStart(run);
|
|
161962
161988
|
const { base, git, written } = context;
|
|
161963
161989
|
const foreign = [...changedSinceBase(base, git)].filter((path) => !written.has(path)).sort();
|
|
161964
|
-
|
|
161990
|
+
const owner = foreignSessionOwner(options.cwd ?? process.cwd());
|
|
161991
|
+
const stderr = owner ? [
|
|
161992
|
+
`commit-guard: another session owns this tree \u2014 .spur/context/.session.json records ${owner.host} ${owner.sessionId}; use a separate worktree (one writer per tree)`
|
|
161993
|
+
] : [];
|
|
161994
|
+
return { ...report(0, [JSON.stringify({ foreign, ...owner ? { foreignSession: owner } : {} })], stderr) };
|
|
161965
161995
|
} catch (err) {
|
|
161966
161996
|
return report(1, [], [probeDiagnostic(err)]);
|
|
161967
161997
|
}
|