gsdd-cli 0.16.1 → 0.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +111 -61
  2. package/agents/README.md +1 -1
  3. package/bin/adapters/claude.mjs +8 -1
  4. package/bin/adapters/codex.mjs +5 -1
  5. package/bin/adapters/opencode.mjs +7 -1
  6. package/bin/gsdd.mjs +25 -20
  7. package/bin/lib/evidence-contract.mjs +112 -0
  8. package/bin/lib/health-truth.mjs +29 -31
  9. package/bin/lib/health.mjs +61 -106
  10. package/bin/lib/init-flow.mjs +91 -34
  11. package/bin/lib/init-runtime.mjs +46 -25
  12. package/bin/lib/init.mjs +3 -7
  13. package/bin/lib/lifecycle-preflight.mjs +333 -0
  14. package/bin/lib/lifecycle-state.mjs +476 -0
  15. package/bin/lib/manifest.mjs +24 -20
  16. package/bin/lib/phase.mjs +81 -26
  17. package/bin/lib/provenance.mjs +295 -54
  18. package/bin/lib/rendering.mjs +70 -12
  19. package/bin/lib/runtime-freshness.mjs +264 -0
  20. package/bin/lib/session-fingerprint.mjs +106 -0
  21. package/distilled/DESIGN.md +707 -13
  22. package/distilled/EVIDENCE-INDEX.md +166 -1
  23. package/distilled/README.md +44 -28
  24. package/distilled/SKILL.md +4 -4
  25. package/distilled/templates/agents.block.md +1 -1
  26. package/distilled/workflows/audit-milestone.md +50 -0
  27. package/distilled/workflows/complete-milestone.md +38 -2
  28. package/distilled/workflows/execute.md +16 -3
  29. package/distilled/workflows/map-codebase.md +15 -4
  30. package/distilled/workflows/new-milestone.md +53 -24
  31. package/distilled/workflows/new-project.md +44 -25
  32. package/distilled/workflows/pause.md +1 -1
  33. package/distilled/workflows/plan.md +187 -74
  34. package/distilled/workflows/progress.md +135 -31
  35. package/distilled/workflows/quick.md +20 -12
  36. package/distilled/workflows/resume.md +152 -65
  37. package/distilled/workflows/verify.md +55 -20
  38. package/docs/BROWNFIELD-PROOF.md +95 -0
  39. package/docs/RUNTIME-SUPPORT.md +77 -0
  40. package/docs/USER-GUIDE.md +443 -0
  41. package/docs/VERIFICATION-DISCIPLINE.md +59 -0
  42. package/docs/claude/context-monitor.md +98 -0
  43. package/docs/proof/consumer-node-cli/README.md +37 -0
  44. package/docs/proof/consumer-node-cli/ROADMAP.md +14 -0
  45. package/docs/proof/consumer-node-cli/SPEC.md +17 -0
  46. package/docs/proof/consumer-node-cli/brief.md +9 -0
  47. package/docs/proof/consumer-node-cli/phases/01-foundation/01-01-PLAN.md +34 -0
  48. package/docs/proof/consumer-node-cli/phases/01-foundation/01-01-SUMMARY.md +10 -0
  49. package/docs/proof/consumer-node-cli/phases/01-foundation/01-VERIFICATION.md +30 -0
  50. package/package.json +26 -20
@@ -12,25 +12,62 @@ Scope boundary: you are NOT resume.md. You do not wait for user input, clean up
12
12
  This is a read-only workflow. No files are created, modified, or deleted. If `.planning/` does not exist, tell the user to run `gsdd init` and stop.
13
13
  </prerequisites>
14
14
 
15
+ <lifecycle_boundary>
16
+ `progress` stays read-only.
17
+
18
+ - Derive lifecycle posture from repo truth only; do not mutate phase or milestone state from this workflow.
19
+ - Do not call `node .planning/bin/gsdd.mjs phase-status` here.
20
+ - If you recommend a next step that crosses a lifecycle boundary, the downstream mutating workflow must rerun its own `node .planning/bin/gsdd.mjs lifecycle-preflight ...` gate before acting.
21
+ </lifecycle_boundary>
22
+
15
23
  <process>
16
24
 
17
25
  <check_existence>
18
26
  Check for project artifacts in order:
19
27
 
20
28
  1. **No `.planning/` directory** — tell the user to run `gsdd init`. Stop.
21
- 2. **No `.planning/ROADMAP.md` AND no `.planning/SPEC.md`** project has no artifacts. Suggest running the `/gsdd-new-project` workflow. Stop.
22
- 3. **No `.planning/ROADMAP.md` BUT `.planning/SPEC.md` exists** this is a between-milestones state (milestone was completed and archived). Go to Branch F.
23
- 4. **Both exist** proceed to derive status.
29
+ 2. **If `.planning/brownfield-change/CHANGE.md` exists**treat this as the active medium-scope brownfield continuity state. Go to Branch F.
30
+ 3. **No `.planning/ROADMAP.md` AND no `.planning/SPEC.md`**check for non-phase brownfield artifacts:
31
+ - if `.planning/codebase/` has substantive map documents, or `.planning/quick/` has LOG/task artifacts, treat this as a non-phase brownfield state. Go to Branch F.
32
+ - otherwise the project has no artifacts. Suggest running the `/gsdd-new-project` workflow. Stop.
33
+ 4. **No `.planning/ROADMAP.md` BUT `.planning/SPEC.md` exists** — this is a between-milestones state (milestone was completed and archived). Go to Branch F.
34
+ 5. **Both exist** — proceed to derive status, including whether a retained `ROADMAP.md` already represents an archived milestone rather than an audit-ready one.
24
35
  </check_existence>
25
36
 
26
37
  <derive_status>
27
38
  Read the following and extract state:
28
39
 
29
40
  **Project identity:**
