@gobing-ai/spur 0.3.63 → 0.3.64

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.
Files changed (36) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/config/corpus-baseline.json +3326 -3886
  3. package/config/workflows/history-anatomy.yaml +2 -2
  4. package/package.json +9 -9
  5. package/plugins/sp/README.md +6 -3
  6. package/plugins/sp/agents/expert-spur.md +20 -4
  7. package/plugins/sp/commands/dev-find-issue.md +1 -1
  8. package/plugins/sp/commands/dev-gitmsg.md +12 -6
  9. package/plugins/sp/commands/dev-gtd.md +8 -19
  10. package/plugins/sp/commands/dev-idea.md +1 -1
  11. package/plugins/sp/commands/dev-plan.md +1 -1
  12. package/plugins/sp/commands/dev-run.md +2 -2
  13. package/plugins/sp/commands/dev-runall.md +2 -2
  14. package/plugins/sp/commands/dev-wrap.md +5 -6
  15. package/plugins/sp/commands/dev-wrapall.md +5 -7
  16. package/plugins/sp/plugin.json +1 -1
  17. package/plugins/sp/scripts/history-anatomy-cache.mjs +3 -2
  18. package/plugins/sp/scripts/history-anatomy-cache.ts +7 -2
  19. package/plugins/sp/skills/dogfood-testing/SKILL.md +14 -1
  20. package/plugins/sp/skills/history-anatomy/references/report-contract.md +8 -0
  21. package/plugins/sp/skills/next-router/SKILL.md +4 -4
  22. package/plugins/sp/skills/pr-reviewing/SKILL.md +2 -3
  23. package/plugins/sp/skills/redesign-web-ui/SKILL.md +184 -0
  24. package/plugins/sp/skills/redesign-web-ui/references/audit-checklist.md +121 -0
  25. package/plugins/sp/skills/redesign-web-ui/references/upgrade-techniques.md +66 -0
  26. package/plugins/sp/skills/spur-cli/references/agent.md +1 -1
  27. package/plugins/sp/skills/spur-cli/references/workflows/authoring-workflows.md +5 -0
  28. package/plugins/sp/skills/spur-cli/references/workflows/operations.md +20 -5
  29. package/plugins/sp/skills/spur-cli/references/workflows/workflow-fit-and-tuning.md +230 -0
  30. package/plugins/sp/skills/spur-cli/references/workflows.md +26 -4
  31. package/plugins/sp/skills/spur-dev/references/cross-cutting.md +22 -30
  32. package/plugins/sp/skills/spur-dev/references/dev-operations.md +62 -20
  33. package/plugins/sp/skills/spur-dev/references/execution-workflow.md +1 -1
  34. package/plugins/sp/skills/spur-dev/references/flag-glossary.md +18 -8
  35. package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +7 -6
  36. package/spur.js +297 -214
@@ -131,12 +131,12 @@ states:
131
131
  options:
132
132
  command: >-
133
133
  mkdir -p .spur/run;
134
- . .spur/run/$__runId-paths.env;
134
+ . .spur/run/$__runId-paths.txt;
135
135
  $spurBin history analyze --out .spur/run/$__runId-history-anatomy-current.json --since "$HA_SINCE" --until "$HA_UNTIL" --json
136
136
  - kind: shell
137
137
  options:
138
138
  command: >-
139
- . .spur/run/$__runId-paths.env;
139
+ . .spur/run/$__runId-paths.txt;
140
140
  $spurBin history analyze --out .spur/run/$__runId-history-anatomy-baseline.json --since "$HA_BASELINE_SINCE" --until "$HA_BASELINE_UNTIL" --json 2>/dev/null || true
141
141
 
142
142
  - id: cache-probe
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gobing-ai/spur",
3
- "version": "0.3.63",
3
+ "version": "0.3.64",
4
4
  "description": "Spur CLI — local-first harness for mainstream coding agents: constraint checking, workflow orchestration, agent health, and history analytics. Bun-native; exposes the `spur` command.",
5
5
  "keywords": [
6
6
  "spur",
@@ -53,14 +53,14 @@
53
53
  },
54
54
  "devDependencies": {
55
55
  "@commander-js/extra-typings": "^14.0.0",
56
- "@gobing-ai/ts-db": "^0.4.43",
57
- "@gobing-ai/ts-ai-runner": "^0.4.43",
58
- "@gobing-ai/ts-dual-workflow-engine": "^0.4.43",
59
- "@gobing-ai/ts-infra": "^0.4.43",
60
- "@gobing-ai/ts-llm-jsonl-importer": "^0.4.43",
61
- "@gobing-ai/ts-rule-engine": "^0.4.43",
62
- "@gobing-ai/ts-runtime": "^0.4.43",
63
- "@gobing-ai/ts-utils": "^0.4.43",
56
+ "@gobing-ai/ts-db": "^0.4.45",
57
+ "@gobing-ai/ts-ai-runner": "^0.4.45",
58
+ "@gobing-ai/ts-dual-workflow-engine": "^0.4.45",
59
+ "@gobing-ai/ts-infra": "^0.4.45",
60
+ "@gobing-ai/ts-llm-jsonl-importer": "^0.4.45",
61
+ "@gobing-ai/ts-rule-engine": "^0.4.45",
62
+ "@gobing-ai/ts-runtime": "^0.4.45",
63
+ "@gobing-ai/ts-utils": "^0.4.45",
64
64
  "@types/bun": "1.3.14",
65
65
  "@types/figlet": "^1.7.0",
66
66
  "@types/node-notifier": "8.0.5",
@@ -135,7 +135,7 @@ list this README is checked against.
135
135
  | `dev-simplify` | Simplify recently-changed code for clarity without changing behavior — incremental, test-after-each, revert on regression |
136
136
  | `dev-arch` | Survey a codebase (or module tree) for shallow modules and deepening opportunities — emit a ranked MARKDOWN candidate report that feeds the planning half; never auto-refactors |
137
137
  | `dev-reverse` | Reverse-engineer a codebase — analyze unfamiliar repos, generate HLD/architecture docs, audit quality/security, and produce onboarding documentation |
138
- | `dev-gitmsg` | Generate conventional commit message(s) from staged changes via per-file summarization, optionally commit |
138
+ | `dev-gitmsg` | Generate conventional commit message(s) from the current change set via one bounded diff capture, optionally commit |
139
139
  | `dev-gtd` | Get things done — quality gate (auto-fix) → conventional commit → push → gh verify in one flow; optional act CI simulation via `--act` |
140
140
  | `dev-changelog` | Generate changelog from git commits |
141
141
 
@@ -173,7 +173,7 @@ and verification (`sp:code-verification`) — plus a CLI facade (`sp:spur-cli`,
173
173
  `spur` noun) and standalone technique skills (`sp:next-router`, `sp:test-driven-development`, `sp:brainstorm`,
174
174
  `sp:wayfinder`, `sp:sys-debugging`, `sp:code-review`, `sp:code-simplification`, `sp:code-improvement`,
175
175
  `sp:parallel-execution`, `sp:branch-workflow`, `sp:doc-evolve`, `sp:dogfood-testing`,
176
- `sp:daily-summary`, `sp:reverse-engineering`, `sp:issue-finding`, `sp:conflict-finding`, `sp:indexed-context`). See
176
+ `sp:daily-summary`, `sp:reverse-engineering`, `sp:issue-finding`, `sp:conflict-finding`, `sp:indexed-context`, `sp:redesign-web-ui`). See
177
177
  [skills/spur-dev/SKILL.md](skills/spur-dev/SKILL.md)'s Step routing table for which skill owns which
