@gobing-ai/spur 0.4.10 → 0.4.12
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.example.yaml +22 -0
- package/config/rules/quality/coverage-gate.yaml +2 -2
- package/config/rules/surface/check-cli-surface.yaml +4 -0
- package/config/workflows/feature-verification.yaml +14 -5
- package/config/workflows/idea-pipeline.yaml +92 -12
- package/config/workflows/pr-review.yaml +72 -224
- package/config/workflows/task-pipeline.yaml +456 -830
- package/config/workflows/wayfinder-resolution.yaml +20 -3
- package/config/workflows/wrapup-pipeline.yaml +22 -9
- package/package.json +1 -1
- package/plugins/sp/README.md +2 -2
- package/plugins/sp/agents/super-planner.md +2 -2
- package/plugins/sp/agents/super-reviewer.md +17 -8
- package/plugins/sp/bunfig.toml +3 -3
- package/plugins/sp/commands/dev-changelog.md +1 -1
- package/plugins/sp/commands/dev-gitmsg.md +2 -2
- package/plugins/sp/commands/dev-handover.md +1 -1
- package/plugins/sp/commands/dev-idea.md +23 -13
- package/plugins/sp/commands/dev-job-dump.md +1 -1
- package/plugins/sp/commands/dev-plan.md +17 -6
- package/plugins/sp/commands/dev-pr-review.md +27 -17
- package/plugins/sp/commands/dev-review.md +1 -1
- package/plugins/sp/commands/dev-run.md +7 -6
- package/plugins/sp/commands/dev-runall.md +1 -1
- package/plugins/sp/plugin.json +1 -1
- package/plugins/sp/skills/code-implementation/SKILL.md +7 -7
- package/plugins/sp/skills/code-refactoring/SKILL.md +1 -1
- package/plugins/sp/skills/code-verification/SKILL.md +1 -1
- package/plugins/sp/skills/code-verification/references/secu-review.md +8 -4
- package/plugins/sp/skills/code-verification/references/verdict-schema.md +23 -10
- package/plugins/sp/skills/doc-evolve/SKILL.md +1 -1
- package/plugins/sp/skills/next-router/references/routing-table.md +1 -1
- package/plugins/sp/skills/parallel-execution/references/dispatch-surface.md +7 -7
- package/plugins/sp/skills/pr-reviewing/SKILL.md +157 -210
- package/plugins/sp/skills/source-driven-development/SKILL.md +14 -6
- package/plugins/sp/skills/spec-decomposition/references/decomposition.md +4 -4
- package/plugins/sp/skills/spur-check/SKILL.md +9 -8
- package/plugins/sp/skills/spur-cli/SKILL.md +3 -3
- package/plugins/sp/skills/spur-cli/references/builder.md +86 -13
- package/plugins/sp/skills/spur-cli/references/self.md +37 -2
- package/plugins/sp/skills/spur-cli/references/tasks/l3-guard-cheatsheet.md +1 -1
- package/plugins/sp/skills/spur-cli/references/tasks/verbs.md +3 -3
- package/plugins/sp/skills/spur-cli/references/tasks.md +1 -1
- package/plugins/sp/skills/spur-cli/references/workflows.md +5 -3
- package/plugins/sp/skills/spur-dev/SKILL.md +3 -3
- package/plugins/sp/skills/spur-dev/references/cross-cutting.md +9 -8
- package/plugins/sp/skills/spur-dev/references/dev-operations.md +11 -11
- package/plugins/sp/skills/spur-dev/references/done-housekeeping.md +4 -3
- package/plugins/sp/skills/spur-dev/references/execution-batch-report.md +4 -4
- package/plugins/sp/skills/spur-dev/references/execution-batch.md +13 -11
- package/plugins/sp/skills/spur-dev/references/execution-workflow.md +31 -22
- package/plugins/sp/skills/spur-dev/references/execution-worktree-landing.md +5 -5
- package/plugins/sp/skills/spur-dev/references/execution-worktree-setup.md +4 -4
- package/plugins/sp/skills/spur-dev/references/flag-glossary.md +3 -2
- package/plugins/sp/skills/spur-dev/references/gate-checklists.md +4 -4
- package/schemas/spur-config.schema.json +19 -1
- package/spur.js +32388 -31906
- package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +0 -997
- package/plugins/sp/skills/spur-dev/references/structured-trace-emission.md +0 -178
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: structured-trace-emission
|
|
3
|
-
description: "Structured trace emission (task 1128 split, ADR-117 / task 0868): the action vocabulary, the per-step emit shape, the close contract and the parse rules the host driver follows. Read it when the first trace event is emitted."
|
|
4
|
-
see_also:
|
|
5
|
-
- inline-pipeline-driver
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## Structured trace emission (ADR-117, task 0868)
|
|
9
|
-
|
|
10
|
-
`.spur/memory/runs/<run-id>.md` is the human half of the two-file run record — evidence, **not the record
|
|
11
|
-
of truth**. A run's
|
|
12
|
-
observability is a property of the run, so the inline driver owes the same structured trace the
|
|
13
|
-
engine subprocess writes — and it owes it through the **same writer**, never a parallel
|
|
14
|
-
implementation. The shared writer is `WorkflowActionTraceWriter`
|
|
15
|
-
(`packages/app/src/workflow/action-trace.ts`): the same decorator the engine composition installs
|
|
16
|
-
around `DbWorkflowPersistenceAdapter`, so the two surfaces call one emission path and one run-row
|
|
17
|
-
closure path and cannot drift.
|
|
18
|
-
|
|
19
|
-
The driver reaches it through the installed CLI transport `spur workflow inline <op>` (the same
|
|
20
|
-
command that began the run) — no second entry point, no second resolution chain:
|
|
21
|
-
|
|
22
|
-
- **Every executed action** — after the action settles, whether it ran host-inline or via a native
|
|
23
|
-
subagent — append its provenance line as before, then record the boundary:
|
|
24
|
-
|
|
25
|
-
```bash
|
|
26
|
-
spur workflow inline action --run-id "$RUN_ID" --node <state-id> --kind <action-kind> \
|
|
27
|
-
--status <done|failed> --ok <true|false> [--duration-ms <measured-ms>] [--estimated] \
|
|
28
|
-
--project-root "$OWNING_TREE"
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
`<state-id>` is the current YAML state id (the `node`), `<action-kind>` the YAML action kind
|
|
32
|
-
(`agent.run`, `shell`, `note`, `doctor.probe`, …). `--status` is `done` when the action settled
|
|
33
|
-
under its declared error policy and `failed` otherwise. This writes the `action_runs` row (node,
|
|
34
|
-
kind, status, `ok`, `duration_ms`, `run_id`) the engine would have written, so the run's rows are
|
|
35
|
-
queryable by run id (`spur workflow progress <run-id>`, `ActionRunDao`) without reading the text
|
|
36
|
-
log. The writer
|
|
37
|
-
back-dates the row's `started_at` from its own `completed_at` minus the measured duration
|
|
38
|
-
(0887 R8), so `completed_at − started_at == duration_ms` exactly; a back-date failure is
|
|
39
|
-
recorded (`action.backdate`) and never affects the run.
|
|
40
|
-
|
|
41
|
-
**`--project-root` names the tree that owns the run row (task 1136 R1/R2).** Per-tree DBs are
|
|
42
|
-
deliberate, so when the driver runs inside a `--worktree` (or any other execution tree) the run row
|
|
43
|
-
lives in the **invoking** tree's `.spur/spur.db` while the action commands run in the execution
|
|
44
|
-
tree. `--project-root` is the invoking tree recorded by the WT-3 marker; without it the row is read
|
|
45
|
-
from the cwd tree. A run-row miss is a **correctness failure**, not a best-effort emission failure:
|
|
46
|
-
`inline action`, `inline actions` and `inline node-enter` exit `1` with
|
|
47
|
-
`{"ok":false,"code":"RUN_NOT_FOUND"}`, exactly like `inline close`. **Never redirect these calls'
|
|
48
|
-
stdout/stderr to `/dev/null`** — the suppressed-RUN_NOT_FOUND run of task 1132 lost 93 action rows
|
|
49
|
-
to exactly that redirect. Capture the output or let it stream; a failure must be visible.
|
|
50
|
-
|
|
51
|
-
**Durations: measured beats reported (task 1136 R4).** Stamp the enter time before the action runs:
|
|
52
|
-
|
|
53
|
-
```bash
|
|
54
|
-
spur workflow inline node-enter --run-id "$RUN_ID" --node <state-id> --project-root "$OWNING_TREE"
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
Then call `inline action` **without** `--duration-ms` — the delegate computes
|
|
58
|
-
`duration = now − enter` and stamps `provenance: measured` into `action_runs.result_json`. A
|
|
59
|
-
caller-supplied `--duration-ms` stays valid but is recorded `provenance: host-reported` (with
|
|
60
|
-
`--estimated` marking a value reconstructed after the fact); every other inline row is
|
|
61
|
-
`host-reported` too, and the projection exposes `provenance` per attempt so the Board can label a
|
|
62
|
-
reported duration instead of presenting it as measured. A row whose computed start would precede
|
|
63
|
-
`runs.started_at` is **rejected** (exit `1`) — a timestamp before the run began is a broken clock,
|
|
64
|
-
not evidence. Calling `inline action` without `--duration-ms` and without a matching `inline node-enter`
|
|
65
|
-
exits `1` with `code:"ACTION_DURATION_UNAVAILABLE"`; it never silently drops the row.
|
|
66
|
-
|
|
67
|
-
- **A state with several actions (1007 R5)** — emit the whole state's boundaries in one call
|
|
68
|
-
instead of one `inline action` invocation per action. Write a JSON array
|
|
69
|
-
(`[{node,kind,status,ok,durationMs,estimated?}, …]` — the `inline action` fields, `estimated`
|
|
70
|
-
optional and `false` when absent) to a temp file and pass it with `spur workflow inline actions --file`:
|
|
71
|
-
|
|
72
|
-
```bash
|
|
73
|
-
spur workflow inline actions --file <actions.json> --run-id "$RUN_ID" --project-root "$OWNING_TREE"
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
Every row is recorded through the same writer as `inline action` (one `action_runs` row per entry);
|
|
77
|
-
the batch is validated in full before the first write, so an invalid row or unreadable file
|
|
78
|
-
exits `1` with `{"ok":false}` and leaves **no** partial rows — fix the batch and re-emit. On
|
|
79
|
-
success it prints `{"ok":true,"runId":…,"recorded":<n>}` and exits `0`. Row emission stays
|
|
80
|
-
best-effort exactly like `inline action`: if a row's write fails mid-batch, the failure is recorded
|
|
81
|
-
to the run record and the call reports `{"ok":false,…,"error":…}` but still exits `0` — the run
|
|
82
|
-
continues; never retry the batch or backfill by hand. Each op takes only its own flags: an
|
|
83
|
-
unknown flag (say `--status` on `inline actions`) is a usage error (exit 2), and such a call
|
|
84
|
-
must be corrected, not silently split.
|
|
85
|
-
|
|
86
|
-
- **A `decide` action (0941)** — the driver never executes the DecisionMaker itself; it delegates
|
|
87
|
-
to the same app runner the engine registers, which writes the resultFile row (schemaVersion 1)
|
|
88
|
-
and returns the decision, then the delegate records the `action_runs` row (`kind=decide`)
|
|
89
|
-
through the same writer as every other action:
|
|
90
|
-
|
|
91
|
-
```bash
|
|
92
|
-
spur workflow inline decide --run-id "$RUN_ID" --node <state-id> --options-json <options-file>
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
The options JSON mirrors the YAML `decide` options (`id`, `method: choice|noul`, `question`,
|
|
96
|
-
`choices`/`default`, optional `evidence`, optional `minConfidence`, `resultFile`); paths resolve
|
|
97
|
-
against the project workdir. The decision never pauses and never fails the run for model
|
|
98
|
-
problems: a degraded outcome (feature switch off, no backend, error, timeout, low confidence)
|
|
99
|
-
prints `ok:true` with `degraded:true`, the declared `reason`, and `value = default`, and exits
|
|
100
|
-
`0` — route on the resultFile's `.value` with the declared file guards. Every row carries
|
|
101
|
-
`source: model|default` (0976 R2), and the delegate appends
|
|
102
|
-
`decide node=<id> value=<v> source=<s> reason=<r>` to the run log, so a declared-default
|
|
103
|
-
fallback is never read as a model decision. Only an invalid options
|
|
104
|
-
schema exits `1` (fail closed), and usage errors exit `2`. The `action_runs` trace row is
|
|
105
|
-
best-effort exactly like `inline action`.
|
|
106
|
-
|
|
107
|
-
- **An operator pause is its own row (task 1136 R5)** — while the driver waits on a `hitl.confirm`
|
|
108
|
-
or `hitl.input`, emit the wait as its own boundary instead of charging it to the neighbouring
|
|
109
|
-
node:
|
|
110
|
-
|
|
111
|
-
```bash
|
|
112
|
-
spur workflow inline action --run-id "$RUN_ID" --node <state-id> --kind operator-wait \
|
|
113
|
-
--status done --ok true --duration-ms <waited-ms> --project-root "$OWNING_TREE"
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
`operator-wait` is a row kind, not a new state — the decision itself still belongs to the
|
|
117
|
-
declared node, and the wait's wall clock stays visible instead of inflating the node's duration.
|
|
118
|
-
|
|
119
|
-
- **At the run's declared terminal state** — before the driver reports the run complete, close the
|
|
120
|
-
row so a successful inline run is never left non-terminal for `spur workflow clean` to reap as
|
|
121
|
-
stale:
|
|
122
|
-
|
|
123
|
-
```bash
|
|
124
|
-
spur workflow inline close --run-id "$RUN_ID" --status <done|failed|paused> --project-root "$OWNING_TREE"
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
The close also produces the execution summary (1146 R1): its stdout carries
|
|
128
|
-
**`summaryFile`** (`.spur/run/<runId>-summary.md`) unless `--no-summary` was passed. Print that
|
|
129
|
-
file's contents verbatim under an `### Execution summary` heading — the driver generates nothing
|
|
130
|
-
itself, and the window is the run row's `started_at` → close time, so no `SINCE` is recorded. A
|
|
131
|
-
summary failure never changes the close verdict: the file then holds exactly
|
|
132
|
-
`Execution summary: n/a (<reason>)`.
|
|
133
|
-
|
|
134
|
-
`--status` is the declared terminal state's verdict, not a guess: a run that reached a terminal
|
|
135
|
-
state is `done`; a run halted by a failing action under its error policy is `failed`. On success
|
|
136
|
-
the close reports the recorded evidence: `{"ok":true,"runId":…,"actionRows":<n>}` plus
|
|
137
|
-
**`missingNodes`** — the declared states the driver recorded as entered that never emitted an
|
|
138
|
-
`action_runs` row (`{"missingNodes":["precheck","verify"]}`, empty array when the trace is
|
|
139
|
-
whole). `missingNodes` is a **trace defect reported, never a close failure**: the close still
|
|
140
|
-
exits `0`, and it exists so a gap is visible — the repair is to emit the missing rows in the next
|
|
141
|
-
run, never to backfill them (ADR-117).
|
|
142
|
-
After the close, the invoking command prints the measured
|
|
143
|
-
[execution summary](dev-operations.md#execution-summary) for `$RUN_ID` unless `--no-summary`.
|
|
144
|
-
|
|
145
|
-
**Zero-row done closes are a named failure (task 0975 R2).** A run closed `done` with **zero**
|
|
146
|
-
`action_runs` rows (`actionRows:0`) finalizes the row but exits `1` with
|
|
147
|
-
`{"ok":false,"code":"NO_ACTION_ROWS","actionRows":0}` — a run that claims success without a
|
|
148
|
-
single recorded action is exactly the untraced-runs gap ADR-117 closes, so the driver must
|
|
149
|
-
surface the code in its final report instead of reporting a clean close. The failure must NOT
|
|
150
|
-
be repaired by backfilling rows: the run row is already terminal, and hand-written rows are
|
|
151
|
-
forbidden (ADR-117) — record the finding and let the task's evidence show the gap. A `failed`
|
|
152
|
-
close with zero rows stays a clean `0` (a halt before the first boundary legitimately records
|
|
153
|
-
nothing), and any `done` close with `actionRows ≥ 1` exits `0`.
|
|
154
|
-
|
|
155
|
-
**Best-effort at the action boundary only (ADR-117, task 1136 R1/R2).** An `inline action` persistence
|
|
156
|
-
failure is recorded — the delegate appends a `trace-emission-failed` line to
|
|
157
|
-
`.spur/memory/runs/<run-id>.md` and prints `{"ok":false}` on stdout — and the run continues to its
|
|
158
|
-
declared terminal state; the delegate exits `0` for that outcome and the driver must never treat an
|
|
159
|
-
emission failure as a run failure, retry it in a loop, or substitute a hand-written row. The
|
|
160
|
-
exception is the **run row itself**: a missing run row, a duration that cannot be measured, or a
|
|
161
|
-
start time before `runs.started_at` are correctness failures and exit `1`
|
|
162
|
-
(`RUN_NOT_FOUND`, `ACTION_DURATION_UNAVAILABLE`). The run-row closure (`inline close`) is bookkeeping, not
|
|
163
|
-
trace emission, and is **not** best-effort either: a missing run row or a persistence failure exits
|
|
164
|
-
`1` with `{"ok":false}` and a named error (a missing row also carries `code:"RUN_NOT_FOUND"`),
|
|
165
|
-
because a silently `running` row is exactly the stale state `spur workflow clean` reaps as `failed`.
|
|
166
|
-
Exit `2` means the invocation itself was malformed (missing `--node`/`--kind`/`--status`/`--ok`, a
|
|
167
|
-
miscased `--ok`, or a malformed `--duration-ms`) and must be corrected, not ignored.
|
|
168
|
-
|
|
169
|
-
**Never suppress this output.** The driver reference forbids redirecting `spur workflow inline`,
|
|
170
|
-
`quality-gate` and `persist-out*` stdout/stderr to `/dev/null`; a static pin fails any reference
|
|
171
|
-
snippet that does. Suppressing a `RUN_NOT_FOUND` is how task 1132's 93 action rows disappeared.
|
|
172
|
-
|
|
173
|
-
Emission is not optional and not deferred: an inline run that skips it reintroduces the
|
|
174
|
-
1,011-untraced-runs gap ADR-117 exists to close.
|
|
175
|
-
|
|
176
|
-
Transition guards are not advisory. Execute the declared guard exactly, in order, with the same
|
|
177
|
-
resolved variables and artifacts. `--no-lifecycle` remains bookkeeping only; the YAML's task checks,
|
|
178
|
-
verdict gate, record step, and done guard all remain authoritative.
|