30
- Read `.planning/SPEC.md`. Extract the project name from the first heading.
41
+ - If `.planning/SPEC.md` exists, read it and extract the project name from the first heading.
42
+ - If `.planning/SPEC.md` does not exist, derive the project name from the repo root directory name.
43
+
44
+ **Non-phase brownfield state:**
45
+ If `.planning/ROADMAP.md` does not exist, determine whether the repo is currently in one of these Branch F states:
46
+ - `active_brownfield_change` — `.planning/brownfield-change/CHANGE.md` exists; read `CHANGE.md` first as the canonical operational anchor, then read `HANDOFF.md` for judgment-only context
47
+ - `between_milestones` — `.planning/SPEC.md` exists
48
+ - `codebase_only` — `.planning/codebase/` has substantive map documents but `.planning/SPEC.md` does not exist
49
+ - `quick_lane` — `.planning/quick/LOG.md` or quick task directories exist but `.planning/SPEC.md` and `.planning/ROADMAP.md` do not
50
+
51
+ For `active_brownfield_change`, `codebase_only`, and `quick_lane`, there is no active phase count. Record the non-phase state instead of trying to infer current milestone progress.
52
+
53
+ **Active brownfield change:**
54
+ If `.planning/brownfield-change/CHANGE.md` exists, extract:
55
+ - change title from the first heading
56
+ - current posture from `## Current Status`
57
+ - current branch / integration surface from `## Current Status`
58
+ - next action from `## Next Action`
59
+ - declared write scope from `## PR Slice Ownership` when present
60
+
61
+ If `.planning/brownfield-change/HANDOFF.md` exists, read it as judgment-only context:
62
+ - active constraints
63
+ - unresolved uncertainty
64
+ - decision posture
65
+ - anti-regression
66
+
67
+ Do not treat `HANDOFF.md` as a co-equal status source. It explains the active change; `CHANGE.md` remains the operational anchor.
31
68
 
32
69
  **Phase statuses:**
33
- Read `.planning/ROADMAP.md`. Parse phase statuses:
70
+ If `.planning/ROADMAP.md` exists, read it and parse phase statuses:
34
71
  - `[ ]` = not started
35
72
  - `[-]` = in progress
36
73
  - `[x]` = done
@@ -41,16 +78,38 @@ Determine:
41
78
  - Current phase: first `[-]` phase, or first `[ ]` if none in progress
42
79
  - Current phase name
43
80
 
44
- **Checkpoint:**
45
- Check if `.planning/.continue-here.md` exists. If yes, note the `workflow` and `phase` frontmatter and the `next_action` section.
81
+ **Archived milestone evidence:**
82
+ If `ROADMAP.md` exists and all phases in the current milestone are `[x]`, determine whether this is still audit-ready or already archived-with-`ROADMAP.md`:
83
+ - derive the current milestone/version from the active milestone heading in `ROADMAP.md`
84
+ - check `.planning/MILESTONES.md` for a shipped entry matching that same milestone/version
85
+ - check for the matching archived milestone audit artifact for that same milestone/version (for example `.planning/v1.1-MILESTONE-AUDIT.md`)
86
+ - if both the shipped ledger entry and the matching archived audit artifact exist, treat the retained `ROADMAP.md` as archived milestone evidence and route to Branch F instead of Branch E
87
+ - if either one is missing, keep the milestone in the audit-ready Branch E state
88
+
89
+ **Checkpoint:**
90
+ Check if `.planning/.continue-here.md` exists. If yes, note the `workflow` and `phase` frontmatter and the `next_action` section.
91
+ - Treat checkpoint routing classes explicitly:
92
+ - `phase` and `quick` checkpoints remain blocking resume-owned surfaces for routing only when there is no active brownfield change, or when a shared strict-match rule proves they still describe the active execution surface.
93
+ - `generic` checkpoints are informational-only for this read-only reporter: show the checkpoint and its `next_action`, but keep evaluating the real lifecycle recommendation instead of routing Branch A back through `/gsdd-resume`.
94
+ - If `.planning/brownfield-change/CHANGE.md` also exists, apply one shared strict-match rule before letting a surviving `phase` or `quick` checkpoint outrank the operational anchor:
95
+ - branch alignment: the checkpoint branch, `CHANGE.md` integration surface, and current git branch all match
96
+ - scope alignment: the live dirty tree stays inside the declared brownfield write scope
97
+ - still-active execution state: the checkpoint still points at live unfinished `phase` or `quick` work
98
+ - If any one of those checks fails, keep the checkpoint visible in the status block but continue routing from the active brownfield change instead of bouncing Branch A back through `/gsdd-resume`.
46
99
 
47
100
  **Incomplete work:**
48
- Scan `.planning/phases/` for:
101
+ If `.planning/phases/` exists, scan it for:
49
102
  - PLAN files without a matching SUMMARY file (incomplete execution)
50
103
  - SUMMARY files without a matching VERIFICATION file (unverified, only relevant if `workflow.verifier` is enabled in `.planning/config.json`; if config.json cannot be read, assume verifier is disabled)
51
104
 
52
- **Quick task log:**
53
- If `.planning/quick/LOG.md` exists, check the last entry for a non-terminal status.
105
+ **Quick task log:**
106
+ If `.planning/quick/LOG.md` exists, check the last entry for a non-terminal status.
107
+
108
+ **Artifact-versus-worktree mismatch:**
109
+ If an active brownfield change exists, compare `CHANGE.md` to live git/worktree truth:
110
+ - branch mismatch between `CHANGE.md` and the current git branch is a warning
111
+ - dirty files outside the declared brownfield write scope are a warning
112
+ - `CHANGE.md` may stay the operational anchor, but conflicting worktree truth must not remain silent
54
113
 
55
114
  <unmerged_commits_check>
56
115
  Run `git log main..HEAD --oneline` to detect commits on the current branch that have not been merged to `main`.
@@ -81,12 +140,28 @@ Project: [name from SPEC.md]
81
140
  Phase: [current] of [total] — [phase name]
82
141
  Completed: [N] phases done
83
142
 
143
+ [If no active roadmap and Branch F is handling a non-phase state:]
144
+ State: [active brownfield change | between milestones | codebase map only | quick lane only]
145
+ Completed: no active roadmap
146
+
147
+ [If an active brownfield change exists:]
148
+ Active change: [title]
149
+ Status: [current posture]
150
+ Integration surface: [branch / integration surface from CHANGE.md]
151
+ Next action: [next action from CHANGE.md]
152
+ Judgment context: `HANDOFF.md` remains the decision-critical context surface, not a co-equal status authority
153
+ Growth boundary: stay in the bounded lane unless the work now needs multiple active streams, milestone-owned lifecycle state, or broader requirement tracking
154
+
155
+ [If the active brownfield artifact conflicts with git/worktree truth:]
156
+ Brownfield continuity warning: the active change artifact and live integration surface disagree
157
+ Review `CHANGE.md`, `HANDOFF.md`, and the current worktree before resuming
158
+
84
159
  Recent Work:
