specdacular 0.8.1 → 0.9.2
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/README.md +166 -54
- package/commands/specd/continue.md +22 -14
- package/commands/specd/toolbox.md +58 -14
- package/package.json +1 -1
- package/specdacular/HELP.md +70 -9
- package/specdacular/STATE-MACHINE.md +376 -0
- package/specdacular/pipeline.json +76 -0
- package/specdacular/references/brain-routing.md +168 -0
- package/specdacular/references/commit-code.md +9 -6
- package/specdacular/references/commit-docs.md +9 -6
- package/specdacular/references/execute-hooks.md +127 -0
- package/specdacular/references/resolve-pipeline.md +74 -0
- package/specdacular/templates/context/review-diff.md +60 -0
- package/specdacular/templates/context/section-display.md +51 -0
- package/specdacular/workflows/brain.md +378 -0
- package/specdacular/workflows/context-add.md +242 -0
- package/specdacular/workflows/context-manual-review.md +410 -0
- package/specdacular/workflows/continue.md +17 -259
- package/specdacular/workflows/execute.md +15 -42
- package/specdacular/workflows/map-codebase.md +14 -0
- package/specdacular/workflows/phase-plan.md +142 -0
- package/specdacular/workflows/plan.md +10 -37
- package/specdacular/workflows/research.md +25 -7
- package/specdacular/workflows/review.md +11 -136
- package/specdacular/workflows/revise.md +126 -0
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
# Specdacular State Machine Reference
|
|
2
|
+
|
|
3
|
+
How the brain orchestrates tasks, how state transitions work, and what custom workflows need to do.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## How the Brain Works
|
|
8
|
+
|
|
9
|
+
The brain is a loop: read state → route → dispatch → update state → repeat.
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
┌─────────────────────────────────────────────────┐
|
|
13
|
+
│ BRAIN LOOP │
|
|
14
|
+
│ │
|
|
15
|
+
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
|
16
|
+
│ │ Read │───▶│ Route │───▶│ Dispatch │ │
|
|
17
|
+
│ │ State │ │ (pick │ │ Step │ │
|
|
18
|
+
│ │ │ │ next) │ │ │ │
|
|
19
|
+
│ └──────────┘ └──────────┘ └────┬─────┘ │
|
|
20
|
+
│ ▲ │ │
|
|
21
|
+
│ │ ┌──────────┐ │ │
|
|
22
|
+
│ └──────────│ Update │◀────────┘ │
|
|
23
|
+
│ │ State │ │
|
|
24
|
+
│ └──────────┘ │
|
|
25
|
+
└─────────────────────────────────────────────────┘
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
**Each iteration:**
|
|
29
|
+
1. Read `config.json`, `STATE.md`, `CONTEXT.md`
|
|
30
|
+
2. Use the routing table (below) to pick the next step
|
|
31
|
+
3. Run pre-hooks → step workflow → post-hooks
|
|
32
|
+
4. Update state based on what the step did
|
|
33
|
+
5. Loop back to step 1
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## State: config.json
|
|
38
|
+
|
|
39
|
+
The brain reads two key fields from config.json to decide where you are:
|
|
40
|
+
|
|
41
|
+
```json
|
|
42
|
+
{
|
|
43
|
+
"stage": "discussion | research | planning | execution | complete",
|
|
44
|
+
"phases": {
|
|
45
|
+
"current": 1,
|
|
46
|
+
"current_status": "pending | executing | executed | completed",
|
|
47
|
+
"total": 3,
|
|
48
|
+
"completed": 0,
|
|
49
|
+
"phase_start_commit": null
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
| Field | What it means |
|
|
55
|
+
|-------|---------------|
|
|
56
|
+
| `stage` | Which part of the lifecycle you're in |
|
|
57
|
+
| `phases.current` | Which phase number is active (1-indexed) |
|
|
58
|
+
| `phases.current_status` | Where that phase is in its sub-lifecycle |
|
|
59
|
+
| `phases.total` | How many phases were planned |
|
|
60
|
+
| `phases.completed` | How many phases are fully done |
|
|
61
|
+
|
|
62
|
+
The brain also checks `CONTEXT.md` for gray area count (unchecked items in "Gray Areas Remaining").
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Routing Table
|
|
67
|
+
|
|
68
|
+
This is the complete decision table. The brain evaluates top-to-bottom and takes the first match:
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
72
|
+
│ ROUTING TABLE │
|
|
73
|
+
├────────────────────────────┬──────────────┬────────────────────┤
|
|
74
|
+
│ State │ Next Step │ Pipeline │
|
|
75
|
+
├────────────────────────────┼──────────────┼────────────────────┤
|
|
76
|
+
│ stage=discussion │ │ │
|
|
77
|
+
│ gray areas > 0 │ discuss │ main │
|
|
78
|
+
│ gray areas = 0 │ research │ main │
|
|
79
|
+
├────────────────────────────┼──────────────┼────────────────────┤
|
|
80
|
+
│ stage=research │ │ │
|
|
81
|
+
│ no RESEARCH.md │ research │ main │
|
|
82
|
+
│ RESEARCH.md exists │ plan │ main │
|
|
83
|
+
├────────────────────────────┼──────────────┼────────────────────┤
|
|
84
|
+
│ stage=planning │ │ │
|
|
85
|
+
│ no ROADMAP.md │ plan │ main │
|
|
86
|
+
│ ROADMAP.md exists │ plan │ phase-execution │
|
|
87
|
+
├────────────────────────────┼──────────────┼────────────────────┤
|
|
88
|
+
│ stage=execution │ │ │
|
|
89
|
+
│ current_status=pending │ │ │
|
|
90
|
+
│ no PLAN.md │ plan │ phase-execution │
|
|
91
|
+
│ PLAN.md exists │ execute │ phase-execution │
|
|
92
|
+
│ current_status=executing │ execute │ phase-execution │
|
|
93
|
+
│ current_status=executed │ review │ phase-execution │
|
|
94
|
+
│ current_status=completed │ next phase │ phase-execution │
|
|
95
|
+
│ │ or COMPLETE │ │
|
|
96
|
+
└────────────────────────────┴──────────────┴────────────────────┘
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Full Lifecycle Diagram
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
┌─────────┐
|
|
105
|
+
│ START │
|
|
106
|
+
└────┬────┘
|
|
107
|
+
│
|
|
108
|
+
▼
|
|
109
|
+
┌─────────────────────┐
|
|
110
|
+
│ DISCUSSION │
|
|
111
|
+
│ │ gray areas > 0
|
|
112
|
+
│ ┌───────────────┐ │◀─────────────────┐
|
|
113
|
+
│ │ discuss │──┼──────────────────┘
|
|
114
|
+
│ └───────────────┘ │
|
|
115
|
+
│ │ gray areas = 0
|
|
116
|
+
└──────────┬──────────┘
|
|
117
|
+
│
|
|
118
|
+
▼
|
|
119
|
+
┌─────────────────────┐
|
|
120
|
+
│ RESEARCH │
|
|
121
|
+
│ │
|
|
122
|
+
│ ┌───────────────┐ │
|
|
123
|
+
│ │ research │ │
|
|
124
|
+
│ └───────────────┘ │
|
|
125
|
+
└──────────┬──────────┘
|
|
126
|
+
│
|
|
127
|
+
▼
|
|
128
|
+
┌─────────────────────┐
|
|
129
|
+
│ PLANNING │
|
|
130
|
+
│ │
|
|
131
|
+
│ ┌───────────────┐ │
|
|
132
|
+
│ │ plan │ │
|
|
133
|
+
│ └───────────────┘ │
|
|
134
|
+
└──────────┬──────────┘
|
|
135
|
+
│
|
|
136
|
+
▼
|
|
137
|
+
┌──────────────────────────────────────────┐
|
|
138
|
+
│ EXECUTION (per phase) │
|
|
139
|
+
│ │
|
|
140
|
+
│ ┌──────┐ ┌─────────┐ ┌────────┐ ┌───────┐│
|
|
141
|
+
│ │ plan │─▶│ execute │─▶│ review │─▶│revise ││
|
|
142
|
+
│ └──────┘ └─────────┘ └────────┘ └───┬───┘│
|
|
143
|
+
│ ▲ │ │
|
|
144
|
+
│ └───────────────────────┘ │
|
|
145
|
+
│ (fix loop) │
|
|
146
|
+
│ │
|
|
147
|
+
│ Phase done? ──▶ Next phase ─┐ │
|
|
148
|
+
│ ▲ │ │
|
|
149
|
+
│ └──────────────────────┘ │
|
|
150
|
+
└──────────────────┬─────────────────────────────┘
|
|
151
|
+
│ all phases done
|
|
152
|
+
▼
|
|
153
|
+
┌────────────┐
|
|
154
|
+
│ COMPLETE │
|
|
155
|
+
└────────────┘
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Hook Execution Order
|
|
161
|
+
|
|
162
|
+
Around every step, hooks execute in this order:
|
|
163
|
+
|
|
164
|
+
```
|
|
165
|
+
┌─────────────────────────────────┐
|
|
166
|
+
│ 1. Global pre-step hook │ pipeline.json → hooks.pre-step
|
|
167
|
+
├─────────────────────────────────┤
|
|
168
|
+
│ 2. Step pre-hook │ step config or .specd/hooks/pre-{step}.md
|
|
169
|
+
├─────────────────────────────────┤
|
|
170
|
+
│ 3. ▶▶▶ STEP WORKFLOW ◀◀◀ │ the actual step (discuss, execute, etc.)
|
|
171
|
+
├─────────────────────────────────┤
|
|
172
|
+
│ 4. Step post-hook │ step config or .specd/hooks/post-{step}.md
|
|
173
|
+
├─────────────────────────────────┤
|
|
174
|
+
│ 5. Global post-step hook │ pipeline.json → hooks.post-step
|
|
175
|
+
└─────────────────────────────────┘
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Writing Custom Step Workflows
|
|
181
|
+
|
|
182
|
+
If you replace a step's workflow (e.g., `"workflow": ".specd/my-execute.md"`), your workflow **must update state** so the brain knows what happened. The brain reads config.json after your step returns.
|
|
183
|
+
|
|
184
|
+
### What Each Step Must Do
|
|
185
|
+
|
|
186
|
+
**Custom `discuss` replacement:**
|
|
187
|
+
- Update `CONTEXT.md` — check off resolved gray areas
|
|
188
|
+
- The brain re-reads gray area count to decide whether to stay in discussion or advance
|
|
189
|
+
|
|
190
|
+
**Custom `research` replacement:**
|
|
191
|
+
- Create `RESEARCH.md` in the task directory
|
|
192
|
+
- The brain checks for this file to know research is done
|
|
193
|
+
|
|
194
|
+
**Custom `plan` replacement (task-level, main pipeline):**
|
|
195
|
+
- Create `ROADMAP.md` with phase goals (no PLAN.md files, no phase directories)
|
|
196
|
+
- Set in config.json:
|
|
197
|
+
```json
|
|
198
|
+
{
|
|
199
|
+
"stage": "execution",
|
|
200
|
+
"phases": {
|
|
201
|
+
"current": 1,
|
|
202
|
+
"current_status": "pending",
|
|
203
|
+
"total": <number of phases>
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
**Custom `plan` replacement (phase-level, phase-execution pipeline — `phase-plan.md`):**
|
|
209
|
+
- Create `phases/phase-NN/` directory and `PLAN.md` for the current phase
|
|
210
|
+
- Read phase goal from ROADMAP.md
|
|
211
|
+
- Do NOT change config.json (brain checks PLAN.md existence to route)
|
|
212
|
+
|
|
213
|
+
**Custom `execute` replacement:**
|
|
214
|
+
- Do whatever execution work is needed for the current phase
|
|
215
|
+
- Set in config.json:
|
|
216
|
+
```json
|
|
217
|
+
{ "phases": { "current_status": "executed" } }
|
|
218
|
+
```
|
|
219
|
+
- The brain will then route to `review`
|
|
220
|
+
|
|
221
|
+
**Custom `review` replacement:**
|
|
222
|
+
- Review the executed phase
|
|
223
|
+
- Set in config.json based on outcome:
|
|
224
|
+
- **Approved:** `{ "phases": { "current_status": "completed" } }` — brain advances to next phase
|
|
225
|
+
- **Needs revision:** set up for revise step (keep `current_status` as `"executed"`)
|
|
226
|
+
|
|
227
|
+
**Custom `revise` replacement:**
|
|
228
|
+
- Create fix plan in a decimal phase directory (e.g., `phase-01.1/`)
|
|
229
|
+
- Set in config.json:
|
|
230
|
+
```json
|
|
231
|
+
{ "phases": { "current_status": "pending" } }
|
|
232
|
+
```
|
|
233
|
+
- The brain loops back to execute for the fix phase
|
|
234
|
+
|
|
235
|
+
### State Update Summary
|
|
236
|
+
|
|
237
|
+
| Your step | Must set | Brain then routes to |
|
|
238
|
+
|-----------|----------|---------------------|
|
|
239
|
+
| discuss | Update gray areas in CONTEXT.md | discuss (if gray areas remain) or research |
|
|
240
|
+
| research | Create RESEARCH.md | plan |
|
|
241
|
+
| plan (task-level) | Create ROADMAP.md, set stage=execution | plan (phase-level) |
|
|
242
|
+
| plan (phase-level) | Create phases/phase-NN/PLAN.md | execute |
|
|
243
|
+
| execute | Set current_status=executed | review |
|
|
244
|
+
| review (approved) | Set current_status=completed | next phase or complete |
|
|
245
|
+
| review (revisions) | Keep current_status=executed | revise |
|
|
246
|
+
| revise | Set current_status=pending | execute (fix phase) |
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## Phase Sub-Lifecycle
|
|
251
|
+
|
|
252
|
+
Each phase goes through its own mini-lifecycle within execution:
|
|
253
|
+
|
|
254
|
+
```
|
|
255
|
+
pending
|
|
256
|
+
│
|
|
257
|
+
┌────┴─────┐
|
|
258
|
+
│ PLAN.md? │
|
|
259
|
+
└────┬─────┘
|
|
260
|
+
│
|
|
261
|
+
No ────┤──── Yes
|
|
262
|
+
│ │
|
|
263
|
+
▼ │
|
|
264
|
+
┌──────┐ │
|
|
265
|
+
│ plan │ │
|
|
266
|
+
└──┬───┘ │
|
|
267
|
+
│ │
|
|
268
|
+
└────┬───────┘
|
|
269
|
+
│
|
|
270
|
+
▼
|
|
271
|
+
executing ◀──────┐
|
|
272
|
+
│ │
|
|
273
|
+
▼ │
|
|
274
|
+
executed │
|
|
275
|
+
│ │
|
|
276
|
+
▼ │
|
|
277
|
+
┌────────┐ │
|
|
278
|
+
│ review │ │
|
|
279
|
+
└───┬────┘ │
|
|
280
|
+
│ │
|
|
281
|
+
┌────┴─────┐ │
|
|
282
|
+
▼ ▼ │
|
|
283
|
+
completed revise ────┘
|
|
284
|
+
│ (creates
|
|
285
|
+
│ fix phase,
|
|
286
|
+
▼ resets to
|
|
287
|
+
next phase pending)
|
|
288
|
+
or DONE
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
The plan step uses `phase-plan.md` — a dedicated workflow that reads the phase goal from ROADMAP.md and creates a detailed PLAN.md for that phase only. This allows later phases to adapt based on earlier phase outcomes.
|
|
292
|
+
|
|
293
|
+
**Decimal fix phases:** When revise creates `phase-01.1/`, the brain executes it before advancing to `phase-02/`. Multiple revisions create `phase-01.1`, `phase-01.2`, etc.
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
## Pipeline Configuration Reference
|
|
298
|
+
|
|
299
|
+
Full `pipeline.json` with all options:
|
|
300
|
+
|
|
301
|
+
```json
|
|
302
|
+
{
|
|
303
|
+
"schema_version": "1.0",
|
|
304
|
+
"pipelines": {
|
|
305
|
+
"main": [
|
|
306
|
+
{
|
|
307
|
+
"name": "discuss",
|
|
308
|
+
"workflow": "discuss.md",
|
|
309
|
+
"hooks": { "pre": null, "post": null }
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
"name": "research",
|
|
313
|
+
"workflow": "research.md",
|
|
314
|
+
"hooks": { "pre": null, "post": null }
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
"name": "plan",
|
|
318
|
+
"workflow": "plan.md",
|
|
319
|
+
"hooks": { "pre": null, "post": null }
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
"name": "phase-execution",
|
|
323
|
+
"pipeline": "phase-execution"
|
|
324
|
+
}
|
|
325
|
+
],
|
|
326
|
+
"phase-execution": [
|
|
327
|
+
{
|
|
328
|
+
"name": "plan",
|
|
329
|
+
"workflow": "phase-plan.md",
|
|
330
|
+
"hooks": { "pre": null, "post": null }
|
|
331
|
+
},
|
|
332
|
+
{
|
|
333
|
+
"name": "execute",
|
|
334
|
+
"workflow": "execute.md",
|
|
335
|
+
"pause": true,
|
|
336
|
+
"hooks": { "pre": null, "post": null }
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
"name": "review",
|
|
340
|
+
"workflow": "review.md",
|
|
341
|
+
"pause": true,
|
|
342
|
+
"hooks": { "pre": null, "post": null }
|
|
343
|
+
},
|
|
344
|
+
{
|
|
345
|
+
"name": "revise",
|
|
346
|
+
"workflow": "revise.md",
|
|
347
|
+
"pause": true,
|
|
348
|
+
"hooks": { "pre": null, "post": null }
|
|
349
|
+
}
|
|
350
|
+
]
|
|
351
|
+
},
|
|
352
|
+
"hooks": {
|
|
353
|
+
"pre-step": null,
|
|
354
|
+
"post-step": null
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
**Step fields:**
|
|
360
|
+
|
|
361
|
+
| Field | Required | Default | Description |
|
|
362
|
+
|-------|----------|---------|-------------|
|
|
363
|
+
| `name` | yes | — | Step identifier, used for routing and hook discovery |
|
|
364
|
+
| `workflow` | yes* | — | Markdown file to execute (* not needed if `pipeline` is set) |
|
|
365
|
+
| `pipeline` | — | — | Reference a sub-pipeline instead of a workflow |
|
|
366
|
+
| `pause` | no | `false` | Whether default mode pauses here (ignored in `--auto`, always prompts in `--interactive`) |
|
|
367
|
+
| `hooks.pre` | no | `null` | Pre-hook config or `null` for convention fallback |
|
|
368
|
+
| `hooks.post` | no | `null` | Post-hook config or `null` for convention fallback |
|
|
369
|
+
|
|
370
|
+
**Hook config fields:**
|
|
371
|
+
|
|
372
|
+
| Field | Required | Default | Description |
|
|
373
|
+
|-------|----------|---------|-------------|
|
|
374
|
+
| `workflow` | yes | — | Path to hook markdown file |
|
|
375
|
+
| `mode` | no | `"inline"` | `"inline"` (runs in brain context) or `"subagent"` (isolated) |
|
|
376
|
+
| `optional` | no | `false` | If `true`, failures are logged but don't stop the pipeline |
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema_version": "1.0",
|
|
3
|
+
"pipelines": {
|
|
4
|
+
"main": [
|
|
5
|
+
{
|
|
6
|
+
"name": "discuss",
|
|
7
|
+
"workflow": "discuss.md",
|
|
8
|
+
"hooks": {
|
|
9
|
+
"pre": null,
|
|
10
|
+
"post": null
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"name": "research",
|
|
15
|
+
"workflow": "research.md",
|
|
16
|
+
"hooks": {
|
|
17
|
+
"pre": null,
|
|
18
|
+
"post": null
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"name": "plan",
|
|
23
|
+
"workflow": "plan.md",
|
|
24
|
+
"hooks": {
|
|
25
|
+
"pre": null,
|
|
26
|
+
"post": null
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"name": "phase-execution",
|
|
31
|
+
"pipeline": "phase-execution"
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
"phase-execution": [
|
|
35
|
+
{
|
|
36
|
+
"name": "plan",
|
|
37
|
+
"workflow": "phase-plan.md",
|
|
38
|
+
"hooks": {
|
|
39
|
+
"pre": null,
|
|
40
|
+
"post": null
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"name": "execute",
|
|
45
|
+
"workflow": "execute.md",
|
|
46
|
+
"pause": true,
|
|
47
|
+
"hooks": {
|
|
48
|
+
"pre": null,
|
|
49
|
+
"post": null
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"name": "review",
|
|
54
|
+
"workflow": "review.md",
|
|
55
|
+
"pause": true,
|
|
56
|
+
"hooks": {
|
|
57
|
+
"pre": null,
|
|
58
|
+
"post": null
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"name": "revise",
|
|
63
|
+
"workflow": "revise.md",
|
|
64
|
+
"pause": true,
|
|
65
|
+
"hooks": {
|
|
66
|
+
"pre": null,
|
|
67
|
+
"post": null
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
]
|
|
71
|
+
},
|
|
72
|
+
"hooks": {
|
|
73
|
+
"pre-step": null,
|
|
74
|
+
"post-step": null
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
<shared name="brain_routing">
|
|
2
|
+
|
|
3
|
+
## Brain Routing
|
|
4
|
+
|
|
5
|
+
Determine the next pipeline step based on current state. The brain calls this after loading state to figure out where to dispatch.
|
|
6
|
+
|
|
7
|
+
**Before using this reference, you must have ready:**
|
|
8
|
+
- `$PIPELINE` — loaded pipeline config
|
|
9
|
+
- `$CONFIG` — task config.json contents
|
|
10
|
+
- `$STATE` — task STATE.md contents
|
|
11
|
+
- `$CONTEXT` — task CONTEXT.md contents
|
|
12
|
+
- `$TASK_DIR` — path to task directory
|
|
13
|
+
|
|
14
|
+
### Read Current State
|
|
15
|
+
|
|
16
|
+
Extract from config.json:
|
|
17
|
+
- `stage` — discussion, research, planning, execution
|
|
18
|
+
- `phases.current` — current phase number (if in execution)
|
|
19
|
+
- `phases.current_status` — pending, executing, executed, completed (if in execution)
|
|
20
|
+
- `phases.total` — total phases (if planned)
|
|
21
|
+
|
|
22
|
+
Extract from CONTEXT.md:
|
|
23
|
+
- Count unchecked items in "Gray Areas Remaining" section → `$GRAY_AREAS_COUNT`
|
|
24
|
+
|
|
25
|
+
### Route to Next Step
|
|
26
|
+
|
|
27
|
+
**State-to-step mapping:**
|
|
28
|
+
|
|
29
|
+
| State | Next Step | Pipeline |
|
|
30
|
+
|-------|-----------|----------|
|
|
31
|
+
| stage=discussion, gray areas > 0 | `discuss` | main |
|
|
32
|
+
| stage=discussion, gray areas = 0 | `research` (or `plan` if user skips) | main |
|
|
33
|
+
| stage=research, no RESEARCH.md | `research` | main |
|
|
34
|
+
| stage=planning, no phases dir | `plan` | main |
|
|
35
|
+
| stage=planning or execution, phases.current_status=pending, no PLAN.md | `plan` | phase-execution |
|
|
36
|
+
| stage=planning or execution, phases.current_status=pending, PLAN.md exists | `execute` | phase-execution |
|
|
37
|
+
| stage=execution, phases.current_status=executing | `execute` (resume) | phase-execution |
|
|
38
|
+
| stage=execution, phases.current_status=executed | `review` | phase-execution |
|
|
39
|
+
| stage=execution, phases.current_status=completed | check more phases | phase-execution |
|
|
40
|
+
|
|
41
|
+
### Routing Logic
|
|
42
|
+
|
|
43
|
+
**1. Discussion stage with gray areas:**
|
|
44
|
+
```
|
|
45
|
+
$NEXT_STEP = "discuss"
|
|
46
|
+
$NEXT_PIPELINE = "main"
|
|
47
|
+
```
|
|
48
|
+
**2. Discussion stage, no gray areas:**
|
|
49
|
+
```
|
|
50
|
+
$NEXT_STEP = "research"
|
|
51
|
+
$NEXT_PIPELINE = "main"
|
|
52
|
+
```
|
|
53
|
+
Auto-proceed to research.
|
|
54
|
+
|
|
55
|
+
**3. Research stage:**
|
|
56
|
+
```bash
|
|
57
|
+
[ -f "$TASK_DIR/RESEARCH.md" ] && echo "has_research"
|
|
58
|
+
```
|
|
59
|
+
If no RESEARCH.md:
|
|
60
|
+
```
|
|
61
|
+
$NEXT_STEP = "research"
|
|
62
|
+
$NEXT_PIPELINE = "main"
|
|
63
|
+
```
|
|
64
|
+
If RESEARCH.md exists, advance to plan.
|
|
65
|
+
|
|
66
|
+
**4. Planning stage, no phases:**
|
|
67
|
+
```bash
|
|
68
|
+
[ -d "$TASK_DIR/phases" ] && echo "has_phases"
|
|
69
|
+
```
|
|
70
|
+
If no phases:
|
|
71
|
+
```
|
|
72
|
+
$NEXT_STEP = "plan"
|
|
73
|
+
$NEXT_PIPELINE = "main"
|
|
74
|
+
```
|
|
75
|
+
If phases exist, advance to execution.
|
|
76
|
+
|
|
77
|
+
**5. Execution — phases.current_status = "pending":**
|
|
78
|
+
|
|
79
|
+
Check if the current phase already has a PLAN.md (just-in-time planning):
|
|
80
|
+
```bash
|
|
81
|
+
PHASE_DIR="$TASK_DIR/phases/phase-$(printf '%02d' $CURRENT)"
|
|
82
|
+
[ -f "$PHASE_DIR/PLAN.md" ] && echo "has_plan"
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
If no PLAN.md — phase needs planning first:
|
|
86
|
+
```
|
|
87
|
+
$NEXT_STEP = "plan"
|
|
88
|
+
$NEXT_PIPELINE = "phase-execution"
|
|
89
|
+
```
|
|
90
|
+
plan.md detects stage=execution and creates a detailed PLAN.md for this phase only, reading the goal from ROADMAP.md.
|
|
91
|
+
|
|
92
|
+
If PLAN.md exists — phase is planned, ready to execute:
|
|
93
|
+
```
|
|
94
|
+
$NEXT_STEP = "execute"
|
|
95
|
+
$NEXT_PIPELINE = "phase-execution"
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**6. Execution — phases.current_status = "executing":**
|
|
99
|
+
```
|
|
100
|
+
$NEXT_STEP = "execute"
|
|
101
|
+
$NEXT_PIPELINE = "phase-execution"
|
|
102
|
+
$RESUME = true
|
|
103
|
+
```
|
|
104
|
+
Interrupted execution — resume.
|
|
105
|
+
|
|
106
|
+
**7. Execution — phases.current_status = "executed":**
|
|
107
|
+
```
|
|
108
|
+
$NEXT_STEP = "review"
|
|
109
|
+
$NEXT_PIPELINE = "phase-execution"
|
|
110
|
+
```
|
|
111
|
+
Phase done, needs review.
|
|
112
|
+
|
|
113
|
+
**8. Execution — phases.current_status = "completed":**
|
|
114
|
+
Check for more phases:
|
|
115
|
+
```bash
|
|
116
|
+
# Check if current phase < total phases
|
|
117
|
+
CURRENT=$(read phases.current from config.json)
|
|
118
|
+
TOTAL=$(read phases.total from config.json)
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Also check for decimal fix phases:
|
|
122
|
+
```bash
|
|
123
|
+
ls -d $TASK_DIR/phases/phase-$(printf '%02d' $CURRENT).* 2>/dev/null
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
If decimal fix phases exist and are incomplete → route to execute for fix phase.
|
|
127
|
+
If current < total → advance `phases.current`, set status to "pending", route to execute.
|
|
128
|
+
If current >= total → task complete.
|
|
129
|
+
|
|
130
|
+
### Task Complete
|
|
131
|
+
|
|
132
|
+
When all phases are done:
|
|
133
|
+
```
|
|
134
|
+
$NEXT_STEP = "complete"
|
|
135
|
+
$TASK_COMPLETE = true
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Find Step in Pipeline
|
|
139
|
+
|
|
140
|
+
To find a step by name in a pipeline array:
|
|
141
|
+
|
|
142
|
+
```
|
|
143
|
+
For each step in $PIPELINE.pipelines.{pipeline_name}:
|
|
144
|
+
If step.name == $NEXT_STEP:
|
|
145
|
+
Return step (workflow path, hooks config)
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
If step not found in pipeline → error:
|
|
149
|
+
```
|
|
150
|
+
Step '{name}' not found in pipeline '{pipeline_name}'. Check your pipeline.json.
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Resolve Workflow Path
|
|
154
|
+
|
|
155
|
+
Step workflow values are filenames (e.g., `"discuss.md"`). Resolve to full path:
|
|
156
|
+
|
|
157
|
+
```
|
|
158
|
+
~/.claude/specdacular/workflows/{workflow}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Or for local install:
|
|
162
|
+
```
|
|
163
|
+
.claude/specdacular/workflows/{workflow}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
For user-overridden workflows (path contains `/`), use as-is (relative to project root).
|
|
167
|
+
|
|
168
|
+
</shared>
|
|
@@ -8,23 +8,26 @@ Commit implementation code changes, respecting the user's auto-commit setting.
|
|
|
8
8
|
- `$FILES` — the files to `git add` (space-separated paths)
|
|
9
9
|
- `$MESSAGE` — the commit message
|
|
10
10
|
|
|
11
|
-
**
|
|
11
|
+
**IMPORTANT — You MUST check the auto-commit setting BEFORE running any git commands. Do NOT skip this check.**
|
|
12
|
+
|
|
13
|
+
**Step 1: Read the setting (MANDATORY):**
|
|
12
14
|
|
|
13
15
|
```bash
|
|
14
16
|
cat .specd/config.json 2>/dev/null || echo '{"auto_commit_code": true}'
|
|
15
17
|
```
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
Read the value of `auto_commit_code` from the output.
|
|
20
|
+
|
|
21
|
+
**Step 2: If `auto_commit_code` is `false` → STOP. Do NOT commit.**
|
|
22
|
+
|
|
23
|
+
Print this message and move on to the next workflow step:
|
|
19
24
|
|
|
20
25
|
```
|
|
21
26
|
Auto-commit disabled for code — changes not committed.
|
|
22
27
|
Modified files: $FILES
|
|
23
28
|
```
|
|
24
29
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
**If `auto_commit_code` is `true` or not set (default):**
|
|
30
|
+
**Step 3: If `auto_commit_code` is `true` or not set (default true) → commit:**
|
|
28
31
|
|
|
29
32
|
```bash
|
|
30
33
|
git add $FILES
|
|
@@ -9,23 +9,26 @@ Commit `.specd/` documentation changes, respecting the user's auto-commit settin
|
|
|
9
9
|
- `$MESSAGE` — the commit message
|
|
10
10
|
- `$LABEL` — short label for the skip message (e.g., "discussion updates", "plan complete", "feature completion")
|
|
11
11
|
|
|
12
|
-
**
|
|
12
|
+
**IMPORTANT — You MUST check the auto-commit setting BEFORE running any git commands. Do NOT skip this check.**
|
|
13
|
+
|
|
14
|
+
**Step 1: Read the setting (MANDATORY):**
|
|
13
15
|
|
|
14
16
|
```bash
|
|
15
17
|
cat .specd/config.json 2>/dev/null || echo '{"auto_commit_docs": true}'
|
|
16
18
|
```
|
|
17
19
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
+
Read the value of `auto_commit_docs` from the output.
|
|
21
|
+
|
|
22
|
+
**Step 2: If `auto_commit_docs` is `false` → STOP. Do NOT commit.**
|
|
23
|
+
|
|
24
|
+
Print this message and move on to the next workflow step:
|
|
20
25
|
|
|
21
26
|
```
|
|
22
27
|
Auto-commit disabled for docs — $LABEL not committed.
|
|
23
28
|
Modified files: $FILES
|
|
24
29
|
```
|
|
25
30
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
**If `auto_commit_docs` is `true` or not set (default):**
|
|
31
|
+
**Step 3: If `auto_commit_docs` is `true` or not set (default true) → commit:**
|
|
29
32
|
|
|
30
33
|
```bash
|
|
31
34
|
git add $FILES
|