178
178
  pipeline step.
179
179
 
@@ -181,7 +181,7 @@ pipeline step.
181
181
 
182
182
  ```
183
183
  plugins/sp/
184
- ├── skills/ # Domain knowledge + workflow docs (28 skills)
184
+ ├── skills/ # Domain knowledge + workflow docs (31 skills)
185
185
  │ ├── brainstorm/ # Structured ideation workflow
186
186
  │ │ ├── agents/openai.yaml
187
187
  │ │ ├── examples/ideation-example.md
@@ -239,6 +239,8 @@ plugins/sp/
239
239
  │ │ └── references/{authority-resolution.md, comparison-protocol.md, finding-contract.md, remediation-routing.md}
240
240
  │ ├── next-feature/ # Prompt-first feature frontier prioritizer (backs /sp:dev-find-next)
241
241
  │ │ └── references/{signal-derivation.md, ranking-rubric.md, proposal-contract.md, handoff-routing.md}
242
+ │ ├── redesign-web-ui/ # Existing-UI visual upgrade past generic AI defaults
243
+ │ │ └── references/{audit-checklist, upgrade-techniques}.md
242
244
  │ ├── history-anatomy/ # Diagnostic interpretation owner over already-imported history (backs /sp:dev-find-issue)
243
245
  │ │ └── references/{modes.md, report-contract.md, operations.md}
244
246
  │ ├── sys-architecture/ # Architecture / ADR judgment competency
@@ -319,6 +321,7 @@ surface or run one workflow. All skills target the same five core platforms: `cl
319
321
  | `pr-reviewing` | 1.0 | GitHub Codex PR review — PR prepare/reuse, `@codex review` request with per-HEAD dedupe, bounded polling, findings normalization, validated fix + re-review; spine SSOT `pr-review.yaml` + `scripts/pr-reviewing.ts`; backs `/sp:dev-pr-review` |
320
322
  | `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 |
321
323
  | `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 |
324
+ | `redesign-web-ui` | 1.0 | Existing-UI visual upgrade — audit generic AI fingerprints, apply in-stack polish against `DESIGN.md` / live tokens, verify behavior and viewports; does not migrate frameworks |
322
325
 
323
326
  #### Bounded coexistence and retirement gate — `sp:issue-finding` (HA-S1 0661)
324
327
 
@@ -45,10 +45,24 @@ guide and conventions before acting.
45
45
  - **Traceability audits** — verify every task links to a feature, every scenario maps to a task.
46
46
  - **Section-editing campaigns** — update the same section across multiple tasks.
47
47
  - **Rule-catalog work** — author, fine-tune, validate, or harden constraint rules across the catalog.
48
- - **Workflow work** — author, validate, dry-run, or refactor one or more workflows.
49
- When authoring or refactoring, read the composition-measures section in
50
- `sp:spur-cli` `references/workflows.md` and apply the advisory's fix-path map — findings are
51
- advisory only; never block a run or edit an executing pipeline over them.
48
+ - **Workflow work** — decide fit, author, validate, dry-run, tune, or refactor one or more workflows.
49
+ Read `sp:spur-cli` `references/workflows/workflow-fit-and-tuning.md` before authoring or
50
+ refactoring, and apply it in this order:
51
+ - **Fit first.** A process earns a `spur workflow` only when it replays, branches on a
52
+ machine-checkable predicate, **and** needs a durable per-run record. Fewer than three → recommend
53
+ a descriptive procedure or checklist and stop. Author the mode gate only after fit clears.
54
+ - **Simplicity is the budget, and it is measured.** `shell` commands at or under 5 non-comment
55
+ units, `agent.run` inputs referencing a slash command rather than carrying a raw prompt, guards
56
+ a single predicate. Over budget → pick a recorded owner from
57
+ `docs/design/workflow-shell-ownership.md`; never reformat to dodge the measure.
58
+ - **Latency and observability are authoring decisions.** Minimize `agent.run` node count first;
59
+ soft status-file probe over repeated probing; guards ordered cheapest-discriminating-first;
60
+ `iterationBound` from a latency budget; states named for outcomes; `failureStates` declared.
61
+ - **Refactor in a named direction** — promote (prose → workflow), demote (workflow → prose),
62
+ or optimize in place. Back an optimization with a before/after `spur workflow trace` pair,
63
+ never with a feel.
64
+ - Composition-advisory findings (`workflow validate --json` → `composition`) are advisory only;
65
+ never block a run or edit an executing pipeline over them.
52
66
  - **Corpus health checks** — run `check`/`validate` across a batch and report findings.