85
160
  - Phase [X]: [one-liner from SUMMARY.md]
86
161
  - Phase [Y]: [one-liner from SUMMARY.md]
87
162
 
88
- [If .continue-here.md exists:]
89
- Checkpoint: paused work found — run /gsdd-resume to restore context
163
+ [If .continue-here.md exists:]
164
+ Checkpoint: paused work found — `phase`/`quick` checkpoints route through /gsdd-resume only when the strict-match rule still proves they are the active execution surface; `generic` checkpoints stay visible as informational context only
90
165
 
91
166
  [If PLAN without SUMMARY found:]
92
167
  Incomplete execution: Phase [N] has PLAN but no SUMMARY
@@ -102,8 +177,11 @@ Unmerged commits: [N] commit(s) on this branch not yet merged to main
102
177
  → Merge or push this branch before closing the milestone, or verify
103
178
  these commits are intentional working-branch state.
104
179
 
105
- [If all phases [x]:]
180
+ [If all phases [x] and the current milestone is not yet archived:]
106
181
  All phases complete — ready for milestone audit
182
+
183
+ [If all phases [x] and the current milestone is already archived-with-`ROADMAP.md`: ]
184
+ All phases complete — archived milestone retained on disk; ready for the next milestone
107
185
  ```
108
186
 
109
187
  **Filled-in example** (fabricated but realistic):
@@ -130,14 +208,17 @@ No ASCII art, no progress bars. Keep it scannable.
130
208
  <route_action>
131
209
  Evaluate in priority order. Present the single best next step as a suggestion with a formatted output block. Do not wait for user selection, do not present numbered menus, do not clean up files. This is purely informational.
132
210
 
133
- **Branch A: Resume checkpoint**
134
- Condition: `.continue-here.md` exists.
135
-
136
- ```
137
- Suggested next action:
138
- Run /gsdd-resume to restore paused session context
139
- Also available: /gsdd-execute (ignore checkpoint, continue current phase), /gsdd-progress (refresh)
140
- ```
211
+ **Branch A: Resume checkpoint**
212
+ Condition: `.continue-here.md` exists, its `workflow` is `phase` or `quick`, and either no active brownfield change exists or the strict-match rule still proves that checkpoint is the active execution surface.
213
+
214
+ ```
215
+ Suggested next action:
216
+ Run /gsdd-resume to restore paused session context
217
+ Also available: /gsdd-execute (ignore checkpoint, continue current phase), /gsdd-progress (refresh)
218
+ ```
219
+
220
+ If `.continue-here.md` exists and its `workflow` is `generic`, do **not** route back through Branch A from this read-only reporter. Show the checkpoint in the status block, surface its `next_action`, and keep evaluating Branch B-F so the primary recommendation can advance toward the real next phase, verification, or milestone-close action.
221
+ If an active brownfield change exists and a `phase` or `quick` checkpoint fails the strict-match rule, treat that checkpoint the same way: keep it visible in the status block, but keep evaluating Branch B-F so the active brownfield change remains the primary recommendation.
141
222
 
142
223
  **Branch B: Execute (PLAN without SUMMARY in current phase)**
143
224
  Condition: Current phase has a PLAN file but no matching SUMMARY.
@@ -166,8 +247,8 @@ Suggested next action:
166
247
  Also available: /gsdd-execute (continue to next phase), /gsdd-plan (plan next phase)
167
248
  ```
168
249
 
169
- **Branch E: Audit milestone (all phases [x])**
170
- Condition: All phases in ROADMAP.md are marked `[x]`.
250
+ **Branch E: Audit milestone (all phases [x], not yet archived)**
251
+ Condition: All phases in the current milestone are marked `[x]`, and the current roadmap milestone/version does **not** yet have both a shipped entry in `.planning/MILESTONES.md` and the matching archived milestone audit artifact.
171
252
 
172
253
  ```
173
254
  Suggested next action:
@@ -175,22 +256,42 @@ Suggested next action:
175
256
  Also available: /gsdd-verify (re-verify a specific phase), /gsdd-quick (sub-hour task)
176
257
  ```
177
258
 
178
- **Branch F: Between milestones (SPEC.md exists, ROADMAP.md absent)**
179
- Condition: `.planning/SPEC.md` exists but `.planning/ROADMAP.md` does not — a milestone was completed and archived.
259
+ **Branch F: Non-phase state (no active roadmap, or retained roadmap already archived)**
260
+ Condition:
261
+ - `.planning/brownfield-change/CHANGE.md` exists, **or**
262
+ - `.planning/SPEC.md` exists but `.planning/ROADMAP.md` does not, **or**
263
+ - `.planning/codebase/` or `.planning/quick/` exists while both `.planning/SPEC.md` and `.planning/ROADMAP.md` are absent, **or**
264
+ - `.planning/ROADMAP.md` still exists, but the current roadmap milestone/version already has both a shipped entry in `.planning/MILESTONES.md` and the matching archived milestone audit artifact — this is the archived-with-`ROADMAP.md` state, not a second trip through audit
180
265
 
181
266
  Check `.planning/MILESTONES.md`:
182
267
  - If MILESTONES.md exists and has at least one milestone entry → this is a subsequent milestone
183
268
  - If MILESTONES.md does not exist or is empty → this is the first milestone setup
184
269
 
185
- ```
186
- Suggested next action (subsequent milestone):
187
- Run /gsdd-new-milestone to start the next milestone cycle (gather goals, define requirements, create ROADMAP.md)
188
- Also available: /gsdd-progress (refresh after milestone setup)
270
+ ```
271
+ Suggested next action (active brownfield change):
272
+ Run /gsdd-resume to restore the active brownfield change context from `.planning/brownfield-change/CHANGE.md`
273
+ Also available: inspect `.planning/brownfield-change/HANDOFF.md`, /gsdd-progress (refresh after the artifact or worktree changes), /gsdd-new-project (only if you intentionally want to widen this bounded change into the first milestone), /gsdd-new-milestone (only if the repo already has shipped milestone history and you intentionally want to widen this change into the next milestone cycle)
274
+
275
+ Suggested next action (subsequent milestone):
276
+ Run /gsdd-new-milestone to start the next milestone cycle (gather goals, define requirements, create ROADMAP.md)
277
+ Also available: /gsdd-progress (refresh after milestone setup)
189
278
 
