@gobing-ai/spur 0.2.5 → 0.2.8
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/package.json +8 -11
- package/schemas/section-matrix.schema.json +68 -0
- package/schemas/spur-config.schema.json +71 -1
- package/schemas/state-machine-workflow.schema.json +4 -0
- package/schemas/task-batch.schema.json +53 -0
- package/spur-cli/config/config.example.yaml +25 -1
- package/spur-cli/config/rules/boundary/config-loading-ownership.yaml +54 -0
- package/spur-cli/config/rules/boundary/planning-folder-hardcode.yaml +46 -0
- package/spur-cli/config/rules/recommended-pre-check.yaml +3 -2
- package/spur-cli/config/rules/structure/test-location.yaml +9 -0
- package/spur-cli/config/rules/typescript/happy-dom-teardown.yaml +43 -0
- package/spur-cli/config/rules/typescript/no-leaky-module-mocks.yaml +71 -0
- package/spur-cli/config/rules/ui/ui-import-boundary.yaml +51 -0
- package/spur-cli/config/tasks/section-matrix.yaml +188 -0
- package/spur-cli/config/tasks/templates/brainstorm.md +29 -0
- package/spur-cli/config/tasks/templates/feature-impl.md +50 -0
- package/spur-cli/config/tasks/templates/issue.md +33 -0
- package/spur-cli/config/tasks/templates/meta.md +31 -0
- package/spur-cli/config/tasks/templates/review.md +48 -0
- package/spur-cli/config/tasks/templates/standard.md +48 -0
- package/spur-cli/config/templates/bdd/checklist.md +1 -0
- package/spur-cli/config/templates/bdd/gherkin.md +8 -0
- package/spur-cli/config/templates/docs/00_ADR.md +27 -0
- package/spur-cli/config/templates/docs/01_PRD.md +37 -0
- package/spur-cli/config/templates/docs/02_ROADMAP.md +22 -0
- package/spur-cli/config/templates/docs/03_ARCHITECTURE.md +27 -0
- package/spur-cli/config/templates/docs/04_DESIGN.md +30 -0
- package/spur-cli/config/templates/docs/05_FEATURES.md +23 -0
- package/spur-cli/config/templates/docs/99_PROJECT_CONSTITUTION.md +65 -0
- package/spur-cli/config/templates/feature/default.md +41 -0
- package/spur-cli/config/templates/task/brainstorm.md +29 -0
- package/spur-cli/config/templates/task/feature-impl.md +50 -0
- package/spur-cli/config/templates/task/issue.md +33 -0
- package/spur-cli/config/templates/task/meta.md +31 -0
- package/spur-cli/config/templates/task/review.md +52 -0
- package/spur-cli/config/templates/task/standard.md +48 -0
- package/spur-cli/config/workflows/feature-dev.yaml +88 -80
- package/spur-cli/config/workflows/feature-lifecycle.yaml +100 -0
- package/spur-cli/config/workflows/planning-pipeline.yaml +166 -0
- package/spur-cli/config/workflows/task-lifecycle.yaml +128 -0
- package/spur-cli/config/workflows/task-pipeline.yaml +238 -0
- package/spur.js +69295 -52352
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 1
|
|
3
|
+
id: "{{ ID }}"
|
|
4
|
+
name: "{{ NAME }}"
|
|
5
|
+
status: backlog
|
|
6
|
+
priority: P2
|
|
7
|
+
tags: []
|
|
8
|
+
created_at: "{{ CREATED_AT }}"
|
|
9
|
+
updated_at: "{{ CREATED_AT }}"
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# {{ ID }}: {{ NAME }}
|
|
13
|
+
|
|
14
|
+
## Goal
|
|
15
|
+
|
|
16
|
+
{{ GOAL }}
|
|
17
|
+
|
|
18
|
+
## Scope
|
|
19
|
+
|
|
20
|
+
- In:
|
|
21
|
+
- Out:
|
|
22
|
+
|
|
23
|
+
## Acceptance Criteria
|
|
24
|
+
|
|
25
|
+
```gherkin
|
|
26
|
+
Feature: {{ NAME }}
|
|
27
|
+
|
|
28
|
+
Scenario: Basic acceptance
|
|
29
|
+
Given some precondition
|
|
30
|
+
When some action
|
|
31
|
+
Then some expected outcome
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Tasks
|
|
35
|
+
|
|
36
|
+
<!-- AUTO-GENERATED by spur feature refresh -->
|
|
37
|
+
<!-- END AUTO-GENERATED -->
|
|
38
|
+
|
|
39
|
+
## Notes
|
|
40
|
+
|
|
41
|
+
## History
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 1
|
|
3
|
+
name: "{{ NAME }}"
|
|
4
|
+
description: ""
|
|
5
|
+
status: backlog
|
|
6
|
+
type: brainstorm
|
|
7
|
+
profile: standard
|
|
8
|
+
feature_id: null
|
|
9
|
+
parent_wbs: null
|
|
10
|
+
priority: P2
|
|
11
|
+
tags: []
|
|
12
|
+
dependencies: []
|
|
13
|
+
created_at: "{{ CREATED_AT }}"
|
|
14
|
+
updated_at: "{{ CREATED_AT }}"
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## {{ WBS }}. {{ NAME }}
|
|
18
|
+
|
|
19
|
+
### Background
|
|
20
|
+
|
|
21
|
+
{{ BACKGROUND }}
|
|
22
|
+
|
|
23
|
+
### Q&A
|
|
24
|
+
|
|
25
|
+
### Plan
|
|
26
|
+
|
|
27
|
+
### References
|
|
28
|
+
|
|
29
|
+
### History
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 1
|
|
3
|
+
name: "{{ NAME }}"
|
|
4
|
+
description: ""
|
|
5
|
+
status: backlog
|
|
6
|
+
type: task
|
|
7
|
+
profile: standard
|
|
8
|
+
feature_id: null
|
|
9
|
+
parent_wbs: null
|
|
10
|
+
priority: P2
|
|
11
|
+
tags: []
|
|
12
|
+
dependencies: []
|
|
13
|
+
created_at: "{{ CREATED_AT }}"
|
|
14
|
+
updated_at: "{{ CREATED_AT }}"
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## {{ WBS }}. {{ NAME }}
|
|
18
|
+
|
|
19
|
+
### Background
|
|
20
|
+
|
|
21
|
+
{{ BACKGROUND }}
|
|
22
|
+
|
|
23
|
+
### Acceptance Criteria
|
|
24
|
+
|
|
25
|
+
```gherkin
|
|
26
|
+
Feature: {{ NAME }}
|
|
27
|
+
|
|
28
|
+
Scenario: Basic acceptance
|
|
29
|
+
Given a precondition
|
|
30
|
+
When an action is taken
|
|
31
|
+
Then an expected result occurs
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
- [ ] Acceptance checklist item
|
|
35
|
+
|
|
36
|
+
### Design
|
|
37
|
+
|
|
38
|
+
### Plan
|
|
39
|
+
|
|
40
|
+
- [ ] Implementation step
|
|
41
|
+
|
|
42
|
+
### Solution
|
|
43
|
+
|
|
44
|
+
### Testing
|
|
45
|
+
|
|
46
|
+
### Review
|
|
47
|
+
|
|
48
|
+
### References
|
|
49
|
+
|
|
50
|
+
### History
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 1
|
|
3
|
+
name: "{{ NAME }}"
|
|
4
|
+
description: ""
|
|
5
|
+
status: backlog
|
|
6
|
+
type: issue
|
|
7
|
+
profile: standard
|
|
8
|
+
feature_id: null
|
|
9
|
+
parent_wbs: null
|
|
10
|
+
priority: P2
|
|
11
|
+
tags: ["bug"]
|
|
12
|
+
dependencies: []
|
|
13
|
+
created_at: "{{ CREATED_AT }}"
|
|
14
|
+
updated_at: "{{ CREATED_AT }}"
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## {{ WBS }}. {{ NAME }}
|
|
18
|
+
|
|
19
|
+
### Background
|
|
20
|
+
|
|
21
|
+
{{ BACKGROUND }}
|
|
22
|
+
|
|
23
|
+
### Root Cause
|
|
24
|
+
|
|
25
|
+
### Solution
|
|
26
|
+
|
|
27
|
+
### Testing
|
|
28
|
+
|
|
29
|
+
### Review
|
|
30
|
+
|
|
31
|
+
### References
|
|
32
|
+
|
|
33
|
+
### History
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 1
|
|
3
|
+
name: "{{ NAME }}"
|
|
4
|
+
description: ""
|
|
5
|
+
status: backlog
|
|
6
|
+
type: meta
|
|
7
|
+
profile: standard
|
|
8
|
+
feature_id: null
|
|
9
|
+
parent_wbs: null
|
|
10
|
+
priority: P2
|
|
11
|
+
tags: ["meta"]
|
|
12
|
+
dependencies: []
|
|
13
|
+
created_at: "{{ CREATED_AT }}"
|
|
14
|
+
updated_at: "{{ CREATED_AT }}"
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## {{ WBS }}. {{ NAME }}
|
|
18
|
+
|
|
19
|
+
### Background
|
|
20
|
+
|
|
21
|
+
{{ BACKGROUND }}
|
|
22
|
+
|
|
23
|
+
### Plan
|
|
24
|
+
|
|
25
|
+
- [ ] Implementation step
|
|
26
|
+
|
|
27
|
+
### Testing
|
|
28
|
+
|
|
29
|
+
### References
|
|
30
|
+
|
|
31
|
+
### History
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 1
|
|
3
|
+
name: "{{ NAME }}"
|
|
4
|
+
description: ""
|
|
5
|
+
status: backlog
|
|
6
|
+
type: review
|
|
7
|
+
template: review
|
|
8
|
+
profile: standard
|
|
9
|
+
feature_id: null
|
|
10
|
+
parent_wbs: null
|
|
11
|
+
priority: P2
|
|
12
|
+
tags: ["review"]
|
|
13
|
+
dependencies: []
|
|
14
|
+
created_at: "{{ CREATED_AT }}"
|
|
15
|
+
updated_at: "{{ CREATED_AT }}"
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## {{ WBS }}. {{ NAME }}
|
|
19
|
+
|
|
20
|
+
### Background
|
|
21
|
+
|
|
22
|
+
{{ BACKGROUND }}
|
|
23
|
+
|
|
24
|
+
#### Review Findings
|
|
25
|
+
|
|
26
|
+
The code-review findings this task must address — logged here as **input** (what was found
|
|
27
|
+
in the reviewed PR/commit/diff). Fix in priority order (P1 → P2 → …); re-review after.
|
|
28
|
+
|
|
29
|
+
| Severity | File | Finding | Recommendation |
|
|
30
|
+
| -------- | ---- | ------- | -------------- |
|
|
31
|
+
| P1 | | | |
|
|
32
|
+
| P2 | | | |
|
|
33
|
+
|
|
34
|
+
### Plan
|
|
35
|
+
|
|
36
|
+
- [ ] Fix P1 findings
|
|
37
|
+
- [ ] Fix P2 findings
|
|
38
|
+
- [ ] Re-review the changed code
|
|
39
|
+
|
|
40
|
+
### Review
|
|
41
|
+
|
|
42
|
+
Post-implementation reflection — filled **after** the first fix round: what went wrong, what
|
|
43
|
+
remains to fix before closing, and any **back-issues** (new findings surfaced by the fix).
|
|
44
|
+
|
|
45
|
+
| Severity | File | Finding | Recommendation |
|
|
46
|
+
| -------- | ---- | ------- | -------------- |
|
|
47
|
+
| P1 | | | |
|
|
48
|
+
| P2 | | | |
|
|
49
|
+
|
|
50
|
+
### References
|
|
51
|
+
|
|
52
|
+
### History
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 1
|
|
3
|
+
name: "{{ NAME }}"
|
|
4
|
+
description: ""
|
|
5
|
+
status: backlog
|
|
6
|
+
type: task
|
|
7
|
+
profile: standard
|
|
8
|
+
feature_id: null
|
|
9
|
+
parent_wbs: null
|
|
10
|
+
priority: P2
|
|
11
|
+
tags: []
|
|
12
|
+
dependencies: []
|
|
13
|
+
created_at: "{{ CREATED_AT }}"
|
|
14
|
+
updated_at: "{{ CREATED_AT }}"
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## {{ WBS }}. {{ NAME }}
|
|
18
|
+
|
|
19
|
+
### Background
|
|
20
|
+
|
|
21
|
+
{{ BACKGROUND }}
|
|
22
|
+
|
|
23
|
+
### Acceptance Criteria
|
|
24
|
+
|
|
25
|
+
```gherkin
|
|
26
|
+
Feature: {{ NAME }}
|
|
27
|
+
|
|
28
|
+
Scenario: Basic acceptance
|
|
29
|
+
Given a precondition
|
|
30
|
+
When an action is taken
|
|
31
|
+
Then an expected result occurs
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
- [ ] Acceptance checklist item
|
|
35
|
+
|
|
36
|
+
### Plan
|
|
37
|
+
|
|
38
|
+
- [ ] Implementation step
|
|
39
|
+
|
|
40
|
+
### Solution
|
|
41
|
+
|
|
42
|
+
### Testing
|
|
43
|
+
|
|
44
|
+
### Review
|
|
45
|
+
|
|
46
|
+
### References
|
|
47
|
+
|
|
48
|
+
### History
|
|
@@ -1,117 +1,125 @@
|
|
|
1
1
|
$schema: "@gobing-ai/spur/schemas/state-machine-workflow.schema.json"
|
|
2
|
-
"$schema": "@gobing-ai/
|
|
2
|
+
"$schema": "@gobing-ai/spur/schemas/state-machine-workflow.schema.json"
|
|
3
3
|
kind: state-machine
|
|
4
4
|
name: feature-dev
|
|
5
5
|
description: >
|
|
6
|
-
End-to-end
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
End-to-end FEATURE development loop: brainstorm → plan (decompose) → execute-tasks →
|
|
7
|
+
feature-verify → done. Drives a whole feature (one description → a feature with BDD AC →
|
|
8
|
+
many tasks → all tasks done → feature verified), NOT a single task — for one deliverable
|
|
9
|
+
use task-pipeline.yaml directly.
|
|
10
|
+
|
|
11
|
+
The engine has no native for-each over a dynamic task list, so the execute-tasks step
|
|
12
|
+
DELEGATES the fan-out: a single agent.run instructs the agent to run every pending task
|
|
13
|
+
under the feature through task-pipeline.yaml, enumerated via `spur task list --feature`.
|
|
14
|
+
This mirrors how /sp:dev-run --mode full delegates its inner work loop (ADR-022: orchestration
|
|
15
|
+
is configuration — zero new engine code).
|
|
16
|
+
|
|
17
|
+
Shape: brainstorm → plan → execute-tasks(delegated loop) → feature-verify → done
|
|
18
|
+
(plan failure or a non-PASS task short-circuits to `failed`).
|
|
19
|
+
|
|
20
|
+
Vars (passed as a JSON object via `--vars`):
|
|
21
|
+
featureId — the feature ID this loop drives (required), e.g. `--vars '{"featureId":"B3"}'`
|
|
22
|
+
agent — agent the agent.run steps invoke; override `--vars '{"agent":"claude"}'`
|
|
23
|
+
profile — `auto` skips the per-task HITL approval inside task-pipeline
|
|
24
|
+
spurBin — PATH-independent spur invocation (CLI overrides at run start; literal fallback)
|
|
25
|
+
|
|
26
|
+
Seeded by `spur init`; adapt the agent.run inputs to your project's command set.
|
|
11
27
|
iterationBound: 20
|
|
12
28
|
initialState: brainstorm
|
|
13
29
|
terminalStates:
|
|
14
30
|
- done
|
|
15
31
|
- failed
|
|
16
32
|
vars:
|
|
17
|
-
|
|
33
|
+
featureId: ""
|
|
34
|
+
agent: "omp"
|
|
35
|
+
profile: "standard"
|
|
36
|
+
spurBin: "spur"
|
|
18
37
|
|
|
19
38
|
states:
|
|
20
39
|
- id: brainstorm
|
|
21
|
-
description: Turn vague intent into a structured feature list via /rd3:dev-brainstorm
|
|
22
|
-
onEnter:
|
|
23
|
-
- kind: agent.run
|
|
24
|
-
options:
|
|
25
|
-
input: /rd3:dev-brainstorm
|
|
26
|
-
|
|
27
|
-
- id: new-task
|
|
28
|
-
description: Convert the feature list into a task file via /rd3:dev-new-task
|
|
29
|
-
onEnter:
|
|
30
|
-
- kind: agent.run
|
|
31
|
-
options:
|
|
32
|
-
input: /rd3:dev-new-task
|
|
33
|
-
|
|
34
|
-
- id: refine
|
|
35
|
-
description: Auto-refine the task definition via /rd3:dev-refine
|
|
36
|
-
onEnter:
|
|
37
|
-
- kind: agent.run
|
|
38
|
-
options:
|
|
39
|
-
input: /rd3:dev-refine ${vars.taskId} --focus all --auto
|
|
40
|
-
|
|
41
|
-
- id: implement
|
|
42
|
-
description: Implement + verify the task via /rd3:dev-run
|
|
43
|
-
onEnter:
|
|
44
|
-
- kind: agent.run
|
|
45
|
-
options:
|
|
46
|
-
input: /rd3:dev-run ${vars.taskId} --auto --verify
|
|
47
|
-
|
|
48
|
-
- id: check
|
|
49
40
|
description: >
|
|
50
|
-
|
|
51
|
-
|
|
41
|
+
Turn vague intent into a validated feature with BDD acceptance criteria via
|
|
42
|
+
/sp:dev-brainstorm --feature. The grilling interview maps the decision space; the
|
|
43
|
+
--feature exit authors AC and loops `spur feature check` until clean. Record the
|
|
44
|
+
derived feature ID into ${vars.featureId} for the downstream steps.
|
|
52
45
|
onEnter:
|
|
53
|
-
- kind:
|
|
46
|
+
- kind: agent.run
|
|
54
47
|
options:
|
|
55
|
-
|
|
56
|
-
|
|
48
|
+
agent: ${vars.agent}
|
|
49
|
+
input: /sp:dev-brainstorm --feature
|
|
57
50
|
|
|
58
|
-
- id:
|
|
51
|
+
- id: plan
|
|
59
52
|
description: >
|
|
60
|
-
|
|
61
|
-
|
|
53
|
+
Decompose the validated feature into a CLI-validated task batch via /sp:dev-plan.
|
|
54
|
+
The batch-create gate (task-batch.schema.json) rejects a malformed decomposition,
|
|
55
|
+
so a bad plan never lands tasks.
|
|
62
56
|
onEnter:
|
|
63
57
|
- kind: agent.run
|
|
64
58
|
options:
|
|
65
|
-
|
|
59
|
+
agent: ${vars.agent}
|
|
60
|
+
input: /sp:dev-plan --feature ${vars.featureId}
|
|
66
61
|
|
|
67
|
-
- id:
|
|
68
|
-
description:
|
|
62
|
+
- id: execute-tasks
|
|
63
|
+
description: >
|
|
64
|
+
Drive EVERY pending task under the feature to done. The agent enumerates the work with
|
|
65
|
+
`spur task list --feature ${featureId} --status todo --json`, then runs each task through
|
|
66
|
+
task-pipeline.yaml (refine → implement → test → review → verify → record → done). It
|
|
67
|
+
stops and reports on the first non-PASS verdict — a failing task fails the feature.
|
|
69
68
|
onEnter:
|
|
70
69
|
- kind: agent.run
|
|
71
70
|
options:
|
|
72
|
-
|
|
71
|
+
agent: ${vars.agent}
|
|
72
|
+
input: >
|
|
73
|
+
Run every pending task under feature ${vars.featureId} to done. Enumerate with
|
|
74
|
+
`${vars.spurBin} task list --feature ${vars.featureId} --status todo --json`, then
|
|
75
|
+
for each task run the task-pipeline (e.g. /sp:dev-refine <wbs> --auto --next, which
|
|
76
|
+
chains implement → verify → done). Stop and report on the first non-PASS verdict.
|
|
77
|
+
|
|
78
|
+
- id: feature-verify
|
|
79
|
+
description: >
|
|
80
|
+
Certify the feature is complete: `spur feature check ${featureId} --strict` validates the
|
|
81
|
+
AC, traceability, and that all linked tasks are done. A clean strict check is the only
|
|
82
|
+
proof the feature is shippable.
|
|
73
83
|
|
|
74
84
|
- id: done
|
|
75
|
-
description: Terminal — feature
|
|
85
|
+
description: Terminal — feature planned, all tasks executed, and the feature verified.
|
|
76
86
|
|
|
77
87
|
- id: failed
|
|
78
|
-
description: Terminal —
|
|
88
|
+
description: Terminal — plan rejected, a task failed verification, or the feature check did not pass.
|
|
79
89
|
|
|
80
90
|
transitions:
|
|
81
|
-
# Linear prefix: brainstorm →
|
|
91
|
+
# Linear prefix: brainstorm → plan → execute-tasks
|
|
82
92
|
- from: brainstorm
|
|
83
|
-
to:
|
|
84
|
-
description: Feature
|
|
85
|
-
|
|
86
|
-
- from: new-task
|
|
87
|
-
to: refine
|
|
88
|
-
description: Task file created; refine it
|
|
89
|
-
|
|
90
|
-
- from: refine
|
|
91
|
-
to: implement
|
|
92
|
-
description: Task refined; implement it
|
|
93
|
-
|
|
94
|
-
- from: implement
|
|
95
|
-
to: check
|
|
96
|
-
description: Implementation done; run the gate
|
|
97
|
-
|
|
98
|
-
# Check gate: action-ok guard FIRST so a passing check short-circuits to verify.
|
|
99
|
-
- from: check
|
|
100
|
-
to: verify
|
|
101
|
-
description: Check passed — advance to cross-agent verification
|
|
93
|
+
to: plan
|
|
94
|
+
description: Feature validated; decompose it into tasks
|
|
102
95
|
guard:
|
|
103
|
-
kind:
|
|
96
|
+
kind: always
|
|
104
97
|
|
|
105
|
-
- from:
|
|
106
|
-
to:
|
|
107
|
-
description:
|
|
98
|
+
- from: plan
|
|
99
|
+
to: execute-tasks
|
|
100
|
+
description: Tasks created; execute them
|
|
101
|
+
guard:
|
|
102
|
+
kind: always
|
|
108
103
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
104
|
+
- from: execute-tasks
|
|
105
|
+
to: feature-verify
|
|
106
|
+
description: All tasks reported done; verify the feature
|
|
107
|
+
guard:
|
|
108
|
+
kind: always
|
|
113
109
|
|
|
114
|
-
#
|
|
115
|
-
|
|
110
|
+
# ── feature-verify gate: strict check certifies done, else fail ──
|
|
111
|
+
# Declaration order: the pass guard is tried FIRST.
|
|
112
|
+
- from: feature-verify
|
|
116
113
|
to: done
|
|
117
|
-
description:
|
|
114
|
+
description: Strict feature check passed — the feature is complete.
|
|
115
|
+
guard:
|
|
116
|
+
kind: shell
|
|
117
|
+
options:
|
|
118
|
+
command: "${vars.spurBin} feature check ${vars.featureId} --strict"
|
|
119
|
+
- from: feature-verify
|
|
120
|
+
to: failed
|
|
121
|
+
description: Strict feature check failed — block before done; investigate incomplete tasks or AC.
|
|
122
|
+
guard:
|
|
123
|
+
kind: shell
|
|
124
|
+
options:
|
|
125
|
+
command: '! ${vars.spurBin} feature check ${vars.featureId} --strict'
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
$schema: "@gobing-ai/spur/schemas/state-machine-workflow.schema.json"
|
|
2
|
+
"$schema": "@gobing-ai/spur/schemas/state-machine-workflow.schema.json"
|
|
3
|
+
kind: state-machine
|
|
4
|
+
name: feature-lifecycle
|
|
5
|
+
description: >
|
|
6
|
+
Feature lifecycle FSM (design §2.3, §5.1, DD-13). States are the canonical
|
|
7
|
+
FeatureStatus vocabulary; transitions encode the §2.3 graph including the
|
|
8
|
+
`verifying` status (DD-13). Guards invoke `${vars.spurBin} feature check`
|
|
9
|
+
at the active→verifying and verifying→done placements. `cancelled` is terminal.
|
|
10
|
+
Guard commands reference the check verb (0057) — structural validation passes
|
|
11
|
+
today, behavioral wiring activates as the verb ships. Unconditional transitions
|
|
12
|
+
use the `always` guard (externally-driven via `requestTransition`, not
|
|
13
|
+
auto-advance).
|
|
14
|
+
initialState: backlog
|
|
15
|
+
terminalStates:
|
|
16
|
+
- cancelled
|
|
17
|
+
vars:
|
|
18
|
+
spurBin: 'spur'
|
|
19
|
+
featureId: X
|
|
20
|
+
|
|
21
|
+
states:
|
|
22
|
+
- id: backlog
|
|
23
|
+
description: Initial state — feature exists but not yet started.
|
|
24
|
+
- id: active
|
|
25
|
+
description: Actively being worked on. P0 in active/verifying is the project goal (B09).
|
|
26
|
+
- id: verifying
|
|
27
|
+
description: >
|
|
28
|
+
Feature verification work (DD-13). Makes verification derivable —
|
|
29
|
+
listable, event-triggerable, assignable.
|
|
30
|
+
- id: blocked
|
|
31
|
+
description: Impediment; work suspended.
|
|
32
|
+
- id: done
|
|
33
|
+
description: Completed and verified.
|
|
34
|
+
- id: cancelled
|
|
35
|
+
description: Terminal — abandoned.
|
|
36
|
+
|
|
37
|
+
transitions:
|
|
38
|
+
# Forward path: backlog → active → verifying → done
|
|
39
|
+
- from: backlog
|
|
40
|
+
to: active
|
|
41
|
+
description: Start feature work
|
|
42
|
+
guard:
|
|
43
|
+
kind: always
|
|
44
|
+
- from: active
|
|
45
|
+
to: verifying
|
|
46
|
+
description: >
|
|
47
|
+
Enter feature verification. Warns unless all linked tasks are done/cancelled.
|
|
48
|
+
guard:
|
|
49
|
+
kind: shell
|
|
50
|
+
options:
|
|
51
|
+
command: '${vars.spurBin} feature check ${vars.featureId}'
|
|
52
|
+
- from: verifying
|
|
53
|
+
to: done
|
|
54
|
+
description: >
|
|
55
|
+
Feature verified — complete. Runs strict check (AC validated, traceability clean).
|
|
56
|
+
guard:
|
|
57
|
+
kind: shell
|
|
58
|
+
options:
|
|
59
|
+
command: '${vars.spurBin} feature check ${vars.featureId} --strict'
|
|
60
|
+
|
|
61
|
+
# Rework: verifying → active (mandatory History entry)
|
|
62
|
+
- from: verifying
|
|
63
|
+
to: active
|
|
64
|
+
description: Rework — feature sent back to active (mandatory History entry)
|
|
65
|
+
guard:
|
|
66
|
+
kind: always
|
|
67
|
+
|
|
68
|
+
# Blocked ↔ active — bidirectional
|
|
69
|
+
- from: active
|
|
70
|
+
to: blocked
|
|
71
|
+
description: Blocked by an impediment
|
|
72
|
+
guard:
|
|
73
|
+
kind: always
|
|
74
|
+
- from: blocked
|
|
75
|
+
to: active
|
|
76
|
+
description: Impediment resolved
|
|
77
|
+
guard:
|
|
78
|
+
kind: always
|
|
79
|
+
|
|
80
|
+
# Cancel: any non-terminal → cancelled (terminal)
|
|
81
|
+
- from: backlog
|
|
82
|
+
to: cancelled
|
|
83
|
+
description: Cancel feature
|
|
84
|
+
guard:
|
|
85
|
+
kind: always
|
|
86
|
+
- from: active
|
|
87
|
+
to: cancelled
|
|
88
|
+
description: Cancel feature
|
|
89
|
+
guard:
|
|
90
|
+
kind: always
|
|
91
|
+
- from: verifying
|
|
92
|
+
to: cancelled
|
|
93
|
+
description: Cancel feature
|
|
94
|
+
guard:
|
|
95
|
+
kind: always
|
|
96
|
+
- from: blocked
|
|
97
|
+
to: cancelled
|
|
98
|
+
description: Cancel feature
|
|
99
|
+
guard:
|
|
100
|
+
kind: always
|