53
67
 
54
68
  For a single operation, use the `spur` CLI directly. For the planning/execution lifecycle, use
@@ -72,12 +86,14 @@ Invoke `sp:spur-cli` for verb guidance and per-noun conventions:
72
86
  - [ ] Run the corpus-wide sweep after batch edits: `spur task check --corpus --json` (fails on structural errors outside `config/corpus-baseline.json`).
73
87
  - [ ] Use `spur task update --section --from-file` for all task section edits.
74
88
  - [ ] Run the noun's scoped `refresh` after batch operations where one exists (`spur task refresh`, `spur feature refresh --feature <id>` or `--all`).
89
+ - [ ] Run the workflow fit gate before authoring any new workflow, and recommend a descriptive procedure when it does not clear all three parts.
75
90
 
76
91
  ### Never
77
92
 
78
93
  - [ ] Never edit corpus files directly — always through CLI verbs.
79
94
  - [ ] Never reimplement verb logic or validation — the CLI owns it.
80
95
  - [ ] Never drive the planning/execution lifecycle through this agent — use `sp:spur-dev`.
96
+ - [ ] Never author a workflow whose every node is a raw-prompt `agent.run` — that is a descriptive procedure paying a process spawn per step.
81
97
 
82
98
  ## Output Format
83
99
 
@@ -25,7 +25,7 @@ evidence validation. This command never triggers an import.
25
25
  | `--since` `<RFC3339>` | Inclusive lower bound (ad-hoc; required). | omitted |
26
26
  | `--until` `<RFC3339>` | Inclusive upper bound (ad-hoc; required). | omitted |
27
27
  | `--recompute` | Force the full analyze/render/enrich/validate path; records disposition forced-recompute. | off |
28
- | `--agent` `<auto\|name>` | Execution surface selector. This target is engine-driven (headless): omit resolves through the executor precedence chain to `agent.default`, then the workflow literal. Explicit `--agent inline` is rejected with the stable special error (exit 2). | omitted |
28
+ | `--agent` `<auto\|name>` | Execution surface selector. This target is engine-driven (headless). Per task 0687, omit and explicit `--agent inline` resolve identically tier resolution with one warning naming the substituted executor; there is deliberately **no** host-session inline driver for `history-anatomy.yaml` (mechanism (b)). A name pins the executor. | omitted |
29
29
  | `--output` `<path>` | Explicit report output path (ad-hoc; default writes to the run directory). | run dir |
30
30
 
31
31
  For shared semantics, see the [flag glossary](../skills/spur-dev/references/flag-glossary.md).
@@ -1,7 +1,7 @@
1
1
  ---
2
- description: Generate conventional commit message(s) from staged changes via per-file summarization, optionally commit
2
+ description: Generate conventional commit message(s) from the current change set via one bounded diff capture, optionally commit
3
3
  role: scribe
4
- argument-hint: "[--commit] [--squash] [--scope <path>]"
4
+ argument-hint: "[--commit] [--squash] [--all] [--scope <path>]"
5
5
  allowed-tools: ["Bash", "Read"]
6
6
  ---
7
7
 