190
279
  Suggested next action (incomplete milestone state — SPEC.md exists but no milestone archived yet):
191
280
  Inspect .planning/ manually — a milestone is likely still in progress.
192
281
  If a ROADMAP.md was deleted prematurely, re-run /gsdd-new-milestone to restore it.
193
282
  Do NOT run /gsdd-new-project — SPEC.md already exists and re-running would overwrite it.
283
+
284
+ Suggested next action (codebase-only brownfield state):
285
+ Run /gsdd-quick if the bounded change is already concrete.
286
+ Also available: /gsdd-new-project (if you intentionally want to widen into full lifecycle work), /gsdd-map-codebase (refresh or deepen the baseline)
287
+
288
+ Suggested next action (quick-lane brownfield state with incomplete quick work):
289
+ Run /gsdd-quick to continue or finish the current bounded change.
290
+ Also available: /gsdd-new-project (only if you intentionally want to widen this bounded change into full lifecycle setup), /gsdd-progress (refresh after the quick task is updated)
291
+
292
+ Suggested next action (quick-lane brownfield state with no incomplete quick work):
293
+ Run /gsdd-quick for the next bounded change.
294
+ Also available: /gsdd-new-project (if you intentionally want to widen into SPEC.md + ROADMAP.md), /gsdd-map-codebase (if the repo baseline feels stale)
194
295
  ```
195
296
 
196
297
  If none of the above conditions match, report that the project is in a clean state with no obvious next action.
@@ -199,8 +300,11 @@ If none of the above conditions match, report that the project is in a clean sta
199
300
  <edge_cases>
200
301
  Handle compound states:
201
302
 
202
- - **Checkpoint + unexecuted plan:** Both `.continue-here.md` exists and a PLAN lacks a SUMMARY. Prioritize checkpoint (Branch A) but mention the unexecuted plan in the status block.
203
- - **All phases complete + checkpoint:** All phases `[x]` but a checkpoint exists. Mention both suggest clearing the stale checkpoint via `/gsdd-resume`, then routing to milestone audit.
303
+ - **Checkpoint + unexecuted plan:** Both `.continue-here.md` exists and a PLAN lacks a SUMMARY. Prioritize checkpoint (Branch A) but mention the unexecuted plan in the status block.
304
+ - **Generic checkpoint + current phase work:** A `workflow: generic` checkpoint may coexist with an incomplete plan, unverified phase, or completed milestone. Keep the checkpoint visible in the status block, but let Branch B-F supply the primary recommendation instead of bouncing back to `/gsdd-resume`.
305
+ - **Active brownfield change + generic checkpoint:** Keep the generic checkpoint visible as informational context, but let the active brownfield change remain the continuity anchor and use Branch F for the primary recommendation.
306
+ - **Active brownfield change + non-matching `phase`/`quick` checkpoint:** Show the checkpoint as surviving context, but let the active brownfield change stay primary unless branch alignment, scope alignment, and still-active execution state all match.
307
+ - **All phases complete + checkpoint:** All phases `[x]` but a checkpoint exists. If the checkpoint is `phase` or `quick`, mention both and suggest `/gsdd-resume` before continuing. If the checkpoint is `generic`, keep it visible as informational context and still route the primary recommendation to milestone audit.
204
308
  - **Phase done but next unplanned:** Current phase has both PLAN and SUMMARY, but the next phase has no PLAN. Show the current phase as complete and suggest planning the next phase (Branch C targeting the next phase).
205
309
  - **No matching condition:** If the project state does not match any branch, report it clearly and suggest the user inspect `.planning/` manually.
206
310
  </edge_cases>
@@ -8,7 +8,7 @@ They reuse the same planner, executor, and verifier roles but skip research and
8
8
  <anti_patterns>
9
9
  - Do not execute before the user sees the plan preview (Step 3.7 must complete before Step 4)
10
10
  - Do not proceed past file verification gates if the expected file does not exist on disk — a plan that exists only in conversation context will be lost on compaction
11
- - Do not ask more than 2 approach clarification questions — if 3+ grey areas exist, recommend /gsdd-plan instead
11
+ - Do not ask more than 2 approach clarification questions — if the bounded change is still undefined, recommend `/gsdd-new-project`; if the change is defined but 3+ grey areas remain, recommend `/gsdd-plan` instead
12
12
  - Do not create APPROACH.md for quick tasks — use inline $APPROACH_CONTEXT only
13
13
  - Do not update ROADMAP.md or SPEC.md from quick tasks — these are phase-level artifacts
14
14
  - Do not skip config.json reads — workflow toggles (discuss, planCheck, verifier) control flow
@@ -33,13 +33,15 @@ Store the response as `$DESCRIPTION`. If empty, re-prompt.
33
33
 
34
34
  ## Step 2: Initialize
35
35
 
36
- 1. Read `.planning/config.json` for workflow toggles and git protocol.
37
- 2. Scan `.planning/quick/` for existing task directories. Calculate `$NEXT_NUM` as the next 3-digit number (001, 002, ...).
38
- 3. Generate `$SLUG` from `$DESCRIPTION` (lowercase, hyphens, max 40 chars).
39
- 4. Create `.planning/quick/$NEXT_NUM-$SLUG/`.
40
- 5. If `.planning/codebase/` exists, read `.planning/codebase/ARCHITECTURE.md` and `.planning/codebase/STACK.md`. Summarize key findings in <=500 words as `$CODEBASE_CONTEXT`. If `.planning/codebase/` does not exist, set `$CODEBASE_CONTEXT` to empty.
41
- 6. **Session-boundary fallback:** If `.planning/.continue-here.bak` exists, read its `<judgment>` section. Use `<active_constraints>` and `<anti_regression>` rules as task-scoping context (do not violate active constraints; do not regress on listed invariants). After reading, run `gsdd file-op delete .planning/.continue-here.bak --missing ok` (auto-clean).
42
- 7. Inspect the live branch/worktree surface separately from checkpoint or planning artifacts. If the current branch appears stale/spent, PR-less with overlapping write scope, or otherwise like the wrong execution surface, warn before proceeding. This is advisory for quick tasks unless the mismatch makes the task description materially misleading.
36
+ 1. Read `.planning/config.json` for workflow toggles and git protocol.
37
+ 2. Scan `.planning/quick/` for existing task directories. Calculate `$NEXT_NUM` as the next 3-digit number (001, 002, ...).
38
+ 3. Generate `$SLUG` from `$DESCRIPTION` (lowercase, hyphens, max 40 chars).
39
+ 4. Create `.planning/quick/$NEXT_NUM-$SLUG/`.
40
+ 5. If `.planning/brownfield-change/CHANGE.md` exists, read it first as the current bounded brownfield continuity anchor. Capture the active goal, current posture, next action, and declared write scope as `$BROWNFIELD_CONTEXT`. If `.planning/brownfield-change/HANDOFF.md` exists, read it as supporting judgment context only. Do not let `/gsdd-new-project` become the default fallback when this active change already defines a concrete bounded lane.
41
+ 6. If `.planning/codebase/` exists, read whichever of `.planning/codebase/ARCHITECTURE.md`, `.planning/codebase/STACK.md`, `.planning/codebase/CONVENTIONS.md`, and `.planning/codebase/CONCERNS.md` are present. Summarize key findings from available docs in <=500 words as `$CODEBASE_CONTEXT`, emphasizing: safest surfaces to touch, risky zones to avoid, must-know conventions/traps, and what must be re-verified after change. Note any missing docs in the summary.
42
+ 7. If `.planning/codebase/` does not exist, build a just-enough inline brownfield baseline instead of stopping. Read the repo root guidance that is cheap and stable (`README.md`, root manifest such as `package.json` / `pyproject.toml` / `Cargo.toml` when present, top-level app entrypoints, and any obviously relevant config or module files surfaced by `$DESCRIPTION`). Summarize the findings in <=500 words as `$CODEBASE_CONTEXT`, explicitly labeling it as a provisional baseline and calling out unknowns. Emphasize: likely implementation surface, likely dependency boundaries, conventions already visible, risky areas to avoid touching blindly, and what must be re-verified after the change. If the repo is still too unclear after this pass, keep that uncertainty explicit so Step 3.6 can recommend `/gsdd-map-codebase`.
43
+ 8. **Session-boundary fallback:** If `.planning/.continue-here.bak` exists, read its `<judgment>` section. Use `<active_constraints>` and `<anti_regression>` rules as task-scoping context (do not violate active constraints; do not regress on listed invariants). After reading, run `node .planning/bin/gsdd.mjs file-op delete .planning/.continue-here.bak --missing ok` (auto-clean).
44
+ 9. Inspect the live branch/worktree surface separately from checkpoint or planning artifacts. If the current branch appears stale/spent, PR-less with overlapping write scope, or otherwise like the wrong execution surface, warn before proceeding. This is advisory for quick tasks unless the mismatch makes the task description materially misleading.
43
45
 
44
46
  If `.planning/quick/` does not exist, create it along with an empty `LOG.md`:
45
47
 
@@ -79,7 +81,7 @@ For each grey area, present 2-3 concrete options with a recommended default:
79
81
 
80
82
  - If user says "go ahead" / "your call" / presses Enter → use the recommendation.
81
83
  - If user specifies a preference → record it.
82
- - Maximum 2 questions. If the task has 3+ grey areas, it's not a quick task.
84
+ - Maximum 2 questions. If the bounded change is still undefined after clarification, recommend `/gsdd-new-project`. If the change is defined but the task still has 3+ grey areas, it's not a quick task — recommend `/gsdd-plan`.
83
85
 
84
86
  ### Output
85
87
 
@@ -101,7 +103,7 @@ Delegate to the planner role in quick mode.
101
103
  **Context to provide:**
102
104
  - Task description: `$DESCRIPTION`
103
105
  - Approach context: `$APPROACH_CONTEXT` (user-confirmed decisions from Step 2.5 — treat as locked constraints, do not revisit)
104
- - Codebase context: `$CODEBASE_CONTEXT` (existing architecture and stack — use for orientation, not as constraints; empty if no codebase map exists)
106
+ - Codebase context: `$CODEBASE_CONTEXT` (existing brownfield codebase summary from codebase maps when they exist, otherwise the inline brownfield baseline from Step 2 — use for orientation and risk awareness, not as hard constraints)
105
107
  - Mode: quick (single plan, 1-3 tasks, no research phase)
106
108
  - Output path: `.planning/quick/$NEXT_NUM-$SLUG/$NEXT_NUM-PLAN.md`
107
109
 
@@ -178,8 +180,10 @@ Evaluate the plan against quick-scope boundaries. Read the plan file and check:
178
180
  | Files modified | >8 distinct files in plan | "This task touches {N} files — consider `/gsdd-plan` for full ceremony." |
179
181
  | Architecture keywords in `$DESCRIPTION` | contains: `refactor`, `migration`, `security`, `auth`, `API design`, `schema`, `database` | "This looks like architectural work — consider `/gsdd-plan` for approach exploration." |
180
182
  | New public APIs | Plan tasks create new route files, API endpoints, or exported interfaces | "New public surface area detected — consider `/gsdd-plan` for approach exploration." |
183
+ | Orientation gap | No `.planning/codebase/` exists AND the inline brownfield baseline still cannot name a clear implementation surface, dependency boundary, or safe-to-touch module | "This repo still needs deeper orientation — consider `/gsdd-map-codebase` before changing code." |
184
+ | Undefined bounded change | `$DESCRIPTION` still does not identify a concrete bug, feature, target surface, or observable outcome after clarification | "This does not yet describe a bounded change — use `/gsdd-new-project` to define the work first. If `.planning/brownfield-change/CHANGE.md` already defines a concrete bounded lane, treat `/gsdd-new-project` as an intentional widen path rather than the default fallback." |
181
185
 
182
- If any signal fires, set `$SCOPE_WARNING` to the first matching advisory text. Multiple signals concatenate.
186
+ If any signals fire, concatenate the matching advisory text in the listed order as `$SCOPE_WARNING`. If the undefined bounded change signal fires, keep that advisory first so the routing recommendation stays explicit.
183
187
  If no signals fire, `$SCOPE_WARNING` is empty.
184
188
 
185
189
  This is advisory only — it does NOT block execution.
@@ -216,11 +220,15 @@ Plan check issues: {$CHECKER_ISSUES}
216
220
 
217
221
  Present options (default-yes — pressing Enter proceeds):
218
222
  - If `$SCOPE_WARNING` is empty: `[Enter to proceed / edit description / abort]`
219
- - If `$SCOPE_WARNING` is non-empty: `[Enter to proceed / switch to /gsdd-plan / edit description / abort]`
223
+ - If `$SCOPE_WARNING` contains `/gsdd-new-project`: `[Enter to proceed / switch to /gsdd-new-project / edit description / abort]`
224
+ - Otherwise if `$SCOPE_WARNING` contains `/gsdd-map-codebase`: `[Enter to proceed / switch to /gsdd-map-codebase / edit description / abort]`
225
+ - Otherwise if `$SCOPE_WARNING` is non-empty: `[Enter to proceed / switch to /gsdd-plan / edit description / abort]`
220
226
 
221
227
  Handle response:
222
228
  - **Enter (or "yes"):** proceed to Step 4.
223
229
  - **"edit description":** clean up the task directory, then return to Step 1 with `$DESCRIPTION` pre-filled as the starting point.
230
+ - **"switch to /gsdd-new-project":** clean up the task directory, then stop quick workflow and report: "Use `/gsdd-new-project` to define or intentionally widen the work into full lifecycle planning. Task description: {$DESCRIPTION}"
231
+ - **"switch to /gsdd-map-codebase":** clean up the task directory, then stop quick workflow and report: "Use `/gsdd-map-codebase` for a deeper brownfield baseline before quick work. Task description: {$DESCRIPTION}"
224
232
  - **"switch to /gsdd-plan":** clean up the task directory, then stop quick workflow and report: "Use `/gsdd-plan` for full ceremony with approach exploration. Task description: {$DESCRIPTION}"
225
233
  - **"abort":** clean up the task directory, report cancellation, stop.
226
234
 
@@ -16,14 +16,28 @@ Infer runtime from the launching surface when obvious: `.claude/` -> `claude-cod
16
16
  When a checkpoint's `runtime` differs from the inferred current runtime, surface it as an informational note in `<present_status>` — it is context, not a gate.
