@gobing-ai/spur 0.3.42 → 0.3.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/config/workflows/task-pipeline.yaml +10 -0
- package/package.json +9 -9
- package/plugins/sp/commands/dev-run.md +3 -3
- package/plugins/sp/commands/dev-runall.md +7 -4
- package/plugins/sp/commands/dev-wrap.md +21 -3
- package/plugins/sp/commands/dev-wrapall.md +21 -3
- package/plugins/sp/plugin.json +1 -1
- package/plugins/sp/skills/code-implementation/SKILL.md +27 -0
- package/plugins/sp/skills/issue-finding/SKILL.md +21 -3
- package/plugins/sp/skills/issue-finding/references/session-formats.md +30 -0
- package/plugins/sp/skills/next-router/references/routing-table.md +2 -2
- package/plugins/sp/skills/parallel-execution/references/dispatch-surface.md +9 -0
- package/plugins/sp/skills/spur-cli/references/tasks.md +3 -1
- package/plugins/sp/skills/spur-dev/references/cross-cutting.md +22 -6
- package/plugins/sp/skills/spur-dev/references/dev-operations.md +13 -13
- package/plugins/sp/skills/spur-dev/references/execution-batch.md +66 -3
- package/plugins/sp/skills/spur-dev/references/execution-workflow.md +4 -2
- package/plugins/sp/skills/spur-dev/references/flag-glossary.md +1 -1
- package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +43 -11
- package/spur.js +383 -224
|
@@ -188,6 +188,11 @@ states:
|
|
|
188
188
|
# a tree already dirty with another task's implementation is how 0485's diff
|
|
189
189
|
# got swept into 0486's run. Corpus dirs are excluded: the pipeline writes
|
|
190
190
|
# those itself.
|
|
191
|
+
# R1 (0511): task-corpus dirt gets its own advisory NOTE — docs/tasks* is
|
|
192
|
+
# excluded from the non-corpus warning, so pre-existing task-corpus edits are
|
|
193
|
+
# invisible at launch yet can be accidentally staged with the current task
|
|
194
|
+
# later. Advisory only (never a block): the pipeline legitimately updates
|
|
195
|
+
# task files, so corpus dirt is launch-time visibility, not a lifecycle guard.
|
|
191
196
|
- kind: shell
|
|
192
197
|
options:
|
|
193
198
|
command: >-
|
|
@@ -196,6 +201,11 @@ states:
|
|
|
196
201
|
echo "precheck: WARNING - working tree has uncommitted non-corpus changes; commit or stash before starting a new task:";
|
|
197
202
|
echo "$DIRTY";
|
|
198
203
|
fi;
|
|
204
|
+
CORPUS_DIRTY=$(git status --porcelain -- ':(glob)docs/tasks*/**' 2>/dev/null);
|
|
205
|
+
if [ -n "$CORPUS_DIRTY" ]; then
|
|
206
|
+
echo "precheck: NOTE - task corpus has uncommitted changes; review before staging with this task:";
|
|
207
|
+
echo "$CORPUS_DIRTY";
|
|
208
|
+
fi;
|
|
199
209
|
exit 0
|
|
200
210
|
- kind: note
|
|
201
211
|
options:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gobing-ai/spur",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.43",
|
|
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.
|
|
57
|
-
"@gobing-ai/ts-ai-runner": "^0.4.
|
|
58
|
-
"@gobing-ai/ts-dual-workflow-engine": "^0.4.
|
|
59
|
-
"@gobing-ai/ts-infra": "^0.4.
|
|
60
|
-
"@gobing-ai/ts-llm-jsonl-importer": "^0.4.
|
|
61
|
-
"@gobing-ai/ts-rule-engine": "^0.4.
|
|
62
|
-
"@gobing-ai/ts-runtime": "^0.4.
|
|
63
|
-
"@gobing-ai/ts-utils": "^0.4.
|
|
56
|
+
"@gobing-ai/ts-db": "^0.4.27",
|
|
57
|
+
"@gobing-ai/ts-ai-runner": "^0.4.27",
|
|
58
|
+
"@gobing-ai/ts-dual-workflow-engine": "^0.4.27",
|
|
59
|
+
"@gobing-ai/ts-infra": "^0.4.27",
|
|
60
|
+
"@gobing-ai/ts-llm-jsonl-importer": "^0.4.27",
|
|
61
|
+
"@gobing-ai/ts-rule-engine": "^0.4.27",
|
|
62
|
+
"@gobing-ai/ts-runtime": "^0.4.27",
|
|
63
|
+
"@gobing-ai/ts-utils": "^0.4.27",
|
|
64
64
|
"@types/bun": "1.3.14",
|
|
65
65
|
"@types/figlet": "^1.7.0",
|
|
66
66
|
"@types/node-notifier": "8.0.5",
|
|
@@ -14,10 +14,10 @@ Wraps the **sp:spur-dev** and **sp:code-implementation** skills.
|
|
|
14
14
|
| --- | --- | --- |
|
|
15
15
|
| `<wbs>` | Task WBS to run. | required |
|
|
16
16
|
| `--mode` `<full\|implement>` | Full pipeline or single implement step. | full |
|
|
17
|
-
| `--agent` `<inline\|auto\|name>` | Who runs the model-bearing stages. In an interactive session, omit/`inline`
|
|
17
|
+
| `--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); eligible full-mode `agent.run` stages may dispatch once to a native subagent, with host fallback (task 0508). `auto` or a name keeps subprocess dispatch. | inline |
|
|
18
18
|
| `--auto` | Skip objective HITL confirmations. | off |
|
|
19
19
|
| `--next` | Chain-to-completion via the next-router. | off |
|
|
20
|
-
| `--wrap` | Run the wrap hop after the main step. | off |
|
|
20
|
+
| `--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 |
|
|
21
21
|
| `--continue` | Resume an interrupted task from its checkpoint. | off |
|
|
22
22
|
|
|
23
23
|
For shared semantics, see the [flag glossary](../skills/spur-dev/references/flag-glossary.md).
|
|
@@ -37,7 +37,7 @@ For shared semantics, see the [flag glossary](../skills/spur-dev/references/flag
|
|
|
37
37
|
|
|
38
38
|
**Flags:**
|
|
39
39
|
|
|
40
|
-
- `--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
|
|
40
|
+
- `--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 eligible `agent.run` stages may dispatch once to a native subagent and otherwise run in the host (task 0508). 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).
|
|
41
41
|
|
|
42
42
|
**Mode split (load-bearing — bug-742)**
|
|
43
43
|
|
|
@@ -17,9 +17,9 @@ Wraps the **sp:spur-dev** skill.
|
|
|
17
17
|
| `--mode` `<sequential\|parallel>` | Batch execution order. | sequential |
|
|
18
18
|
| `--keep-going` | Continue past per-task failures. | off |
|
|
19
19
|
| `--auto` | Skip objective HITL gates. | off |
|
|
20
|
-
| `--agent` `<inline\|auto\|name>` | Who runs each task's pipeline stages. Interactive sequential omit/`inline` uses the host-session driver; `auto`, a name, parallel mode, and headless invocation use subprocesses. | inline |
|
|
20
|
+
| `--agent` `<inline\|auto\|name>` | Who runs each task's pipeline stages. Interactive sequential omit/`inline` uses the host-session driver — host-controlled, eligible `agent.run` stages may use a native subagent (task 0508); `auto`, a name, parallel mode, and headless invocation use subprocesses. | inline |
|
|
21
21
|
| `--json` | Emit structured JSON. | off |
|
|
22
|
-
| `--wrap` | Run the wrap hop per task. | off |
|
|
22
|
+
| `--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 |
|
|
23
23
|
| `--next` | Chain-to-completion via the next-router. | off |
|
|
24
24
|
| `--continue` | Resume an interrupted batch. | off |
|
|
25
25
|
| `--worktree` `[<name>]` | Run the batch in an isolated git worktree; FF-merge on success, retain on failure. Bare `--worktree` creates a fresh tree; `--worktree <name>` adopts an existing worktree by name/path/branch. | off |
|
|
@@ -33,7 +33,10 @@ For shared semantics, see the [flag glossary](../skills/spur-dev/references/flag
|
|
|
33
33
|
```
|
|
34
34
|
|
|
35
35
|
Flags: `--tasks <selector>` (required — explicit WBS list, status pseudo-list, `feature:<id>`,
|
|
36
|
-
or `ready`), `--feature <id>` (sugar for `feature:<id
|
|
36
|
+
or `ready`), `--feature <id>` (sugar for `feature:<id>`; when the effective selector is
|
|
37
|
+
feature-derived, `dev-runall` runs `spur feature check <id> --strict --json` **once** before
|
|
38
|
+
resolving tasks — a non-zero strict check aborts the batch with verdict `aborted` and the
|
|
39
|
+
structured findings, before any task pipeline action, task 0510 R2), `--mode`
|
|
37
40
|
`<sequential|parallel>` (default `sequential`; `parallel` fans out a proven-independent subset —
|
|
38
41
|
see `execution-batch.md` § Parallel Execution), `--keep-going`
|
|
39
42
|
(batch failure policy — skip a failed task's in-batch dependents, continue independents; default
|
|
@@ -75,6 +78,6 @@ full distinction.
|
|
|
75
78
|
|
|
76
79
|
## Implementation
|
|
77
80
|
|
|
78
|
-
- 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
|
|
81
|
+
- 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); eligible `agent.run` stages may dispatch once to a native subagent with host fallback (task 0508). `--agent auto`, a name, or parallel mode retains the isolated per-task workflow boundary.
|
|
79
82
|
- Interactive sequential omit/inline: `Skill(skill="sp:spur-dev", args="runall-inline $ARGUMENTS")`.
|
|
80
83
|
- Explicit executor or parallel mode: `Skill(skill="sp:spur-dev", args="runall $ARGUMENTS")` → `sp:super-planner` agent.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Wrap up a single completed task — learnings, metrics, doc-sync, optional feature transition and branch cleanup
|
|
3
|
-
argument-hint: "<wbs> [--auto] [--merge] [--dry-run]"
|
|
3
|
+
argument-hint: "<wbs> [--agent <inline|auto|name>] [--auto] [--merge] [--dry-run]"
|
|
4
4
|
allowed-tools: ["Bash", "Read", "AskUserQuestion"]
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -13,6 +13,7 @@ Wraps the **wrapup-pipeline.yaml** workflow.
|
|
|
13
13
|
| Flag | Description | Default |
|
|
14
14
|
| --- | --- | --- |
|
|
15
15
|
| `<wbs>` | Task WBS to wrap. | required |
|
|
16
|
+
| `--agent` `<inline\|auto\|name>` | Who runs the wrap's model-bearing steps. Wrap is workflow-backed: omit/`inline` resolves to `agent.default` (objective trigger 3 — durable auditable run record required); `auto` tier-resolves an executor; a name pins that executor into `vars.agent`. | agent.default |
|
|
16
17
|
| `--auto` | Skip objective HITL gates. | off |
|
|
17
18
|
| `--merge` | Merge the wrap branch. | off |
|
|
18
19
|
| `--dry-run` | Render the wrap without writing. | off |
|
|
@@ -21,10 +22,27 @@ For shared semantics, see the [flag glossary](../skills/spur-dev/references/flag
|
|
|
21
22
|
|
|
22
23
|
## Usage
|
|
23
24
|
|
|
24
|
-
/sp:dev-wrap <wbs> [--auto] [--merge] [--dry-run]
|
|
25
|
+
/sp:dev-wrap <wbs> [--agent <inline|auto|name>] [--auto] [--merge] [--dry-run]
|
|
25
26
|
|
|
26
27
|
## Implementation
|
|
27
28
|
|
|
29
|
+
- Apply the [inline-default execution-surface contract](../skills/spur-dev/references/cross-cutting.md#inline-default-execution-surface).
|
|
30
|
+
- Wrap stays **workflow-backed** — `spur workflow run .spur/workflows/wrapup-pipeline.yaml` is the only implementation; there is no inline wrap driver.
|
|
31
|
+
- Resolve the executor **before** launching the workflow:
|
|
32
|
+
- `--agent <name>` → pass the name unchanged into `vars.agent`.
|
|
33
|
+
- `--agent auto` → tier-resolve a concrete executor first, then merge it into `vars.agent`.
|
|
34
|
+
- omit/`--agent inline` → resolve to `agent.default` (the documented headless resolution of `inline`).
|
|
35
|
+
- Emit a pre-dispatch notice naming the override before `spur workflow run`, exactly:
|
|
36
|
+
`execution surface: subprocess`, `reason: trigger 3 — durable auditable run record required`, `requested agent: inline|auto|<name>`, `executor: agent.default|<resolved-name>`.
|
|
37
|
+
- The wrap workflow still creates its durable run record (task_run_links / trace) — the notice reports the override, it does not change the workflow.
|
|
38
|
+
|
|
28
39
|
```bash
|
|
29
|
-
|
|
40
|
+
AGENT=… # resolved above: agent.default for inline/omitted, tier-resolved for auto, unchanged for <name>
|
|
41
|
+
echo "execution surface: subprocess; reason: trigger 3 — durable auditable run record required; requested agent: <inline|auto|name>; executor: $AGENT"
|
|
42
|
+
VARS=$(jq -nc --arg tasks "[\"$WBS\"]" --arg agent "$AGENT" --arg profile "$PROFILE" --arg merge "$MERGE" \
|
|
43
|
+
'{tasks:$tasks, agent:$agent, profile:$profile, merge:$merge}')
|
|
44
|
+
spur workflow run .spur/workflows/wrapup-pipeline.yaml --vars "$VARS" [--dry-run]
|
|
30
45
|
```
|
|
46
|
+
|
|
47
|
+
The executor resolution is described in the bullets above; the snippet's `AGENT` variable carries
|
|
48
|
+
the resolved name (`agent.default` for omit/`inline`).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Wrap up a batch of completed tasks — learnings, metrics, doc-sync, feature transition, optional branch cleanup
|
|
3
|
-
argument-hint: "[--since <iso-date>] [--feature <id>] [--status <s>] [--auto] [--merge] [--dry-run]"
|
|
3
|
+
argument-hint: "[--since <iso-date>] [--feature <id>] [--status <s>] [--agent <inline|auto|name>] [--auto] [--merge] [--dry-run]"
|
|
4
4
|
allowed-tools: ["Bash", "Read", "AskUserQuestion"]
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -15,6 +15,7 @@ Wraps the **wrapup-pipeline.yaml** workflow.
|
|
|
15
15
|
| `--since` `<iso-date>` | Wrap tasks completed since a date. | configured |
|
|
16
16
|
| `--feature` `<id>` | Wrap tasks in a feature. | omitted |
|
|
17
17
|
| `--status` `<s>` | Only wrap tasks in a status. | done |
|
|
18
|
+
| `--agent` `<inline\|auto\|name>` | Who runs the wrap's model-bearing steps. Wrap is workflow-backed: omit/`inline` resolves to `agent.default` (objective trigger 3 — durable auditable run record required); `auto` tier-resolves an executor; a name pins that executor into `vars.agent`. | agent.default |
|
|
18
19
|
| `--auto` | Skip objective HITL gates. | off |
|
|
19
20
|
| `--merge` | Merge wrap branches. | off |
|
|
20
21
|
| `--dry-run` | Render wraps without writing. | off |
|
|
@@ -23,11 +24,28 @@ For shared semantics, see the [flag glossary](../skills/spur-dev/references/flag
|
|
|
23
24
|
|
|
24
25
|
## Usage
|
|
25
26
|
|
|
26
|
-
/sp:dev-wrapall [--since <iso-date>] [--feature <id>] [--status <s>] [--auto] [--merge] [--dry-run]
|
|
27
|
+
/sp:dev-wrapall [--since <iso-date>] [--feature <id>] [--status <s>] [--agent <inline|auto|name>] [--auto] [--merge] [--dry-run]
|
|
27
28
|
|
|
28
29
|
## Implementation
|
|
29
30
|
|
|
31
|
+
- Apply the [inline-default execution-surface contract](../skills/spur-dev/references/cross-cutting.md#inline-default-execution-surface).
|
|
32
|
+
- Wrap stays **workflow-backed** — `spur workflow run .spur/workflows/wrapup-pipeline.yaml` is the only implementation; there is no inline wrap driver.
|
|
33
|
+
- Resolve the executor **before** launching the workflow:
|
|
34
|
+
- `--agent <name>` → pass the name unchanged into `vars.agent`.
|
|
35
|
+
- `--agent auto` → tier-resolve a concrete executor first, then merge it into `vars.agent`.
|
|
36
|
+
- omit/`--agent inline` → resolve to `agent.default` (the documented headless resolution of `inline`).
|
|
37
|
+
- Emit a pre-dispatch notice naming the override before `spur workflow run`, exactly:
|
|
38
|
+
`execution surface: subprocess`, `reason: trigger 3 — durable auditable run record required`, `requested agent: inline|auto|<name>`, `executor: agent.default|<resolved-name>`.
|
|
39
|
+
- The wrap workflow still creates its durable run record — the notice reports the override, it does not change the workflow.
|
|
40
|
+
|
|
30
41
|
```bash
|
|
31
|
-
|
|
42
|
+
AGENT=… # resolved above: agent.default for inline/omitted, tier-resolved for auto, unchanged for <name>
|
|
43
|
+
echo "execution surface: subprocess; reason: trigger 3 — durable auditable run record required; requested agent: <inline|auto|name>; executor: $AGENT"
|
|
44
|
+
VARS=$(jq -nc --arg tasks "$TASKS" --arg feature "$FEATURE" --arg agent "$AGENT" --arg profile "$PROFILE" --arg merge "$MERGE" \
|
|
45
|
+
'{tasks:$tasks, feature:$feature, agent:$agent, profile:$profile, merge:$merge}')
|
|
46
|
+
spur workflow run .spur/workflows/wrapup-pipeline.yaml --vars "$VARS" [--dry-run]
|
|
32
47
|
```
|
|
33
48
|
|
|
49
|
+
The executor resolution is described in the bullets above; the snippet's `AGENT` variable carries
|
|
50
|
+
the resolved name (`agent.default` for omit/`inline`).
|
|
51
|
+
|
package/plugins/sp/plugin.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sp",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.43",
|
|
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"]
|
|
@@ -92,6 +92,33 @@ only burns wall clock and context budget.
|
|
|
92
92
|
- If a targeted probe reveals a failure you cannot fix within implement scope, note it in
|
|
93
93
|
`## Solution` and let the `test` hop's fixall handle it — do not pre-empt the gate.
|
|
94
94
|
|
|
95
|
+
## Changed-path targeted checks (dependency-aware verification, task 0510 R3)
|
|
96
|
+
|
|
97
|
+
"Run the narrow test first" needs a second half: *which* narrow tests, when a change to a shared
|
|
98
|
+
surface can break a downstream consumer. The matrix below is dependency-aware — domain → app →
|
|
99
|
+
CLI — so a shared change verifies its consumers without recreating the full project check inside
|
|
100
|
+
implement. **It augments narrow behavior tests; it never authorizes `bun run spur-check`,
|
|
101
|
+
`bun run test`, or another full project check inside implement** — the pipeline's `test` hop owns
|
|
102
|
+
that single full gate.
|
|
103
|
+
|
|
104
|
+
| Changed surface | Required targeted tests | Required typechecks |
|
|
105
|
+
| --- | --- | --- |
|
|
106
|
+
| `packages/domain/src/**` public type/query | affected domain test; affected app service test; affected CLI command test | `@gobing-ai/spur-domain`, `@gobing-ai/spur-app`, `@gobing-ai/spur` |
|
|
107
|
+
| `packages/app/src/**` public service/type | affected app test; affected CLI command test | `@gobing-ai/spur-app`, `@gobing-ai/spur` |
|
|
108
|
+
| `apps/cli/src/**` | affected `apps/cli/tests/**` file | `@gobing-ai/spur` |
|
|
109
|
+
| shared plugin flag/command/reference | affected plugin structure/contract test; add `flag-contract-parity.test.ts` **only** when the shared flag surface changes | no package typecheck unless TypeScript also changed |
|
|
110
|
+
|
|
111
|
+
- Apply **only the matching rows** for the surfaces actually changed; a multi-surface change applies
|
|
112
|
+
the union.
|
|
113
|
+
- Workspace typechecks run as `bun run --filter <workspace> typecheck` for each listed workspace
|
|
114
|
+
(monorepo; installed/other projects substitute their package-manager surface).
|
|
115
|
+
- The shared plugin row is deliberately conditional: a pure reference/prose change needs only the
|
|
116
|
+
affected structure test; `flag-contract-parity.test.ts` is added only when the shared flag surface
|
|
117
|
+
(a flag the plugin layer consumes) actually changes, so an unconditional parity suite does not
|
|
118
|
+
creep into every plugin edit.
|
|
119
|
+
- Run the applicable rows, then stop: the single full project check belongs to the pipeline's
|
|
120
|
+
`test` hop (`task-pipeline.yaml` `${vars.qualityGateCmd}`).
|
|
121
|
+
|
|
95
122
|
## Behavior
|
|
96
123
|
|
|
97
124
|
This skill behaves as a **technique**: given a task (read its Background, AC, Design, Plan), it maps
|
|
@@ -169,9 +169,27 @@ count identical commands for loop detection.
|
|
|
169
169
|
Produce per-session metrics (duration, tools, compactions, test runs, spur calls, guard failures,
|
|
170
170
|
key finding). Aggregate totals across sessions.
|
|
171
171
|
|
|
172
|
-
When `--use-history` is set,
|
|
173
|
-
|
|
174
|
-
|
|
172
|
+
When `--use-history` is set, the **selected-file history bridge** supplies ETL aggregates for the
|
|
173
|
+
frozen session set (task 0507 R3):
|
|
174
|
+
|
|
175
|
+
1. **Freeze Phase 1's selected OMP JSONL files once** — the same inventory the raw analysis reads.
|
|
176
|
+
Discovery roots: the normal OMP session root (`~/.omp/agent/sessions/`) **and**
|
|
177
|
+
`.spur/run/<run-id>/agent-sessions/<omp-executor>/*.jsonl` for workflow subprocess sessions.
|
|
178
|
+
Never import a broad `.spur/run` scan and never run a full/source-root reconciliation here.
|
|
179
|
+
2. **Import each frozen file once, through the source-local CLI**, with single-file `force-file`
|
|
180
|
+
mode:
|
|
181
|
+
`bun run apps/cli/src/index.ts history import --source omp --file <absolute-file> --mode force-file --json`.
|
|
182
|
+
The importer derives the session key from the filename; use the same stem for analysis.
|
|
183
|
+
3. **Analyze scoped to that key**: `history analyze --session <filename-stem> --json`.
|
|
184
|
+
4. Use the artifact for the aggregates ETL can represent — tokens, cost, messages, tool calls,
|
|
185
|
+
loops, and assistant response duration. **Continue parsing the same raw files** for command text,
|
|
186
|
+
compactions, test/guard retries, tool execution duration/status/errors, and every other signal
|
|
187
|
+
the ETL does not carry.
|
|
188
|
+
|
|
189
|
+
ETL supplies normalized aggregates; it is **not** a substitute for raw tool-loop evidence. If an
|
|
190
|
+
import fails or the DB is empty, continue with raw logs and note that cost data is unavailable.
|
|
191
|
+
Before any ad-hoc verification SQL against `history_*` tables, follow the schema-first rule in
|
|
192
|
+
[references/session-formats.md](references/session-formats.md) — inspect the live schema once.
|
|
175
193
|
|
|
176
194
|
### Phase 3: IDENTIFY — Root Cause Ranking
|
|
177
195
|
|
|
@@ -104,6 +104,36 @@ For issue-finding:
|
|
|
104
104
|
Import does not invent bottleneck categories. If import fails or the DB is empty, continue with
|
|
105
105
|
raw logs and note that cost data is unavailable.
|
|
106
106
|
|
|
107
|
+
**Schema-first rule (task 0506 R3):** history tables are owned by
|
|
108
|
+
`@gobing-ai/ts-llm-jsonl-importer` and can change between versions — never copy column lists
|
|
109
|
+
into this skill. Before any ad-hoc verification SQL that references importer-owned `history_*`
|
|
110
|
+
tables, run **one** schema-introspection query for every table you need and compose the data
|
|
111
|
+
queries from that result:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
# one introspection pass, then write data queries against what it reports
|
|
115
|
+
sqlite3 <db> "SELECT name, sql FROM sqlite_schema WHERE type='table' AND name LIKE 'history_%';"
|
|
116
|
+
# (or a single `.schema history_<table>` invocation per referenced table)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
If a column you expected is absent, trust the live schema — do not guess. The importer's
|
|
120
|
+
`HISTORY_IMPORT_SCHEMA_SQL` is the authority; this skill holds no duplicate column contract.
|
|
121
|
+
|
|
122
|
+
**Selected-file bridge (task 0507 R3):** `--use-history` imports the frozen Phase-1 file set one
|
|
123
|
+
file at a time — never a root scan, never a full reconciliation. Ambient discovery covers the
|
|
124
|
+
normal OMP root (`~/.omp/agent/sessions/`) **and** workflow subprocess sessions under
|
|
125
|
+
`.spur/run/<run-id>/agent-sessions/<omp-executor>/*.jsonl` (same `type: "message"` envelope). For
|
|
126
|
+
each file, the session key is the JSONL filename stem (importer `sessionIdFromContext`); import and
|
|
127
|
+
analyze per key:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
bun run apps/cli/src/index.ts history import --source omp --file <absolute-file> --mode force-file --json
|
|
131
|
+
bun run apps/cli/src/index.ts history analyze --session <filename-stem> --json
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
ETL owns token/cost/message/tool/loop/assistant-duration aggregates; raw JSONL stays authoritative
|
|
135
|
+
for command text, compactions, test/guard retries, and tool execution duration/status/errors.
|
|
136
|
+
|
|
107
137
|
## Edge cases
|
|
108
138
|
|
|
109
139
|
| Scenario | Handling |
|
|
@@ -65,7 +65,7 @@ Statuses from `TASK_STATUSES`: backlog | todo | wip | testing | blocked | done |
|
|
|
65
65
|
| A5 | `status == wip` (no usable checkpoint) | `task.show.status` | `/sp:dev-run <wbs> --mode implement --auto --next` | yes | **yes** → verify | Completes implement step then chain |
|
|
66
66
|
| A6 | `status == testing` | `task.show.status` | `/sp:dev-verify <wbs> --auto --next` | yes | **yes** — verify `--next` → done (FSM + provenance guards) | On PARTIAL/FAIL → stop review-pending (do not force done) |
|
|
67
67
|
| A7 | `status == blocked` | `task.show` + Notes/History for blocker text | `/sp:dev-handover "<blocker summary from Notes or status>"` | no | no | **STOP** after handover doc; human unblocks |
|
|
68
|
-
| A8 | `status == done` | `task.show.status` | `/sp:dev-wrap <wbs>` | no | **no** (wrap's `--merge` is irreversible HITL; never auto) | Operator may re-invoke with `--merge` explicitly later |
|
|
68
|
+
| A8 | `status == done` | `task.show.status` | `/sp:dev-wrap <wbs>` (`--agent <value>` preserved when the originating command supplied it; omission remains omission) | no | **no** (wrap's `--merge` is irreversible HITL; never auto) | Operator may re-invoke with `--merge` explicitly later |
|
|
69
69
|
| A9 | `status == cancelled` | `task.show.status` | *(none)* | no | no | **STOP** — no-op; print "cancelled — nothing to advance" |
|
|
70
70
|
|
|
71
71
|
**Priority when multiple TABLE A rows could match:** lowest row number wins (A1–A9 are mutually
|
|
@@ -83,7 +83,7 @@ When input is a feature id:
|
|
|
83
83
|
| B3 | Feature has ≥1 frontier task | task list under feature | **Recurse TABLE A** on chosen task | per A | per A | Frontier = open (`backlog`\|`todo`\|`wip`\|`testing`\|`blocked`), unblocked (all `dependencies[]` done), prefer WBS-ascending among `todo` then `backlog` then `wip` then `testing` then `blocked` |
|
|
84
84
|
| B4 | No frontier tasks AND `feature.status == backlog` AND AC placeholder/invalid | `feature check` / AC body | `/sp:dev-plan` continuation is not WBS-shaped — **STOP** with: run `/sp:dev-plan --feature <id>` or fix AC then `spur feature check <id>` | no | no | Planning-half entry needs a description; do not invent idea text |
|
|
85
85
|
| B5 | No frontier tasks AND feature has valid AC but zero tasks | feature + empty task roster | **STOP** with: `/sp:dev-plan --feature <id>` (decompose/batch-create) | no | no | Avoid auto-running plan without operator description confirmation in v1 |
|
|
86
|
-
| B6 | No frontier tasks AND all child tasks `done` AND feature in `active`\|`verifying` | task list all done | `/sp:dev-wrapall --feature <id>` | no | no | Advances feature via wrapall guards; `--merge` never auto |
|
|
86
|
+
| B6 | No frontier tasks AND all child tasks `done` AND feature in `active`\|`verifying` | task list all done | `/sp:dev-wrapall --feature <id>` (`--agent <value>` preserved when the originating command supplied it; omission remains omission) | no | no | Advances feature via wrapall guards; `--merge` never auto |
|
|
87
87
|
| B7 | No frontier tasks AND mixed cancelled/done only | statuses | **STOP** — print summary; suggest feature status update manually | no | no | |
|
|
88
88
|
| B8 | `feature.status == blocked` | feature status | **STOP** — print feature blocked; do not pick tasks | no | no | |
|
|
89
89
|
|
|
@@ -89,6 +89,15 @@ non-sandboxed shell, or a workspace that owns the storage path). The upstream fi
|
|
|
89
89
|
pi-coding-agent's storage-path resolution; it is out of scope here and recorded as motivating
|
|
90
90
|
evidence only.
|
|
91
91
|
|
|
92
|
+
## Composition with the inline pipeline driver (task 0508)
|
|
93
|
+
|
|
94
|
+
The interactive inline driver (`cross-cutting.md` § Inline-default execution surface) applies this
|
|
95
|
+
reference's default — native subagent first — to sequential `task-pipeline.yaml` `agent.run`
|
|
96
|
+
stages. Eligibility there is the same observable test (pure-slash action, non-interactive state,
|
|
97
|
+
native subagent with shared-worktree capability); the inline driver remains the authority for
|
|
98
|
+
provenance, artifact validation, and no-replay guarantees. This reference stays the authority for
|
|
99
|
+
the native-subagent versus `spur agent run` choice everywhere else.
|
|
100
|
+
|
|
92
101
|
## See also
|
|
93
102
|
|
|
94
103
|
- **`parallel-execution`** SKILL.md - the dispatch disciplines this rule sits beside.
|
|
@@ -68,7 +68,9 @@ See [tasks/verbs.md](tasks/verbs.md) for the variant detail.
|
|
|
68
68
|
exit code `3` and names the existing WBS — reuse it.
|
|
69
69
|
- **`--dedupe-within <seconds>`** overrides the default window (e.g. `--dedupe-within 60`).
|
|
70
70
|
- **`--allow-duplicate-name`** disables the guard entirely (explicit override).
|
|
71
|
-
-
|
|
71
|
+
- The guard applies to every create: feature-scoped tasks collide within the same
|
|
72
|
+
feature; unscoped tasks (no `--feature`) collide with other unscoped tasks of the
|
|
73
|
+
same title (their own collision scope).
|
|
72
74
|
- With `--json`, a duplicate emits `{ ok: false, error: { code, message, existingWbs,
|
|
73
75
|
existingName, attemptedName } }` for deterministic reuse.
|
|
74
76
|
|
|
@@ -41,7 +41,7 @@ in scripts and audit output but does not change the default.
|
|
|
41
41
|
|
|
42
42
|
| Value | Who does the work | Derived surface |
|
|
43
43
|
|---|---|---|
|
|
44
|
-
| `inline` (default when omitted) | Whoever is running this session (interactive) or `agent.default` (headless) | Interactive: inline
|
|
44
|
+
| `inline` (default when omitted) | Whoever is running this session (interactive) or `agent.default` (headless) | Interactive: inline — host-controlled, eligible model stages may use a native subagent (0508); headless: subprocess of `agent.default` |
|
|
45
45
|
| `auto` | Tier-resolved from the stage's `min_tier` + `fallback` | Subprocess — a tier-resolved executor pins a specific agent/model, which the host session cannot supply |
|
|
46
46
|
| `<name>` (coding agent or configured executor) | That executor | Inline when it resolves to the current session's agent; subprocess otherwise |
|
|
47
47
|
|
|
@@ -105,11 +105,18 @@ meaningless.
|
|
|
105
105
|
**Interactive task pipelines invert control into the host session (ADR-047 amendment).**
|
|
106
106
|
`dev-run --mode full` and sequential `dev-runall` with omit/`inline` interpret the existing
|
|
107
107
|
`task-pipeline.yaml` in the host session; they do not launch `spur workflow run` and never redirect
|
|
108
|
-
silently to `agent.default`.
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
108
|
+
silently to `agent.default`. Interactive inline is **host-controlled and non-subprocess**, but no
|
|
109
|
+
longer guarantees host-context execution for every model stage (task 0508): an eligible `agent.run`
|
|
110
|
+
stage — pure-slash input, non-interactive state, native subagent with shared-worktree
|
|
111
|
+
read/write/shell capability — dispatches **once** to that native subagent and joins before the
|
|
112
|
+
driver continues; any pre-dispatch eligibility failure falls back to one host execution, and a
|
|
113
|
+
failure after dispatch follows the stage's error policy with no automatic host replay. Operator
|
|
114
|
+
confirmation actions, `pause: true`, and approve/taste/ask decisions stay host-owned. Each inline
|
|
115
|
+
model stage appends `stage <id> executed inline in session <session-id>` to its run log; a
|
|
116
|
+
subagent-dispatched stage appends `stage <id> executed via subagent <agent-id> (host session
|
|
117
|
+
<session-id>)` instead. `dev-plan` remains a workflow subprocess, as do `dev-run`/`dev-runall` with
|
|
118
|
+
`--agent auto` or a name, parallel batches, and every headless `spur workflow run` / `spur agent
|
|
119
|
+
run`. `dev-run --mode implement` continues to run its single competency in-session under omit/`inline`.
|
|
113
120
|
|
|
114
121
|
### Executor precedence chain (R7)
|
|
115
122
|
|
|
@@ -429,6 +436,15 @@ iterating one task).
|
|
|
429
436
|
2. Loop on that narrow target until green.
|
|
430
437
|
3. **Then** run the single full `spur-check` (or `bun run check`) as the final gate.
|
|
431
438
|
|
|
439
|
+
**Dependency-aware selection (task 0510 R3).** "Narrow" is not "whatever file I touched" — a change
|
|
440
|
+
to a shared surface must also verify its downstream consumers. Pick the targeted tests and
|
|
441
|
+
typechecks from the **changed-path matrix** in `code-implementation/SKILL.md` (§ Changed-path
|
|
442
|
+
targeted checks): domain changes run affected domain + app/CLI consumer tests and
|
|
443
|
+
domain/app/CLI typechecks; app changes run affected app + CLI tests and app/CLI typechecks; CLI
|
|
444
|
+
changes run affected CLI tests and the CLI typecheck; shared plugin flag/command contract changes
|
|
445
|
+
run their focused structure/parity tests. Run only the applicable rows, then stop — the full
|
|
446
|
+
project check is still the pipeline's single final gate, never a per-iteration re-run.
|
|
447
|
+
|
|
432
448
|
Do not re-run the full suite per iteration, and do not `spur-check` before you have a green narrow
|
|
433
449
|
target. **Target:** full `spur-check` runs ≤2 per task (one during iteration, one final) instead of
|
|
434
450
|
4 across a chain.
|
|
@@ -77,8 +77,8 @@ each would be scope creep for one-liner procedures.
|
|
|
77
77
|
| 12 | brainstorm | `dev-brainstorm` | `Skill()` | `sp:brainstorm` (`dev-brainstorm`) | `<topic> [--depth <basic\|detailed\|comprehensive>] [--options <n>] [--agent <inline\|auto\|name>] [--skip-discovery] [--wayfind] [--task [<feature-id>]] [--feature [<parent-id>]] [--next]` |
|
|
78
78
|
| 13 | runall | `dev-runall` | `Skill()` → agent | `sp:spur-dev` (`runall`) → `sp:super-planner` | `--tasks <selector> [--feature <id>] [--mode <sequential\|parallel>] [--keep-going] [--auto] [--agent <inline\|auto\|name>] [--json] [--wrap] [--next] [--continue] [--worktree [<name>]]` |
|
|
79
79
|
| 13a | parallel | `dev-parallel` | `Skill()` | `sp:parallel-execution` | `--tasks <selector> [--feature <id>] [--mode <fan-out\|review-panel\|investigation>] [--agent <inline\|auto\|name>] [--json]` |
|
|
80
|
-
| 14 | wrap | `dev-wrap` | `Skill()` | `spur workflow run` (wrapup-pipeline) | `<wbs> [--auto] [--merge] [--dry-run]`
|
|
81
|
-
| 15 | wrapall | `dev-wrapall` | `Skill()` | `spur workflow run` (wrapup-pipeline) | `[--since <iso>] [--feature <id>] [--status <s>] [--auto] [--merge] [--dry-run]`
|
|
80
|
+
| 14 | wrap | `dev-wrap` | `Skill()` | `spur workflow run` (wrapup-pipeline) | `<wbs> [--agent <inline\|auto\|name>] [--auto] [--merge] [--dry-run]` |
|
|
81
|
+
| 15 | wrapall | `dev-wrapall` | `Skill()` | `spur workflow run` (wrapup-pipeline) | `[--since <iso>] [--feature <id>] [--status <s>] [--agent <inline\|auto\|name>] [--auto] [--merge] [--dry-run]` |
|
|
82
82
|
| 16 | idea | `dev-idea` | `Skill()` | `spur workflow run` (idea-pipeline) | `"<idea>" [--auto] [--skip-design] [--approve-taste]` |
|
|
83
83
|
|
|
84
84
|
## Skill-backed operations
|
|
@@ -137,10 +137,10 @@ must not be changed without updating the backing skill.
|
|
|
137
137
|
### 4. run
|
|
138
138
|
|
|
139
139
|
- **Purpose:** Run a task through the execution pipeline (full) or execute a single pipeline step (implement).
|
|
140
|
-
- **Inputs:** `<wbs>` (required). `--mode <full|implement>` selects the execution mode. `implement` invokes `sp:code-implementation` inline by default. Interactive `full` with omit/`--agent inline` reads `task-pipeline.yaml` and drives its actions/guards in the host session; `--agent auto`, a name, or headless invocation launches the workflow subprocess. `--agent <inline|auto|name>` selects the execution surface (see [SSOT](cross-cutting.md#inline-default-execution-surface)). `--auto` skips the HITL approve gate / confirmations and propagates down the `--next` chain. `--next` controls chaining only and never changes the mode; a pipeline implement stage must invoke `/sp:dev-run <wbs> --mode implement`. On implement success with `--next`, transition `todo → wip → testing` through the FSM (guards honored — no `--no-lifecycle`) + chain to `/sp:dev-verify <wbs> --auto --next`. On a guard failure, stop as review-pending. **Partial-deliverable rule:** if the task ships only part of its requirements (e.g. an R1/R2 split with the rest in a follow-up task), the `## Solution` section must state that explicitly and the verify verdict will record the scope.
|
|
140
|
+
- **Inputs:** `<wbs>` (required). `--mode <full|implement>` selects the execution mode. `implement` invokes `sp:code-implementation` inline by default. Interactive `full` with omit/`--agent inline` reads `task-pipeline.yaml` and drives its actions/guards in the host session — host-controlled and non-subprocess, with eligible `agent.run` stages dispatching once to a native subagent and host fallback (task 0508); `--agent auto`, a name, or headless invocation launches the workflow subprocess. `--agent <inline|auto|name>` selects the execution surface (see [SSOT](cross-cutting.md#inline-default-execution-surface)). `--auto` skips the HITL approve gate / confirmations and propagates down the `--next` chain. `--next` controls chaining only and never changes the mode; a pipeline implement stage must invoke `/sp:dev-run <wbs> --mode implement`. On implement success with `--next`, transition `todo → wip → testing` through the FSM (guards honored — no `--no-lifecycle`) + chain to `/sp:dev-verify <wbs> --auto --next`. On a guard failure, stop as review-pending. **Partial-deliverable rule:** if the task ships only part of its requirements (e.g. an R1/R2 split with the rest in a follow-up task), the `## Solution` section must state that explicitly and the verify verdict will record the scope. `--wrap` hands off to `/sp:dev-wrap <wbs>` after the main step; the `--agent` selector is preserved into that handoff when supplied (omission remains omission), and the wrap hop reports its own trigger-3 subprocess override per the wrap contract.
|
|
141
141
|
- **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).
|
|
142
142
|
- **Modes:**
|
|
143
|
-
- **`full`** (default): Drive the full pipeline — precheck → implement → test → review → approve(HITL) → verify → record → done. Interactive omit/inline uses [inline-pipeline-driver.md](inline-pipeline-driver.md); explicit/headless executor selection invokes `spur workflow run .spur/workflows/task-pipeline.yaml --vars '{"wbs":"<wbs>"}'` (with `profile: auto` when `--auto`). Both monitor/surface HITL and preserve the YAML gates. `--next` never changes this mode.
|
|
143
|
+
- **`full`** (default): Drive the full pipeline — precheck → implement → test → review → approve(HITL) → verify → record → done. Interactive omit/inline uses [inline-pipeline-driver.md](inline-pipeline-driver.md) (host-controlled; eligible stages may use a native subagent); explicit/headless executor selection invokes `spur workflow run .spur/workflows/task-pipeline.yaml --vars '{"wbs":"<wbs>"}'` (with `profile: auto` when `--auto`). Both monitor/surface HITL and preserve the YAML gates. `--next` never changes this mode.
|
|
144
144
|
- **`implement`** (explicit `--mode implement` only): Execute only the implement step. Read the task's `## Requirements` / `## Design` / `## Plan`, write the code that satisfies them, author the `## Solution` change-map section (file:line + what/why per changed file) via `spur task update <wbs> --section Solution --from-file`. This is the implement step the pipeline calls — it is NOT the pipeline driver. With `--next`: on success, 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` and `## Review` sections MUST carry a `⚠️ PARTIAL` marker naming the deferred part and the follow-up WBS — see `plugins/sp/commands/dev-run.md` → "Section ownership".
|
|
145
145
|
- **Delegation:** `Skill(skill="sp:spur-dev", args="run-inline $ARGUMENTS")` for interactive full omit/inline; `Skill(skill="sp:spur-dev", args="run $ARGUMENTS")` for explicit/headless full mode; `Skill(skill="sp:code-implementation", args="$ARGUMENTS")` for implement mode.
|
|
146
146
|
|
|
@@ -288,7 +288,7 @@ must not be changed without updating the backing skill.
|
|
|
288
288
|
### 13. runall
|
|
289
289
|
|
|
290
290
|
- **Purpose:** Run a batch of tasks through their pipelines in dependency-correct order — resolve a set, topo-sort, run each via `task-pipeline.yaml`, inspect verdicts, apply the failure policy, emit a batch report.
|
|
291
|
-
- **Inputs:** `--tasks <selector>` (required — explicit WBS list, status pseudo-list, `feature:<id>`, or `ready`). `--mode <sequential|parallel>` (default `sequential`; `parallel` fans out a proven-independent subset per `execution-batch.md` § Parallel Execution). `--keep-going` skips a failed task's in-batch dependents and continues independents (default halts on first failure). `--auto` sets `profile=auto` on each per-task run (skips the HITL approve gate). The orchestrator loop itself continues in this session;
|
|
291
|
+
- **Inputs:** `--tasks <selector>` (required — explicit WBS list, status pseudo-list, `feature:<id>`, or `ready`). `--mode <sequential|parallel>` (default `sequential`; `parallel` fans out a proven-independent subset per `execution-batch.md` § Parallel Execution). `--keep-going` skips a failed task's in-batch dependents and continues independents (default halts on first failure). `--auto` sets `profile=auto` on each per-task run (skips the HITL approve gate). `--feature <id>` is sugar for `--tasks feature:<id>`; when the effective selector is feature-derived, the batch runs `spur feature check <id> --strict --json` **once** before task resolution — a non-zero strict check aborts with verdict `aborted`, zero attempted tasks, and the structured findings (task 0510 R2). Explicit WBS/status/`ready` selectors add no feature check. The orchestrator loop itself continues in this session; interactive sequential omit/`inline` uses the host driver — host-controlled with eligible `agent.run` stages dispatching once to a native subagent and host fallback (task 0508) — while `--agent auto`/a name, parallel mode, and headless invocation keep the isolated per-task workflow subprocess boundary. `--agent <inline|auto|name>` pins the executor for the per-task stages (see [SSOT](cross-cutting.md#inline-default-execution-surface)); the value crosses into per-task `vars.agent`, not the orchestrator. `--json` emits the report as JSON. `--wrap` triggers `wrapup-pipeline.yaml` after the batch completes, `--next` chains each task to terminal status then runs the wrap hop **once for the batch**, `--continue` resumes from checkpoint.
|
|
292
292
|
- **Three orthogonal axes (do not confuse):** `--keep-going` = batch failure policy (halt vs skip dependents); `--continue` = resume from checkpoint (pick up an interrupted batch); `--next` = per-task lifecycle chaining (advance status on a verdict — `dev-verify`/`dev-verifyall` only). `routing-table.md` offers `--continue` and `--next` as competing options for the same situation only when the batch was interrupted mid-run; otherwise they address different problems.
|
|
293
293
|
- **Backing:** `sp:spur-dev` skill, `runall` operation → delegates the driver loop to the **`sp:super-planner`** agent (the batch orchestrator).
|
|
294
294
|
- **Behavior:** The orchestrator reads [execution-batch.md](execution-batch.md) and drives: resolve selector → freeze set → topo-sort by `dependencies[]` (Kahn, WBS-ascending tie-break; cycle aborts) → resolve out-of-set deps by status (done → allow, else → block subtree) → run each task via `spur workflow run task-pipeline.yaml --async` + `spur workflow trace` polling → inspect terminal state + `.spur/run/<wbs>-verdict.json` → stop-the-batch default or `--keep-going` subtree skip → emit batch report. Per-task pipeline is invoked **verbatim** — no new FSM, no step edits. `--auto`/`--agent` are the only flags that cross the orchestrator→pipeline boundary (both into per-task `--vars`).
|
|
@@ -297,14 +297,14 @@ must not be changed without updating the backing skill.
|
|
|
297
297
|
### 14. wrap
|
|
298
298
|
|
|
299
299
|
- **Purpose:** Wrap up a single completed task — capture learnings, record metrics, sync docs, and optionally advance the feature / clean up the branch.
|
|
300
|
-
- **Inputs:** `<wbs>` (required, positional). `--auto` skips objective confirmations (the branch-cleanup HITL gate still pauses — irreversible). `--merge` triggers branch cleanup (irreversible HITL gate).
|
|
300
|
+
- **Inputs:** `<wbs>` (required, positional). `--agent <inline|auto|name>` names the wrap's model-bearing executor (default: `agent.default`); wrap is workflow-backed, so omit/`inline` resolves to `agent.default` under objective trigger 3 (durable auditable run record required), `auto` tier-resolves an executor, and a name pins that executor into `vars.agent` (see [SSOT](cross-cutting.md#inline-default-execution-surface)). `--auto` skips objective confirmations (the branch-cleanup HITL gate still pauses — irreversible). `--merge` triggers branch cleanup (irreversible HITL gate).
|
|
301
301
|
- **Backing:** `spur workflow run .spur/workflows/wrapup-pipeline.yaml` — direct workflow invocation (no backing skill; the pipeline IS the procedure).
|
|
302
|
-
- **Behavior:**
|
|
302
|
+
- **Behavior:** Resolves the executor (`agent.default` for omit/`inline`, tier-resolved for `auto`, unchanged for a name), emits a pre-dispatch notice naming the subprocess override — `execution surface: subprocess`, `reason: trigger 3 — durable auditable run record required`, `requested agent: <selector>`, `executor: <resolved>` — then builds `--vars '{"tasks":"[\"<wbs>\"]","agent":"<resolved>","profile":"interactive|auto","merge":"true|false"}'` and invokes the wrapup pipeline. The pipeline runs: task-resolve → doc-sync → learning-capture → metrics-record → (feature-transition) → (branch-cleanup) → done. Task statuses are NOT mutated. Branch cleanup is an irreversible HITL gate that always pauses, even under `--auto`.
|
|
303
303
|
- **Vars string typing:** `tasks` is a JSON-encoded **string**, not a JSON array — `spur workflow run --vars` accepts only string values (`--vars values must be strings`); the pipeline's guards parse the string with `jq length`. `jq -nc` guarantees the shape:
|
|
304
304
|
|
|
305
305
|
```bash
|
|
306
|
-
VARS=$(jq -nc --arg tasks "[\"$WBS\"]" --arg profile "$PROFILE" --arg merge "$MERGE" \
|
|
307
|
-
'{tasks:$tasks, profile:$profile, merge:$merge}')
|
|
306
|
+
VARS=$(jq -nc --arg tasks "[\"$WBS\"]" --arg agent "$AGENT" --arg profile "$PROFILE" --arg merge "$MERGE" \
|
|
307
|
+
'{tasks:$tasks, agent:$agent, profile:$profile, merge:$merge}')
|
|
308
308
|
spur workflow run .spur/workflows/wrapup-pipeline.yaml --vars "$VARS"
|
|
309
309
|
```
|
|
310
310
|
|
|
@@ -313,14 +313,14 @@ must not be changed without updating the backing skill.
|
|
|
313
313
|
### 15. wrapall
|
|
314
314
|
|
|
315
315
|
- **Purpose:** Wrap up a batch of completed tasks — capture learnings, record metrics, sync docs, advance a feature through legal lifecycle edges, and optionally clean up branches.
|
|
316
|
-
- **Inputs:** `--since <iso-date>` filters done tasks by frontmatter `updated_at >= date` (v1 approximation). `--feature <id>` selects all tasks under a feature AND advances the feature through legal lifecycle edges (`backlog → active → verifying → done`, guards honored). `--status <s>` (default: `done`) filters by task status. `--auto` skips objective confirmations. `--merge` triggers branch cleanup (irreversible HITL gate).
|
|
316
|
+
- **Inputs:** `--since <iso-date>` filters done tasks by frontmatter `updated_at >= date` (v1 approximation). `--feature <id>` selects all tasks under a feature AND advances the feature through legal lifecycle edges (`backlog → active → verifying → done`, guards honored). `--status <s>` (default: `done`) filters by task status. `--agent <inline|auto|name>` names the wrap's model-bearing executor (default: `agent.default`); wrap is workflow-backed, so omit/`inline` resolves to `agent.default` under objective trigger 3 (durable auditable run record required), `auto` tier-resolves an executor, and a name pins that executor into `vars.agent` (see [SSOT](cross-cutting.md#inline-default-execution-surface)). `--auto` skips objective confirmations. `--merge` triggers branch cleanup (irreversible HITL gate).
|
|
317
317
|
- **Backing:** `spur workflow run .spur/workflows/wrapup-pipeline.yaml` — direct workflow invocation.
|
|
318
|
-
- **Behavior:** Resolves the task list via `spur task list --json` (filtered by `--feature`, `--since`, `--status`), builds `--vars '{"tasks":"[...]","feature":"<id>","profile":"interactive|auto","merge":"true|false"}'
|
|
318
|
+
- **Behavior:** Resolves the task list via `spur task list --json` (filtered by `--feature`, `--since`, `--status`), resolves the executor (`agent.default` for omit/`inline`, tier-resolved for `auto`, unchanged for a name), emits a pre-dispatch notice naming the subprocess override — `execution surface: subprocess`, `reason: trigger 3 — durable auditable run record required`, `requested agent: <selector>`, `executor: <resolved>` — then builds `--vars '{"tasks":"[...]","feature":"<id>","agent":"<resolved>","profile":"interactive|auto","merge":"true|false"}'` and invokes the wrapup pipeline. The pipeline runs the same states as `wrap` but with the full task list and optional feature transition. Task statuses are NOT mutated. Feature transitions go through `spur feature update` so lifecycle guards apply. Branch cleanup is an irreversible HITL gate.
|
|
319
319
|
- **Vars string typing:** `tasks` is a JSON-encoded **string**, not a JSON array — `--vars` values must be strings (the CLI rejects raw arrays); `jq -nc` passes the array text through as a string value:
|
|
320
320
|
|
|
321
321
|
```bash
|
|
322
|
-
VARS=$(jq -nc --arg tasks "$TASKS" --arg feature "$FEATURE" --arg profile "$PROFILE" --arg merge "$MERGE" \
|
|
323
|
-
'{tasks:$tasks, feature:$feature, profile:$profile, merge:$merge}')
|
|
322
|
+
VARS=$(jq -nc --arg tasks "$TASKS" --arg feature "$FEATURE" --arg agent "$AGENT" --arg profile "$PROFILE" --arg merge "$MERGE" \
|
|
323
|
+
'{tasks:$tasks, feature:$feature, agent:$agent, profile:$profile, merge:$merge}')
|
|
324
324
|
spur workflow run .spur/workflows/wrapup-pipeline.yaml --vars "$VARS"
|
|
325
325
|
```
|
|
326
326
|
|