@@ -13,17 +13,23 @@ Implements an inline procedure — see [dev-operations.md](../skills/spur-dev/re
13
13
 
14
14
  | Flag | Description | Default |
15
15
  | --- | --- | --- |
16
- | `--commit` | Stage and commit with the generated message. | off |
17
- | `--squash` | Squash staged changes into one commit. | off |
18
- | `--scope` `<path>` | Scope the diff to a path. | all staged changes |
16
+ | `--commit` | Commit the change set one commit per concern. | off |
17
+ | `--squash` | Collapse every concern into one message and one commit; implies `--commit`. | off |
18
+ | `--all` | Widen the change set past the index to every change in the tree unstaged **and untracked**. | off |
19
+ | `--scope` `<path>` | Path filter on the change set; always wins over change-set auto-discovery. | the whole change set |
19
20
 
20
21
  For shared semantics, see the [flag glossary](../skills/spur-dev/references/flag-glossary.md).
21
22
 
22
23
  ## Usage
23
24
 
24
- /sp:dev-gitmsg [--commit] [--squash] [--scope <path>]
25
+ /sp:dev-gitmsg [--commit] [--squash] [--all] [--scope <path>]
25
26
 
26
27
  ## Implementation
27
28
 
28
29
  Follow the inline procedure in [dev-operations.md](../skills/spur-dev/references/dev-operations.md#9-gitmsg) (gitmsg).
29
30
 
31
+ One diff capture per run — `-U0`, lockfiles excluded, 60 KB cap — is the token contract; never re-read
32
+ the diff wider. Neither `--commit` nor `--squash` → messages only. `--commit` → one commit per concern, split automatically,
33
+ so the operator is never asked to re-stage and re-run. `--squash` → one commit for everything.
34
+ An empty index widens to the whole tree only on a message-only run, and says so; a committing run
35
+ stops there and prints the exact `--all` re-run line instead of guessing.
@@ -62,25 +62,14 @@ The real GitHub CI runner passes. **Do not** modify the build infrastructure to
62
62
  Then stop the run (this stage failed). The operator can proceed by re-running without `--act`.
63
63
 
64
64
  **3 — Generate a conventional commit message.** Follow the gitmsg procedure (the same one
65
- `/sp:dev-gitmsg` runs). Run `git diff --cached --stat` (add `-- <path>` when `--scope` is given) for
66
- the outline; if it is empty, stage the intended changes first and report "no staged changes" if
67
- nothing was meant to be committed. Capture the full diff to a temp file
68
- (`TEMP_FILE="/tmp/gitdiff_$(date +%s)"; git diff --cached > "$TEMP_FILE" 2>&1`). Read it and write
69
- **one sentence per changed file** what changed and why. Group the per-file sentences by concern;
70
- for each group derive its commit type (`feat` · `fix` · `refactor` · `docs` · `chore` · `perf` ·
71
- `test` · `style`), scope (affected module/package, or the `--scope` value), and message:
72
-
73
- ```
74
- <type>(<scope>): <summary>
75
-
76
- <body — optional bullets from the group's per-file sentences>
77
- ```
78
-
79
- Summary: imperative mood, ≤72 chars, lowercase first word, no period. Body only when the change is
80
- non-obvious. Resolve groups: one group → emit its message; multiple groups → emit one message per
81
- group plus a split recommendation (stage per concern, re-run); under this all-in-one flow, prefer a
82
- single combined message (dominant type/scope, per-file bullets) so the push is atomic. Delete the
83
- temp file (`rm "$TEMP_FILE"`) — no `/tmp` diff residue.
65
+ `/sp:dev-gitmsg` runs) see
66
+ [dev-operations.md](../skills/spur-dev/references/dev-operations.md#9-gitmsg): one bounded diff
67
+ capture, concern grouping, conventional `<type>(<scope>): <summary>` formatting. Two deviations
68
+ belong to this flow: read the change set with `--all` semantics (this stage commits everything the
69
+ gate just proved green, not only what happens to be staged), and resolve multiple concerns to a
70
+ **single combined message** (dominant type/scope, one body bullet per concern) so the push is
71
+ atomic. `--scope <path>` bounds the capture as usual. If the change set is empty, report
72
+ "no changes to commit" and stop.
84
73
 
85
74
  **4 — Commit.** Stage all intended changes (`git add`) and commit with the resolved message
86
75
  (`git commit -m "$MESSAGE"`). When `--dry-run`, print the message and the copy-paste `git commit` /
@@ -20,7 +20,7 @@ contract below maps to that workflow's transitions.
20
20
  | `--approve-taste` | With `--auto`: set idea_approved + design_approved so idea-eval / design-approval do not pause. | off |
21
21
  | `--idea-approved` | Compatibility alias for idea_approved=true (subset of --approve-taste). | off |
22
22
  | `--design-approved` | Compatibility alias for design_approved=true (subset of --approve-taste). | off |
23
- | `--agent` `<auto\|name>` | Who runs the model-bearing ideation. The pipeline's `agent.run` stages are headless — they always dispatch a subprocess, so `--agent inline` is rejected there with the stable special error (exit 2). Use `omit` (resolves to `agent.default`), `auto` (tier-resolves an executor), or a name (pins that executor). | agent.default |
23
+ | `--agent` `<auto\|name>` | Who runs the model-bearing ideation. The pipeline's `agent.run` stages are headless — they always dispatch a subprocess. Omission and explicit `--agent inline` resolve identically per task 0687: tier substitution plus one warning naming the substituted executor; `auto` (tier-resolves an executor); a name (pins that executor). | inline |
24
24
 
25
25
  For shared semantics, see the [flag glossary](../skills/spur-dev/references/flag-glossary.md).
26
26
 
@@ -16,7 +16,7 @@ Wraps the **sp:spur-dev** skill.
16
16
  | `"<description>"` | Feature description to plan. | required |
17
17
  | `--feature` `<id>` | Attach to an existing feature. | omitted |
18
18
  | `--parent` `<feature-id>` | Create under a parent feature. | omitted |
19
- | `--agent` `<inline\|auto\|name>` | Who runs the model-bearing planning. The planning pipeline's `agent.run` stages are headless — they always dispatch a subprocess. Explicit `--agent inline` is rejected there with the stable special error (exit 2): a headless surface cannot host a session no dispatch, no `agent.default` fallback. Use `omit` (resolves to `agent.default`), `auto` (tier-resolves an executor), or a name (pins that executor). | agent.default |
19
+ | `--agent` `<inline\|auto\|name>` | Who runs the model-bearing planning. The planning pipeline's `agent.run` stages are headless — they always dispatch a subprocess. `inline` also what omission resolves to since task 0687 substitutes tier resolution there with one warning naming the resolved executor; `auto` (tier-resolves an executor); a name (pins that executor). | inline |
20
20
  | `--skip-design` | Omit the system-design hop. | off |
21
21
  | `--auto` | Skip objective HITL gates. | off |
22
22
  | `--approve-taste` | With --auto: skip design-approval pause. | off |
@@ -15,7 +15,7 @@ Wraps the **sp:spur-dev** and **sp:code-implementation** skills.
15
15
  | --- | --- | --- |
16
16
  | `<wbs>` | Task WBS to run. | required |
17
17
  | `--mode` `<full\|implement>` | Full pipeline or single implement step. | full |
18
- | `--agent` `<inline\|auto\|name>` | Who runs the model-bearing stages. In an interactive session, omit/`inline` keeps the controller in the host session (non-subprocess) — **omit**'s eligible full-mode `agent.run` stages may dispatch once to a native subagent, with host fallback (task 0508); explicit `--agent inline` is the zero-dispatch carve-out (every stage executes in the invoking session, never a native subagent). `auto` or a name keeps subprocess dispatch. | omit |
18
+ | `--agent` `<inline\|auto\|name>` | Who runs the model-bearing stages. omit and explicit `--agent inline` resolve identically (task 0687): eligible stages dispatch once to a native subagent with host-session fallback (0508 eligibility); otherwise every stage executes in the invoking session. `auto` or a name keeps subprocess dispatch.. | omit |
19
19
  | `--auto` | Skip objective HITL confirmations. | off |
20
20
  | `--next` | Chain-to-completion via the next-router. | off |
21
21
  | `--wrap` | Run the wrap hop after the main step. The `--agent` selector is preserved into the `/sp:dev-wrap <wbs>` handoff when supplied; omission remains omission. The wrap hop is workflow-backed and reports its trigger-3 subprocess override. | off |
@@ -39,7 +39,7 @@ For shared semantics, see the [flag glossary](../skills/spur-dev/references/flag
39
39
 
40
40
  **Flags:**
41
41
 
42
- - `--auto` | `--agent <inline|auto|name>` — Skip objective HITL confirmations (taste/irreversible gates still pause). `--agent` names who does the model-bearing work. Interactive omit/`inline` keeps the controller and implement-only stages in this session; full mode reads `task-pipeline.yaml` as the SSOT and interprets its actions/guards through the inline driver, where **omitted** `--agent`'s eligible `agent.run` stages may dispatch once to a native subagent and otherwise run in the host (task 0508); explicit `--agent inline` is the zero-dispatch carve-out — every stage executes in the invoking session. It records `stage <id> executed inline in session <session-id>` or `stage <id> executed via subagent <agent-id> (host session <session-id>)` in the run log. `auto` or a name is merged into `vars.agent` and `vars.implementAgent` and keeps the existing subprocess workflow. Headless `spur workflow run` / `spur agent run` is unchanged. See the [execution-surface contract](../skills/spur-dev/references/cross-cutting.md#inline-default-execution-surface).
42
+ - `--auto` | `--agent <inline|auto|name>` — Skip objective HITL confirmations (taste/irreversible gates still pause). `--agent` names who does the model-bearing work. Interactive omit/`inline` keeps the controller and implement-only stages in this session; full mode reads `task-pipeline.yaml` as the SSOT and interprets its actions/guards through the inline driver, whose eligible `agent.run` stages dispatch once to a native subagent and otherwise run in the host (0508 eligibility task 0687 resolved-inline) It records `stage <id> executed inline in session <session-id>` or `stage <id> executed via subagent <agent-id> (host session <session-id>)` in the run log. `auto` or a name is merged into `vars.agent` and `vars.implementAgent` and keeps the existing subprocess workflow. Headless `spur workflow run` / `spur agent run` is unchanged. See the [execution-surface contract](../skills/spur-dev/references/cross-cutting.md#inline-default-execution-surface).
43
43
 
44
44
  `--worktree` `[<name>]` (run the task's pipeline in an isolated git worktree — FF-merge onto the
45
45
  base ref on full success, retain intact on any failure/halt/non-FF; bare form creates a fresh tree,
@@ -18,7 +18,7 @@ Wraps the **sp:spur-dev** skill.
18
18
  | `--mode` `<sequential\|parallel>` | Batch execution order. | sequential |
19
19
  | `--keep-going` | Continue past per-task failures. | off |
20
20
  | `--auto` | Skip objective HITL gates. | off |
21
- | `--agent` `<inline\|auto\|name>` | Who runs each task's pipeline stages. Interactive sequential omit/`inline` uses the host-session driver host-controlled; **omit**'s eligible `agent.run` stages may use a native subagent (task 0508); explicit `--agent inline` is the zero-dispatch carve-out (every stage executes in the invoking session). `auto`, a name, parallel mode, and headless invocation use subprocesses. | omit |
21
+ | `--agent` `<inline\|auto\|name>` | Who runs each task's pipeline stages. Interactive sequential omit/`inline` uses the host-session driver with unified inline semantics (task 0687 see below)). `auto`, a name, parallel mode, and headless invocation use subprocesses. | omit |
22
22
  | `--json` | Emit structured JSON. | off |
23
23
  | `--wrap` | Run the wrap hop per task. The `--agent` selector is preserved into each `/sp:dev-wrap <wbs>` handoff when supplied; omission remains omission. | off |
24
24
  | `--next` | Chain-to-completion via the next-router. | off |
@@ -81,6 +81,6 @@ full distinction.
81
81
 
82
82
  ## Implementation
83
83
 
84
- - Apply the [inline-default execution-surface contract](../skills/spur-dev/references/cross-cutting.md#inline-default-execution-surface). Interactive sequential omit/`inline` keeps the orchestrator in the host session through the [inline pipeline driver](../skills/spur-dev/references/inline-pipeline-driver.md); **omitted** `--agent`'s eligible `agent.run` stages may dispatch once to a native subagent with host fallback (task 0508); explicit `--agent inline` is the zero-dispatch carve-out. `--agent auto`, a name, or parallel mode retains the isolated per-task workflow boundary.
84
+ - Apply the [inline-default execution-surface contract](../skills/spur-dev/references/cross-cutting.md#inline-default-execution-surface). Interactive sequential omit/`inline` keeps the orchestrator in the host session through the [inline pipeline driver](../skills/spur-dev/references/inline-pipeline-driver.md); the resolved selector applies uniformly — eligible `agent.run` stages dispatch once to a native subagent with host fallback (0508). `--agent auto`, a name, or parallel mode retains the isolated per-task workflow boundary.
85
85
  - Interactive sequential omit/inline: `Skill(skill="sp:spur-dev", args="runall-inline $ARGUMENTS")`.
86
86
  - Explicit executor or parallel mode: `Skill(skill="sp:spur-dev", args="runall $ARGUMENTS")` → `sp:super-planner` agent.
@@ -14,7 +14,7 @@ Wraps the **wrapup-pipeline.yaml** workflow.
14
14
  | Flag | Description | Default |
15
15
  | --- | --- | --- |
16
16
  | `<wbs>` | Task WBS to wrap. | required |
17
- | `--agent` `<inline\|auto\|name>` | Who runs the wrap's model-bearing steps. Wrap is workflow-backed (headless): `omit` resolves to `agent.default` (objective trigger 3 durable auditable run record required); explicit `--agent inline` is rejected with the stable special error — a headless workflow surface cannot host a session; `auto` tier-resolves an executor; a name pins that executor into `vars.agent`. | agent.default |
17
+ | `--agent` `<inline\|auto\|name>` | Who runs the wrap's model-bearing steps. Wrap is workflow-backed (headless): `omit` and `--agent inline` resolve identically per task 0687 — tier substitution under objective trigger 3 (durable auditable run record required) with a warning naming the substituted executor; `auto` tier-resolves an executor; a name pins that executor into `vars.agent`. | inline |
18
18
  | `--auto` | Skip objective HITL gates. | off |
19
19
  | `--merge` | Merge the wrap branch. | off |
20
20
  | `--dry-run` | Render the wrap without writing. | off |
@@ -32,13 +32,13 @@ For shared semantics, see the [flag glossary](../skills/spur-dev/references/flag
32
32
  - Resolve the executor **before** launching the workflow:
33
33
  - `--agent <name>` → pass the name unchanged into `vars.agent`.
34
34
  - `--agent auto` → tier-resolve a concrete executor first, then merge it into `vars.agent`.
35
- - omit resolve to `agent.default`; explicit `--agent inline` rejected with the stable special error (headless surface no dispatch, no `agent.default` fallback).
35
+ - omit and explicit `--agent inline` resolve identically (task 0687): tier substitution plus one warning naming the resolved executor (headless surface).
36
36
  - Emit a pre-dispatch notice naming the override before `spur workflow run`, exactly:
37
- `execution surface: subprocess`, `reason: trigger 3 — durable auditable run record required`, `requested agent: inline|auto|<name>` (explicit `inline` rejects before dispatch no executor resolves), `executor: agent.default|<resolved-name>`.
37
+ `execution surface: subprocess`, `reason: trigger 3 — durable auditable run record required`, `requested agent: inline|auto|<name>` (explicit `inline` substitutes tier resolution and warns), `executor: <substituted-name>|<resolved-name>`.
38
38
  - The wrap workflow still creates its durable run record (task_run_links / trace) — the notice reports the override, it does not change the workflow.
39
39
 
40
40
  ```bash
41
- AGENT=… # resolved above: agent.default for omitted, tier-resolved for auto, unchanged for <name>; explicit inline errors (headless)
41
+ AGENT=… # omit≡inline tier-substituted executor + warning; auto tier-resolved; <name> unchanged
42
42
  echo "execution surface: subprocess; reason: trigger 3 — durable auditable run record required; requested agent: <inline|auto|name>; executor: $AGENT"
43
43
  VARS=$(jq -nc --arg tasks "[\"$WBS\"]" --arg agent "$AGENT" --arg profile "$PROFILE" --arg merge "$MERGE" \
44
44
  '{tasks:$tasks, agent:$agent, profile:$profile, merge:$merge}')
@@ -46,5 +46,4 @@ spur workflow run wrapup-pipeline.yaml --vars "$VARS" [--dry-run]
46
46
  ```
47
47
 
48
48
  The executor resolution is described in the bullets above; the snippet's `AGENT` variable carries
49
- the resolved name (`agent.default` for omitted `--agent`; explicit `--agent inline` is rejected
50
- before dispatch).
49
+ the resolved name (omit explicit `inline`; both tier-substitute with a warning).
@@ -16,7 +16,7 @@ Wraps the **wrapup-pipeline.yaml** workflow.
16
16
  | `--since` `<iso-date>` | Wrap tasks completed since a date. | configured |
17
17
  | `--feature` `<id>` | Wrap tasks in a feature. | omitted |
18
18
  | `--status` `<s>` | Only wrap tasks in a status. | done |
19
- | `--agent` `<inline\|auto\|name>` | Who runs the wrap's model-bearing steps. Wrap is workflow-backed (headless): `omit` resolves to `agent.default` (objective trigger 3 durable auditable run record required); explicit `--agent inline` is rejected with the stable special error — a headless workflow surface cannot host a session; `auto` tier-resolves an executor; a name pins that executor into `vars.agent`. | agent.default |
19
+ | `--agent` `<inline\|auto\|name>` | Who runs the wrap's model-bearing steps. Wrap is workflow-backed (headless): `omit` and `--agent inline` resolve identically per task 0687 — tier substitution under objective trigger 3 (durable auditable run record required) with a warning naming the substituted executor; `auto` tier-resolves an executor; a name pins that executor into `vars.agent`. | inline |
20
20
  | `--auto` | Skip objective HITL gates. | off |
21
21
  | `--merge` | Merge wrap branches. | off |
22
22
  | `--dry-run` | Render wraps without writing. | off |
@@ -34,13 +34,13 @@ For shared semantics, see the [flag glossary](../skills/spur-dev/references/flag
34
34
  - Resolve the executor **before** launching the workflow:
35
35
  - `--agent <name>` → pass the name unchanged into `vars.agent`.
36
36
  - `--agent auto` → tier-resolve a concrete executor first, then merge it into `vars.agent`.
37
- - omit resolve to `agent.default`; explicit `--agent inline` rejected with the stable special error (headless surface no dispatch, no `agent.default` fallback).
37
+ - omit and explicit `--agent inline` resolve identically (task 0687): tier substitution plus one warning naming the resolved executor (headless surface).
38
38
  - Emit a pre-dispatch notice naming the override before `spur workflow run`, exactly:
39
- `execution surface: subprocess`, `reason: trigger 3 — durable auditable run record required`, `requested agent: inline|auto|<name>` (explicit `inline` rejects before dispatch no executor resolves), `executor: agent.default|<resolved-name>`.
39
+ `execution surface: subprocess`, `reason: trigger 3 — durable auditable run record required`, `requested agent: inline|auto|<name>` (explicit `inline` substitutes tier resolution and warns), `executor: <substituted-name>|<resolved-name>`.
40
40
  - The wrap workflow still creates its durable run record — the notice reports the override, it does not change the workflow.
41
41
 
42
42
  ```bash
43
- AGENT=… # resolved above: agent.default for omitted, tier-resolved for auto, unchanged for <name>; explicit inline errors (headless)
43
+ AGENT=… # omit≡inline tier-substituted executor + warning; auto tier-resolved; <name> unchanged
44
44
  echo "execution surface: subprocess; reason: trigger 3 — durable auditable run record required; requested agent: <inline|auto|name>; executor: $AGENT"
45
45
  VARS=$(jq -nc --arg tasks "$TASKS" --arg feature "$FEATURE" --arg agent "$AGENT" --arg profile "$PROFILE" --arg merge "$MERGE" \
46
46
  '{tasks:$tasks, feature:$feature, agent:$agent, profile:$profile, merge:$merge}')
@@ -48,6 +48,4 @@ spur workflow run wrapup-pipeline.yaml --vars "$VARS" [--dry-run]
48
48
  ```
49
49
 
50
50
  The executor resolution is described in the bullets above; the snippet's `AGENT` variable carries
51
- the resolved name (`agent.default` for omitted `--agent`; explicit `--agent inline` is rejected
52
- before dispatch).
53
-
51
+ the resolved name (omit explicit `inline`; both tier-substitute with a warning).
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sp",
3
- "version": "0.3.63",
3
+ "version": "0.3.64",
4
4
  "description": "Spur — a local-first harness engineering toolkit that wraps mainstream coding agents with constraint checking, workflow orchestration, and history analytics.",
5
5
  "extensions": {
6
6
  "pi": ["./hooks/pi/guard-extension.ts"]
@@ -404,8 +404,9 @@ function dayBounds(tz, ymd) {
404
404
  };
405
405
  }
406
406
  function resolvePaths(opts) {
407
- const pluginRoot = opts.helper.replace(/\/scripts\/[^/]+$/, "");
408
- const skill = `${pluginRoot}/skills/history-anatomy`;
407
+ const m = opts.helper.match(/\/scripts\/(?:([^/]+)\/)?[^/]+$/);
408
+ const pluginRoot = m ? opts.helper.slice(0, m.index) : opts.helper;
409
+ const skill = `${pluginRoot}/skills/${m?.[1] ? `${m[1]}-history-anatomy` : "history-anatomy"}`;
409
410
  const tz = opts.tz ?? Intl.DateTimeFormat().resolvedOptions().timeZone ?? "UTC";
410
411
  const date = opts.date !== undefined && opts.date !== "" ? opts.date : localDay(tz, opts.now ?? new Date);
411
412
  const target = opts.output !== undefined && opts.output !== "" ? opts.output : `${opts.reportDir}/${date}-history-anatomy.md`;
@@ -563,8 +563,13 @@ export function resolvePaths(opts: {
563
563
  since?: string;
564
564
  until?: string;
565
565
  }): string {
566
- const pluginRoot = opts.helper.replace(/\/scripts\/[^/]+$/, '');
567
- const skill = `${pluginRoot}/skills/history-anatomy`;
566
+ // Layouts: monorepo `<root>/scripts/<file>` → skill `<root>/skills/history-anatomy`;
567
+ // superskill-installed `<root>/scripts/<plugin>/<file>` → skill `<root>/skills/<plugin>-history-anatomy`.
568
+ // (0660 dogfood 2026-08-26: the single-segment strip left HA_SKILL bogus on installed layouts,
569
+ // silently degrading probe contract/skill digests to "not available".)
570
+ const m = opts.helper.match(/\/scripts\/(?:([^/]+)\/)?[^/]+$/);
571
+ const pluginRoot = m ? opts.helper.slice(0, m.index) : opts.helper;
572
+ const skill = `${pluginRoot}/skills/${m?.[1] ? `${m[1]}-history-anatomy` : 'history-anatomy'}`;
568
573
  const tz = opts.tz ?? Intl.DateTimeFormat().resolvedOptions().timeZone ?? 'UTC';
569
574
  const date = opts.date !== undefined && opts.date !== '' ? opts.date : localDay(tz, opts.now ?? new Date());
570
575
  const target =
@@ -48,7 +48,7 @@ testee (a /sp:... command, Skill(...), or shell CLI invocation)
48
48
  The command forwards these via `$ARGUMENTS`:
49
49
 
50
50
  | Argument | Description | Default |
51
- |----------|-------------|---------|
51
+ | ---------- | ------------- | --------- |
52
52
  | `testee` | What to exercise — a slash command, agent skill, or CLI invocation (positional, required). Quote it if it contains flags. | (required) |
53
53
  | `--agent <name\|auto>` | **Testee-scoped** agent: the agent the **testee** runs under, forwarded into the testee invocation. The driver (this skill) always runs in the current session. **Omit it** to forward nothing — the testee runs under its own default. See [§Testee-scoped agent](#testee-scoped-agent). | (omitted → forward nothing) |
54
54
  | `--max-retry <n>` | Fix attempts per failed step. The **default is `2`** (fix mode): apply `Edit`/`Write` fixes to the working tree, up to 2 attempts per step. This flag is **mandatory** for two independent mutation sources: (a) pipeline-driving testees and (b) testees carrying a mutating `--fix` mode (`--fix all` / `--fix blockers-first`). Pass `--max-retry 0` for **observe-only**, or `--max-retry N` to acknowledge fix-mode mutation risk. For a mutating-`--fix` testee, `--max-retry 0` bounds the **driver only** — the testee still mutates the tree. | `2` unless the testee is pipeline-driving or carries a mutating `--fix` mode |
@@ -239,6 +239,7 @@ Full section contract, frontmatter, Cost shape, and footer:
239
239
  **[report-template.md](references/report-template.md)**.
240
240
 
241
241
  **Sinks** (composable):
242
+
242
243
  - **Always-on report files** → live + `docs/dogfood/YYYY-MM-DD-<testee-slug>-dogfood.md` (see Phase 1).
243
244
  - `--save` → no-op for delivery; still print/document the report path (back-compat).
244
245
  - `--task` → file findings as a review task (`spur task create --template review`), writing the
@@ -276,6 +277,7 @@ which always launches a fresh agent subprocess.
276
277
  - Producing a structured findings report (and optionally a fix task) from a real run.
277
278
 
278
279
  Do **not** use this skill for:
280
+
279
281
  - Requirements-traceability verdicts — use `sp:code-verification` (`/sp:dev-verify`).
280
282
  - SECU code review of a diff — use `sp:code-verification` (`/sp:dev-review`).
281
283
  - Running a task through the fix pipeline — use `sp:spur-dev` (`/sp:dev-run`).
@@ -606,3 +608,14 @@ Findings (P1+P2):
606
608
  A report missing any of the six headings, the on-disk live ledger, dual paths, terminal `status`,
607
609
  the Cost block, or this footer does not satisfy the dogfood contract on this platform, regardless
608
610
  of `Skill()` availability.
611
+
612
+ ## Engine-driven testees under a sandboxed session
613
+
614
+ A subprocess executor dies at startup, not at model time, when `.claude/settings.json` denies
615
+ it its state directory (`~/.pi`, `~/.grok`, `~/.gemini`, `~/.codex`, `~/.cache`) or local
616
+ socket binding. Signals: `EPERM: operation not permitted`, `FS_PERMISSION_DENIED`,
617
+ `bind: operation not permitted`. Two affordances must be granted and the session restarted:
618
+ `sandbox.filesystem.allowWrite` covering the executor home dirs, and
619
+ `sandbox.network.allowLocalBinding`. Caveat: `spur agent doctor` reports `usable: true` from
620
+ configuration alone — it never probes a real dispatch, so `usable` means *configured*, not
621
+ *proven runnable under this sandbox*.
@@ -175,6 +175,14 @@ proposal-only: no applied change, no diff, and no command the report claims to h
175
175
  The final section lists, for every finding, the artifact anchor(s) and any cited `file:line`,
176
176
  so a reader can verify the report's claims against the evidence plane.
177
177
 
178
+ Every row MUST name the artifact path in backticks — the deterministic structure gate's
179
+ `evidence-claim-without-anchor` check matches `` `[^`]+\.(md|ts|json)` `` or a
180
+ `path:line` — never a bare `current`/`baseline` label. Write each anchor as:
181
+
182
+ ```text
183
+ `telemetry:history-analyze:duration-coverage-gap` | `.spur/run/<runId>-history-anatomy-current.json` — `#/warnings/0`, `#/derived/timeDecomposition`, `#/stepSupport`
184
+ ```
185
+
178
186
  ## Truthfulness invariants
179
187
 
180
188
  - `not available` is the true rendering for an unsupported dimension, never a masked gap.
@@ -42,12 +42,12 @@ silently (that is a HITL stop).
42
42
  ## Inputs
43
43
 
44
44
  | Input | Semantics |
45
- |-------|-----------|
45
+ | ------- | ----------- |
46
46
  | `target` | Task WBS (digits), task `.md` path, or feature id (`^[A-Z][1-9]*$`). Required for dispatch; omit → stop **U1** (usage). |
47
47
  | `--dry-run` | Print the resolved plan (**P1**) and do not dispatch. |
48
48
  | `--once` | Strip `--next` from the shaped child argv so only the current step runs; no router re-entry. |
49
49
  | `--auto` | Forward into dispatched children that support it. **Never** breaks multi-candidate HITL ties. |
50
- | `--agent <inline\|auto\|name>` | Execution-surface selector forwarded into the dispatched child when that child documents `--agent`. Router defaults to omit semantics: Omit forwards nothing, and the dispatched child applies its own default (host session, 0508 eligibility). Explicit `--agent inline` is the zero-dispatch carve-out, forwarded as-is; escalation triggers reject `inline` (no override). |
50
+ | `--agent <inline\|auto\|name>` | Execution-surface selector forwarded into the dispatched child when that child documents `--agent`. Router defaults to omit semantics: Omit forwards nothing, and the dispatched child applies its own default (`inline`, task 0687 — native-subagent-first with host fallback). Explicit `--agent inline` is forwarded as-is and resolves identically; escalation triggers take precedence over `inline`. |
51
51
  | `--full` | When the primary route is `dev-run … --next`, substitute `dev-run <wbs> --mode full` (no `--next`). No effect on non-run routes → warning **W-FULL**. |
52
52
 
53
53
  ## Protocol (deterministic)
@@ -126,7 +126,7 @@ but redundant. See the glossary entry for the disambiguation in full.
126
126
  **[references/messages.md](references/messages.md)** (exact templates, prefixed `dev-next:`). The router fires them by id:
127
127
 
128
128
  | Id | Fires when | Kind |
129
- |----|-----------|------|
129
+ | ---- | ----------- | ------ |
130
130
  | U1 | no target | stop — usage |
131
131
  | U2 | target unresolvable | stop |
132
132
  | U3 | no route (table miss / cancelled) | stop |
@@ -147,7 +147,7 @@ bypass lifecycle guards (`--no-lifecycle`) to force progress.
147
147
  ## Common Rationalizations
148
148
 
149
149
  | Rationalization | Reality |
150
- |---|---|
150
+ | --- | --- |
151
151
  | "Two candidates are both fine — pick the higher-priority one." | Multi-candidate is a HITL stop (routing-table §4). A silent pick hides a real fork from the operator; print the decision-brief. |
152
152
  | "The task is todo, so run the full pipeline to be safe." | Full mode is not the v1 default (non-route). A3 dispatches the `--next` chain link; `--full` exists for the explicit override. |
153
153
  | "I can loop dev-next until the task is done." | Step budget is one dispatch per invocation. Self-looping makes token cost unbounded; the operator re-invokes after non-chain dispatches. |
@@ -86,11 +86,10 @@ Parse the first positional argument as the mode; default `full`.
86
86
  - `--agent <inline|auto|name>` — names **who performs model-bearing work**, per the
87
87
  [inline-default execution-surface contract](../spur-dev/references/cross-cutting.md#inline-default-execution-surface).
88
88
  Omit: the current agent is the default owner (eligible model stages may use one native subagent
89
- under the shared contract). `inline` keeps all model work in the host session as the hard
90
- zero-dispatch guarantee. `auto` resolves the command's declared role; a named executor pins that executor.
89
+ under the shared contract). `inline` (also what omission resolves to, task 0687) keeps model work in the host session native-subagent-first with host fallback where eligible `auto` resolves the command's declared role; a named executor pins that executor.
91
90
  An alternate executor gets one `spur agent run --agent <value>` dispatch with the selector removed
92
91
  from child args; that child owns model work. Current-agent selection stays inline.
93
- Headless surfaces reject explicit `inline` with the shared stable error.
92
+ Headless surfaces substitute tier resolution for `inline` with a warning (task 0687), never refusing.
94
93
  - `--agent` describes the model owner only; it is independent of the deterministic git/GitHub spine
95
94
  and the workflow/direct route. Run the selected route in that resolved skill context. A separate
96
95
  workflow subprocess belongs to the caller's execution surface or an objective trigger (for example,