17
17
  </runtime_contract>
18
18
 
19
+ <lifecycle_preflight>
20
+ Before loading checkpoint state or cleaning up any checkpoint file, run:
21
+
22
+ - `node .planning/bin/gsdd.mjs lifecycle-preflight resume`
23
+
24
+ If the preflight result is `blocked`, STOP and report the blocker instead of inferring resume eligibility from workflow-local prose.
25
+
26
+ Treat the preflight as an authorization seam over shared repo truth only:
27
+ - it may authorize or reject resume
28
+ - it does not mutate phase or milestone state
29
+ - the owned write for this workflow remains checkpoint cleanup when the user actually resumes from `.continue-here.md`
30
+ </lifecycle_preflight>
31
+
19
32
  <process>
20
33
 
21
34
  <detect_state>
22
35
  Check for project artifacts in order:
23
36
 
24
- 1. **No `.planning/` directory** — route user to run `gsdd init`. Stop.
25
- 2. **No `.planning/SPEC.md` or no `.planning/ROADMAP.md`** `.planning/` exists but the project is not fully initialized (partial init). Route user to run the `/gsdd-new-project` workflow. Stop.
26
- 3. **Both exist**proceed to load state.
37
+ 1. **No `.planning/` directory** — route user to run `gsdd init`. Stop.
38
+ 2. **If `.planning/brownfield-change/CHANGE.md` exists** this repo has an active medium-scope brownfield change. Proceed to load brownfield continuity state even if there is no active roadmap.
39
+ 3. **No `.planning/SPEC.md` or no `.planning/ROADMAP.md`** `.planning/` exists but the project is not fully initialized (partial init). Route user to run the `/gsdd-new-project` workflow. Stop.
40
+ 4. **Both exist** — proceed to load state.
27
41
  </detect_state>
28
42
 
29
43
  <load_artifacts>
@@ -41,10 +55,28 @@ Determine:
41
55
  - Next phase (first `[ ]` after current)
42
56
  - Completed phase count
43
57
 
44
- **SPEC.md:**
45
- Read `.planning/SPEC.md`. Extract:
46
- - Project name or description (first heading or "What This Is" section)
47
- - Current state summary if present
58
+ **SPEC.md:**
59
+ Read `.planning/SPEC.md`. Extract:
60
+ - Project name or description (first heading or "What This Is" section)
61
+ - Current state summary if present
62
+
63
+ **Active brownfield change:**
64
+ If `.planning/brownfield-change/CHANGE.md` exists, read it first as the canonical operational continuity anchor and extract:
65
+ - change title from the first heading
66
+ - current posture from `## Current Status`
67
+ - current branch / integration surface from `## Current Status`
68
+ - current owner / runtime from `## Current Status`
69
+ - next action from `## Next Action`
70
+ - declared write scope from `## PR Slice Ownership` when present
71
+
72
+ If `.planning/brownfield-change/HANDOFF.md` exists, read it as judgment-only context:
73
+ - active constraints
74
+ - unresolved uncertainty
75
+ - decision posture
76
+ - anti-regression
77
+ - next-action context
78
+
79
+ Do not flatten `CHANGE.md` and `HANDOFF.md` into co-equal operational sources. `CHANGE.md` stays the live status/next-action anchor; `HANDOFF.md` explains why that posture exists.
48
80
 
49
81
  **Checkpoint file:**
50
82
  Check if `.planning/.continue-here.md` exists. If yes, read it and extract:
@@ -74,25 +106,38 @@ Collect the live integration-surface facts separately from checkpoint narrative
74
106
  </load_artifacts>
75
107
 
76
108
  <provenance_reconciliation>
77
- Before routing, reconstruct and compare these truth buckets explicitly:
78
-
79
- 1. **Checkpoint narrative truth** — what `.planning/.continue-here.md` claims was happening
80
- 2. **Planning/artifact truth** — what ROADMAP, SPEC, phase files, and quick-task logs say
81
- 3. **Git/worktree truth** — what the live branch and working tree say now
109
+ Before routing, reconstruct and compare these truth buckets explicitly:
110
+
111
+ 1. **Checkpoint narrative truth** — what `.planning/.continue-here.md` claims was happening
112
+ 2. **Planning/artifact truth** — what ROADMAP, SPEC, phase files, quick-task logs, and the active brownfield change artifacts say
113
+ 3. **Git/worktree truth** — what the live branch and working tree say now
82
114
 
83
115
  Treat them as separate inputs. Do not flatten them into one continuity story.
84
116
 
85
- Material mismatch signals include:
86
- - checkpoint narrative describes only a narrow slice of a broader dirty tree
87
- - current branch is stale/spent relative to the next intended integration surface
88
- - dirty files suggest overlapping write sets or mixed phase scope
89
-
90
- If git/worktree truth materially disagrees with checkpoint narrative truth:
91
- - record a mismatch flag
92
- - keep ordinary git risk warning-level by default
93
- - require explicit user acknowledgement before routing onward
94
- - do not allow a quick "continue" shortcut to skip that acknowledgement
95
- </provenance_reconciliation>
117
+ Material mismatch signals include:
118
+ - checkpoint narrative describes only a narrow slice of a broader dirty tree
119
+ - current branch is stale/spent relative to the next intended integration surface
120
+ - dirty files suggest overlapping write sets or mixed phase scope
121
+ - `CHANGE.md` names a different branch / integration surface than the current git branch
122
+ - dirty files fall outside the active brownfield write scope declared in `CHANGE.md`
123
+
124
+ If git/worktree truth materially disagrees with checkpoint narrative truth:
125
+ - record a mismatch flag
126
+ - keep ordinary git risk warning-level by default
127
+ - require explicit user acknowledgement before routing onward
128
+ - do not allow a quick "continue" shortcut to skip that acknowledgement
129
+
130
+ If git/worktree truth materially disagrees with the active brownfield artifact:
131
+ - keep `CHANGE.md` as the operational anchor
132
+ - surface the mismatch explicitly
133
+ - require acknowledgement before continuing the brownfield change from this workflow
134
+ - keep ordinary git warnings separate from this stronger continuity gate
135
+ - When a checkpoint also exists, let that checkpoint outrank the brownfield anchor only if a strict-match rule proves it is still the active execution surface:
136
+ - branch alignment: checkpoint branch, `CHANGE.md` integration surface, and current git branch all match
137
+ - scope alignment: the live dirty tree stays inside the declared brownfield write scope
138
+ - still-active execution state: the checkpoint still points at unfinished `phase` or `quick` work
139
+ - If any one of those checks fails, keep the checkpoint visible but do not let it become the primary resume target.
140
+ </provenance_reconciliation>
96
141
 
97
142
  <validate_checkpoint>
98
143
  Only run this step when `.planning/.continue-here.md` was found in `<load_artifacts>`. If no checkpoint exists, skip this step entirely.
@@ -126,21 +171,45 @@ The output of this step is either:
126
171
  Present a compact status to the user:
127
172
 
128
173
  ```
129
- Project: [name from SPEC.md]
130
- Phase: [current] of [total] — [phase name]
131
- Completed: [N] phases done
132
-
133
- [If .continue-here.md exists:]
134
- [If stale checkpoint flag set:]
135
- Stale checkpoint detected
174
+ Project: [name from SPEC.md]
175
+ Phase: [current] of [total] — [phase name]
176
+ Completed: [N] phases done
177
+
178
+ [If an active brownfield change exists:]
179
+ Active brownfield change: [title]
180
+ Status: [current posture]
181
+ Integration surface: [branch / integration surface from CHANGE.md]
182
+ Next action: [next action from CHANGE.md]
183
+ Judgment source: `HANDOFF.md` explains constraints/posture but does not override the operational state in `CHANGE.md`
184
+ Growth boundary: stay in the bounded lane unless the work now needs multiple active streams, milestone-owned lifecycle state, or broader requirement tracking
185
+
186
+ [If `HANDOFF.md` exists for the active brownfield change:]
187
+ Brownfield judgment:
188
+ Constraints:
189
+ [Full content of Active Constraints]
190
+ Uncertainty:
191
+ [Full content of Unresolved Uncertainty]
192
+ Posture:
193
+ [Full content of Decision Posture]
194
+ Anti-regression:
195
+ [Full content of Anti-Regression]
196
+
197
+ [If .continue-here.md exists:]
198
+ [If stale checkpoint flag set:]
199
+ ⚠ Stale checkpoint detected
136
200
  Reason: [specific staleness reason]
137
201
  Review the checkpoint contents below and decide whether to resume from it or continue without it.
138
202
 
139
- Checkpoint found: [workflow type] — [phase name or task description]
140
- Last paused: [timestamp from frontmatter]
141
- Paused by: [runtime from checkpoint, or unknown if field absent]
142
- Resuming in: [inferred current runtime]
143
- Next action: [next_action section content]
203
+ Checkpoint found: [workflow type] — [phase name or task description]
204
+ Last paused: [timestamp from frontmatter]
205
+ Paused by: [runtime from checkpoint, or unknown if field absent]
206
+ Resuming in: [inferred current runtime]
207
+ Next action: [next_action section content]
208
+
209
+ [If an active brownfield change also exists and the checkpoint fails the strict-match rule:]
210
+ Checkpoint note:
211
+ This checkpoint no longer cleanly matches the active brownfield execution surface.
212
+ Keep it reviewable, but do not treat it as the primary resume target unless the user explicitly chooses it.
144
213
 
145
214
  [If <judgment> was present in checkpoint:]
146
215
  Judgment context:
@@ -163,10 +232,15 @@ Git/worktree truth:
163
232
  PR: [open|closed|merged|none|unknown]
164
233
  Integration surface: [clean | warning | stale/spent | mixed-scope]
165
234
 
166
- [If material checkpoint/worktree mismatch flag set:]
167
- ⚠ Checkpoint/worktree mismatch
168
- The checkpoint narrative no longer matches the live branch/worktree scope.
169
- Review both truth surfaces before choosing the next action.
235
+ [If material checkpoint/worktree mismatch flag set:]
236
+ ⚠ Checkpoint/worktree mismatch
237
+ The checkpoint narrative no longer matches the live branch/worktree scope.
238
+ Review both truth surfaces before choosing the next action.
239
+
240
+ [If material brownfield artifact/worktree mismatch flag set:]
241
+ ⚠ Brownfield continuity mismatch
242
+ `CHANGE.md` no longer cleanly matches the live branch/worktree truth.
243
+ Review `CHANGE.md`, `HANDOFF.md`, and the dirty tree before choosing the next action.
170
244
 
171
245
  [If incomplete phase execution found:]
172
246
  Incomplete execution: Phase [N] has a PLAN but no SUMMARY
@@ -183,18 +257,29 @@ Only show the staleness banner when `<validate_checkpoint>` produced a staleness
183
257
  <determine_action>
184
258
  Evaluate in priority order and present the primary recommendation:
185
259
 
186
- **Checkpoint exists (`.continue-here.md`):**
187
- Route based on the `workflow` frontmatter:
188
- - `phase` — route to `/gsdd-execute` (or `/gsdd-plan`/`/gsdd-verify` based on checkpoint context)
189
- - `quick` — route to `/gsdd-quick` to complete the task
190
- - `generic` — present the next_action and let the user decide
191
-
192
- If `<validate_checkpoint>` marked the checkpoint as stale, keep the same routing logic. The user may still choose to resume from the checkpoint after reviewing the warning. If the user chooses a different path, leave the checkpoint in place and continue without it.
193
-
194
- If `<provenance_reconciliation>` marked a material checkpoint/worktree mismatch, keep the same routing logic but require explicit acknowledgement before continuing. The workflow should not silently route onward from a materially misleading checkpoint narrative.
195
-
196
- **Incomplete plan execution (PLAN without SUMMARY):**
197
- Route to `/gsdd-execute` for that phase.
260
+ **Checkpoint exists (`.continue-here.md`):**
261
+ Route based on the `workflow` frontmatter:
262
+ - `phase` — route to `/gsdd-execute` (or `/gsdd-plan`/`/gsdd-verify` based on checkpoint context)
263
+ - `quick` — route to `/gsdd-quick` to complete the task
264
+ - `generic` — present the checkpoint `next_action` and let the user decide. This workflow still owns checkpoint cleanup only if the user explicitly resumes from that checkpoint, but downstream read-only `progress` routing must treat the surviving generic checkpoint as informational context rather than an automatic blocker.
265
+
266
+ If `<validate_checkpoint>` marked the checkpoint as stale, keep the same routing logic. The user may still choose to resume from the checkpoint after reviewing the warning. If the user chooses a different path, leave the checkpoint in place and continue without it.
267
+
268
+ If `<provenance_reconciliation>` marked a material checkpoint/worktree mismatch, keep the same routing logic but require explicit acknowledgement before continuing. The workflow should not silently route onward from a materially misleading checkpoint narrative.
269
+ If an active brownfield change also exists, apply the same strict-match rule before making a `phase` or `quick` checkpoint primary. A checkpoint only stays primary when branch alignment, scope alignment, and still-active execution state all hold at once. Otherwise, keep the checkpoint visible and user-selectable, but fall through to the active brownfield change as the default resume target.
270
+
271
+ **Active brownfield change (`.planning/brownfield-change/CHANGE.md`):**
272
+ If there is no checkpoint, or if the surviving checkpoint does not satisfy the strict-match rule against the active brownfield change:
273
+ - present the `CHANGE.md` next action as the primary resume target
274
+ - keep `HANDOFF.md` as supporting judgment context only
275
+ - if artifact/worktree mismatch is material, require explicit acknowledgement before continuing
276
+ - if the user does not want to continue immediately, let them review `CHANGE.md` or `HANDOFF.md` without deleting any checkpoint file
277
+ - do not force this state back through `/gsdd-new-project` or milestone routing just because there is no active roadmap
278
+ - keep `/gsdd-new-project` and `/gsdd-new-milestone` as explicit widen-only choices when the bounded change no longer fits one active stream or now needs milestone-owned lifecycle state
279
+ - use `/gsdd-new-project` for first-milestone setup and `/gsdd-new-milestone` when the repo already has shipped milestone history
280
+
281
+ **Incomplete plan execution (PLAN without SUMMARY):**
282
+ Route to `/gsdd-execute` for that phase.
198
283
 
199
284
  **Phase needs planning (next `[ ]` phase, no PLAN file exists):**
200
285
  Route to `/gsdd-plan` for that phase.
@@ -212,24 +297,26 @@ Present a numbered list of actions based on the state analysis:
212
297
  ```
213
298
  What would you like to do?
214
299
 
215
- 1. [Primary action from above] (recommended)
216
- 2. [Secondary action if applicable]
217
- 3. Review ROADMAP.md
218
- 4. Something else
219
- ```
220
-
221
- **Quick-resume shortcut:** If there is no stale-checkpoint banner and no material checkpoint/worktree mismatch, the user may say "continue", "go", or "resume" without further input to execute the primary action directly.
222
-
223
- **Mismatch acknowledgement:** If material checkpoint/worktree mismatch was detected, require an explicit acknowledgement such as "continue despite mismatch" or a different selected path. Do not let a bare "continue" skip the warning.
224
-
225
- Wait for user selection.
226
- </present_options>
300
+ 1. [Primary action from above] (recommended)
301
+ 2. [Secondary action if applicable]
302
+ 3. Review ROADMAP.md
303
+ 4. Something else
304
+ ```
305
+
306
+ When the primary action is an active brownfield change rather than a checkpoint or lifecycle workflow, replace option 3 with `Review CHANGE.md or HANDOFF.md` if there is no active roadmap to inspect.
307
+
308
+ **Quick-resume shortcut:** If there is no stale-checkpoint banner and no material checkpoint/worktree mismatch, the user may say "continue", "go", or "resume" without further input to execute the primary action directly.
309
+
310
+ **Mismatch acknowledgement:** If material checkpoint/worktree mismatch or material brownfield artifact/worktree mismatch was detected, require an explicit acknowledgement such as "continue despite mismatch" or a different selected path. Do not let a bare "continue" skip the warning.
311
+
312
+ Wait for user selection.
313
+ </present_options>
227
314
 
228
315
  <cleanup_checkpoint>
229
316
  Immediately after the user confirms their action selection (before routing to the target workflow):
230
317
  - If the user chose to resume from `.continue-here.md`:
231
- 1. Run `gsdd file-op copy .planning/.continue-here.md .planning/.continue-here.bak`.
232
- 2. After the copy succeeds, run `gsdd file-op delete .planning/.continue-here.md`.
318
+ 1. Run `node .planning/bin/gsdd.mjs file-op copy .planning/.continue-here.md .planning/.continue-here.bak`.
319
+ 2. After the copy succeeds, run `node .planning/bin/gsdd.mjs file-op delete .planning/.continue-here.md`.
233
320
  - If the user chose a different action (not based on the checkpoint), leave `.continue-here.md` in place for a future resume.
234
321
 
235
322
  Copying before deleting ensures the checkpoint survives a session crash between deletion and dispatch. `.continue-here.bak` is cleaned up by the downstream workflow after absorbing the judgment, or by the next `pause.md` run.