@boopkit/cap-workflows 0.2.2 → 0.2.4

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/capability.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "workflows",
3
- "description": "Reusable end-to-end development and writing workflows",
3
+ "description": "Reusable end-to-end development and audit workflows for code",
4
4
  "type": "development",
5
5
  "package": "@boopkit/cap-workflows",
6
6
  "dependencies": [],
@@ -11,11 +11,28 @@
11
11
  "boop-light-dev-workflow",
12
12
  "boop-refactor-dev-workflow",
13
13
  "boop-test-audit-workflow",
14
- "boop-architecture-audit-workflow",
15
- "boop-issue-sweep-workflow",
16
- "boop-website-dev-workflow",
17
- "boop-design-handoff-workflow",
18
- "boop-knowledge-backfill",
19
- "boop-stray-disposition"
20
- ]
14
+ "boop-architecture-audit-workflow"
15
+ ],
16
+ "file_moves": {
17
+ "skills/boop-website-dev-workflow/": {
18
+ "capability": "web",
19
+ "path": "skills/boop-web-website-dev-workflow/"
20
+ },
21
+ "skills/boop-design-handoff-workflow/": {
22
+ "capability": "web",
23
+ "path": "skills/boop-web-design-handoff-workflow/"
24
+ },
25
+ "skills/boop-issue-sweep-workflow/": {
26
+ "capability": "project-mgmt",
27
+ "path": "skills/boop-project-mgmt-issue-sweep-workflow/"
28
+ },
29
+ "skills/boop-stray-disposition/": {
30
+ "capability": "project-mgmt",
31
+ "path": "skills/boop-project-mgmt-stray-disposition/"
32
+ },
33
+ "skills/boop-knowledge-backfill/": {
34
+ "capability": "product-design",
35
+ "path": "skills/boop-product-design-knowledge-backfill/"
36
+ }
37
+ }
21
38
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@boopkit/cap-workflows",
3
- "version": "0.2.2",
4
- "description": "Reusable end-to-end development and writing workflows for AI agents",
3
+ "version": "0.2.4",
4
+ "description": "Reusable end-to-end code development and audit workflows for AI agents",
5
5
  "files": [
6
6
  "skills/",
7
7
  "capability.json"
@@ -137,16 +137,16 @@ For the work that is genuinely new:
137
137
  - **One child per structural change, not one per call site.** Enumerate-and-patch is the failure that [`boop-refactor-dev-workflow`](../boop-refactor-dev-workflow/SKILL.md) exists to prevent, and it starts at decomposition time.
138
138
  - **Carry the method on every child.** Each child must state the go-red discipline explicitly: delete the old shape first, commit the red build, follow the compiler. An agent picking up "split this interface" without that instruction will keep the build green by leaving a fallback, which is the exact failure this is meant to prevent.
139
139
  - **Carry the named change too**, so the executor can tell a finished refactor from a rearranged one.
140
- - **Name the skills on every child, and name only their names.** Step 8 says each child runs under [`boop-refactor-dev-workflow`](../boop-refactor-dev-workflow/SKILL.md) — but the executing session never reads this workflow, only the issue body, so that pointer reaches it exactly when the child says so and never otherwise. Put `boop-refactor-dev-workflow` on every child, plus the skill for the layer the structural change touches (services, controllers, data model, view) and `boop-testing-testing` for the real-path proof. Names, not extracts: the go-red method in the bullet above is copied deliberately, because a fallback that survives into the branch cannot be corrected afterwards, and that is the one exception. Everything else stays in its skill so there is a single copy to keep current.
140
+ - **Name the skills on every child, and name only their names.** Step 8 says each child runs under [`boop-refactor-dev-workflow`](../boop-refactor-dev-workflow/SKILL.md) — but the executing session never reads this workflow, only the issue body, so that pointer reaches it exactly when the child says so and never otherwise. Put `boop-refactor-dev-workflow` on every child, plus the skill for the layer the structural change touches (services, controllers, data model, view) and `boop-testing-testing` for the real-path proof. Write them as the skills list that `boop-project-mgmt-beads-planning` sets out in its section "Breadcrumb the skills that carry the discipline": a `## Skills` heading, the line "Before making changes, read each of these in full.", and a path to each skill's `SKILL.md`, because a session opens a skill named only in a bare list of names about one time in seven. Names, not extracts: the go-red method in the bullet above is copied deliberately, because a fallback that survives into the branch cannot be corrected afterwards, and that is the one exception. Everything else stays in its skill so there is a single copy to keep current.
141
141
  - **Settle open decisions before the work starts, not during.** A choice like which validation library, or where a declaration lives, belongs in the issue body marked as decided, with the reasoning. An executor who has to pick one mid-implementation will pick silently.
142
142
  - **Include a review child** that checks each change against its named change, not merely that the issue closed.
143
143
  - **Put the test run scope on every child.**
144
- The review child above is the one that runs the full suite; every other child runs focused tests plus the project's whole-program static check.
145
- Left unstated, a child that has just changed a widely called function runs the whole suite on its own reasoning, and every sibling pays it again.
146
- The rule and the wording to use are in `boop-project-mgmt-beads-planning`.
144
+ Each child runs the focused tests for what it touches, plus the project's whole-program static check; the full suite runs once per branch, on the review child above.
145
+ Left unstated, a child that has just changed a widely called function runs the whole suite on its own reasoning.
146
+ The rule and the wording to put on each are in the section "Test run scope: what each task runs, and what runs once" in `boop-project-mgmt-beads-planning`.
147
147
  - **Do not create the feature branch.** The loop creates the worktree and its `work/<epic-id>` branch when it takes the first child.
148
148
 
149
- - **Audit the issue bodies before the session ends, then revise them.** Writing an issue and auditing it are separate passes, and doing both at once produces bodies that read well to their author and cost their reader time. Once every child issue exists, re-read them all as the agent who will claim them cold, using the audit pass in `boop-project-mgmt-beads-planning` and the anti-patterns in `boop-writing-technical-prose`, then rewrite whatever the audit finds. Read the tree side by side rather than one issue at a time: a child that says "a sibling issue handles this" without naming it, or a term the container defines and a child then uses bare, is only visible that way.
149
+ - **Audit the issue bodies before the session ends, then revise them.** Writing an issue and auditing it are separate passes, and doing both at once produces bodies that read well to their author and cost their reader time. Once every child exists, re-read them all side by side as the agent who will claim each one cold, following the section "Write, audit and revise in three separate turns" in `boop-project-mgmt-beads-planning`, then rewrite whatever the audit finds. Some faults show only side by side: a child that says "a sibling issue handles this" without naming it, or a term the container defines and a child then uses bare.
150
150
 
151
151
  ### 8. Execute, verify, close out
152
152
 
@@ -183,7 +183,7 @@ The last three are the same problem at different scales, and together they are t
183
183
  | Judge an area's structural health, decide what is worth fixing, and plan it | **this** |
184
184
  | Execute a structural change you have already decided on | [`boop-refactor-dev-workflow`](../boop-refactor-dev-workflow/SKILL.md) |
185
185
  | The tests around the area cannot catch a behaviour change | [`boop-test-audit-workflow`](../boop-test-audit-workflow/SKILL.md) first |
186
- | Clear a noisy backlog of small lingering items in a themed sweep | [`boop-issue-sweep-workflow`](../boop-issue-sweep-workflow/SKILL.md) |
186
+ | Clear a noisy backlog of small lingering items in a themed sweep | `boop-project-mgmt-issue-sweep-workflow` |
187
187
  | Extend an existing system toward a goal, wiring new behaviour from parts that exist | [`boop-light-dev-workflow`](../boop-light-dev-workflow/SKILL.md) |
188
188
  | Find bugs in a diff | `boop-coding-review-changes` |
189
189
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: boop-feature-dev-workflow
3
- description: "When you are tasked with building a feature end-to-end, follow this guidance."
3
+ description: "When you are tasked with building a feature end-to-end, follow this beads-issue-per-step workflow: epic root → understand → plan → decompose → implement → review → punch-list → closeout → reconcile-and-finalize."
4
4
  metadata:
5
5
  category: workflow
6
6
  ---
@@ -20,7 +20,7 @@ When you are tasked with building a feature end-to-end, follow this guidance.
20
20
  > fails. Refactors done to make a feature buildable run first, as their own unit; the feature then
21
21
  > follows on this workflow.
22
22
 
23
- ## Relvant skills
23
+ ## Relevant skills
24
24
 
25
25
  ### Step zero — before claiming any task
26
26
  - `boop-skills-discovery` — when you pick up a non-trivial task, before claiming it: the discovery backstop. An issue's breadcrumbs are the primary way the right skills reach you, but an issue can miss one. Before claiming any task in this workflow, run the discovery sweep so a forgotten breadcrumb does not cost you the discipline that skill carries.
@@ -37,7 +37,7 @@ When you are tasked with building a feature end-to-end, follow this guidance.
37
37
  - `boop-database-data-model` — when you need to design data models.
38
38
  - `boop-web-web-ui-design` — when you need to design web UIs.
39
39
  - `boop-ux-purpose-judgement` — when the feature includes new or substantially modified UI surface: the structural lens. Does each affordance belong, in the right shape, for the right job? Run during Plan against the spec; run during Review against a screenshot of the built page.
40
- - `boop-ux-visual-judgement` — when the feature includes new or substantially modified UI surface: the taste lens (eye-path, register, anatomy, scan-line). Run during Review against a screenshot of the built page; optional during Plan against a nearby existing surface for register calibration only.
40
+ - `boop-ux-visual-judgement` — when the feature includes new or substantially modified UI surface: the taste lens (eye-path, loudness, anatomy, scan-line). Run during Review against a screenshot of the built page; optional during Plan against a nearby existing surface for loudness calibration only.
41
41
 
42
42
 
43
43
  ### Coding
@@ -53,7 +53,7 @@ Read all three for any code-touching task. They cover different layers, and the
53
53
 
54
54
  - `boop-testing-testing` — the foundational testing skill: pairwise producer/consumer contracts, integration vs. unit decisions, mock boundaries, data-driven config coverage. Read this **before** picking a test shape; it tells you which shape the change actually needs.
55
55
  - `boop-testing-tdd-light` — the Light TDD cycle: the Red / Green / Verify loop applied to features and bug fixes.
56
- - `boop-testing-testing-express-web` — the domain-specific test skill for services, controllers, middleware, and route tests in the Express stack.
56
+ - `boop-web-testing` — the domain-specific test skill for services, controllers, middleware, and route tests in the Express stack.
57
57
 
58
58
  ### Documentation
59
59
  - `boop-product-design-feature-documentation` — when you need to write feature documentation.
@@ -71,6 +71,15 @@ Documents are organized into
71
71
 
72
72
  The loop runs without a live operator. The patterns below follow from that and apply to every task in the workflow.
73
73
 
74
+ ### Keep working until the Done-when is true
75
+
76
+ A task is finished when every one of its Done-when conditions holds, checked against the artifact the condition names: the call site in the code, the archived spec, the rendered page.
77
+ "I performed the listed steps" and "the tests are green" are the two weaker stopping points an agent drifts to, and neither is the bar.
78
+ If a condition cannot be met, register the wait as the "Waiting protocol" below says, with a blocking edge or a human gate, rather than closing on partial work.
79
+
80
+ This is the same discipline Review applies afterwards, when it verifies each closed slice against its Done-when by name (step 4).
81
+ Review is the second net, not the only one.
82
+
74
83
  ### Respect safety mechanisms; do not override them
75
84
 
76
85
  Tools sometimes expose safety mechanisms for destructive operations. Examples include consent environment variables like `PRISMA_USER_CONSENT_FOR_DANGEROUS_AI_ACTION`, a required `--force` flag, an interactive "are you sure?" prompt, or a warning that the command emits before it runs. These mechanisms exist because the action behind them was deemed to require explicit human approval before it could be considered safe to run.
@@ -113,7 +122,7 @@ You leave `bd ready` because of the edge, and you return to it automatically whe
113
122
  Two constraints, both easy to get wrong:
114
123
 
115
124
  - **The edge must point at a sibling or an unrelated issue — never at your own ancestor or your own descendant.** An unresolved edge on a parent holds *every* descendant out of `bd ready` at every depth, so gating a container on its own children deadlocks those children. (bd rejects ancestor/descendant gating edges outright.)
116
- - **Use `blocks`, not `waits-for`.** In bd 1.1.2 `waits-for` is not even a valid `bd dep add -t` type (valid types are `blocks|tracks|related|parent-child|discovered-from|until|caused-by|validates|relates-to|supersedes`); and where `waits-for` does exist it releases when the *first* child of its target closes, not all of them — unsafe against any container with more than one child. Use `blocks`, one edge per thing waited on.
125
+ - **Use `blocks`, not `waits-for`.** In bd 1.1.2 a `waits-for` edge added with `bd dep add -t waits-for` releases when the *first* child of its target closes, not all of them — unsafe against any container with more than one child. (`bd dep add --help` does not list `waits-for`, but bd accepts it, as it accepts any string after `-t`; see `boop-project-mgmt-beads-planning` for the measured types.) Use `blocks`, one edge per thing waited on.
117
126
 
118
127
  **Waiting on a human decision** — a build-or-defer call, a safety mechanism that needs operator consent, a spec ambiguity only the operator can resolve. Create a **human gate** and stay `open`:
119
128
 
@@ -164,8 +173,8 @@ Create tasks as child issues of the feature issue. The descriptions below are th
164
173
  2. **Plan the work**: Next task (don't *do* this work, this is the content of the task issue): **Start by reading `specs/{feature-name}-plan-findings.md`** from the "understand" task (path is in this task's breadcrumbs; also check `bd show <predecessor-id>` notes). The findings contain gap analysis and open questions that must inform the plan. Then find the feature implementation plan document, or create one in `specs/`. Follow the engineering planning skill. Ensure the plan covers the spec; create follow-up tasks for any gaps.
165
174
 
166
175
  **UX paired-lens pass (when the feature includes new or substantially modified UI surface):** If the spec touches the app's UI surface, run a paired-lens pass during planning so the plan and downstream punch-list carry explicit UI work and acceptance criteria. The two cases are not symmetric:
167
- - **Brand-new surface (the page does not exist yet):** run `boop-ux-purpose-judgement` against the spec, reference docs, and any existing nearby templates that anchor the register. **Do not try to screenshot a not-yet-built surface** — the purpose lens has an explicit fallback for missing inputs; use it and label each finding by which inputs supported it. The output validates the spec's interaction-shapes table: each affordance traced to a job, mechanism matched against frequency × consequence, anything underspecified flagged as a plan or punch-list candidate. Optionally run `boop-ux-visual-judgement` against a nearby existing surface for **register calibration only** (output is "the calm/loud target the new surface should match," not findings about the unbuilt page); skip it if no nearby surface is a useful anchor.
168
- - **Modified existing surface (the page exists and is being changed):** capture a screenshot of the current surface with the capture script cap-ux ships (`scripts/ux-eval-capture.ts`), then run both lenses in order — purpose first, visual second.
176
+ - **Brand-new surface (the page does not exist yet):** run `boop-ux-purpose-judgement` against the spec, reference docs, and any existing nearby templates that anchor how loud the surface should be. **Do not try to screenshot a not-yet-built surface** — the purpose lens has an explicit fallback for missing inputs; use it and label each finding by which inputs supported it. The output validates the spec's interaction-shapes table: each affordance traced to a job, mechanism matched against frequency × consequence, anything underspecified flagged as a plan or punch-list candidate. Optionally run `boop-ux-visual-judgement` against a nearby existing surface for **loudness calibration only** (output is "the calm/loud target the new surface should match," not findings about the unbuilt page); skip it if no nearby surface is a useful anchor.
177
+ - **Modified existing surface (the page exists and is being changed):** capture a screenshot of the current surface with `npm run ux:capture -- <path> <label>`, then run both lenses in order — purpose first, visual second.
169
178
  Write the lens findings into the same `specs/{feature-name}-plan-findings.md`, labelling each with the lens that produced it (`[purpose]` or `[visual]`) and noting which inputs were loaded.
170
179
 
171
180
  3. **Decompose the plan**: Next task (don't *do* this work, this is the content of the task issue): **Start by reading the engineering plan** at `specs/{feature-name}-plan.md` (confirm path from this task's breadcrumbs). Break it down into a "do the work" **container** — a `feature`-typed organiser, never a task — holding smaller, manageable `task` children, following the `boop-project-mgmt-beads-planning` skill for the issue mechanics (hierarchy, dependencies, breadcrumb links). Create the feature branch `work/<feature-issue-id>` (e.g. `work/boop-arc.14`) — branch names MUST use the `work/` prefix + issue ID, never feature names like `email-capability`. All sub-tasks work within this branch.
@@ -173,11 +182,24 @@ Create tasks as child issues of the feature issue. The descriptions below are th
173
182
  **Every code-touching sub-task carries a `Tests` section and testing breadcrumbs.** This is how the workflow produces tasks that get tested correctly — author it when you write the sub-task, not later. Each sub-task that creates or changes code must include in its description:
174
183
  - A **`Tests`** section naming: (a) the contracts the task creates or modifies — if it writes a function other code calls, or is itself a new caller of an existing function, name that producer/consumer boundary explicitly (e.g. *"this task calls `buildXyz`; exercise the caller's actual argument shape pairwise, not just the function's contract in isolation"*); (b) the test shapes required at this scope — unit for pure helpers, pairwise component where two pieces of code share a boundary, integration where data crosses a real boundary (DB, HTTP, serialization), route/render for surfaces; (c) any test scope deliberately deferred, with why. A `Tests` section that only says "tests pass" gives the implementing agent no signal about which shape the work needs, and the easy default (a unit test on whatever was written) misses contract bugs.
175
184
  - **Breadcrumbs to the design/layer skill** for the code being written (controller, service, data-access, view) **and to all three testing skills** (general principles, Light TDD, the domain testing skill — see the Testing section above). The general-principles skill is the one most often dropped because a task "feels like just unit-testing" — which is exactly when pairwise contract tests get missed. List all three by default; drop one only if it is genuinely irrelevant.
185
+ A child's session starts cold and sees only its issue; it does not read this workflow.
186
+ Write them as the skills list that `boop-project-mgmt-beads-planning` sets out in its section "Breadcrumb the skills that carry the discipline": a `## Skills` heading, the line "Before making changes, read each of these in full.", and a path to each skill's `SKILL.md`.
187
+ Names, not extracts: a command or checklist copied out of a skill into an issue is a second copy of the method, and it drifts out of step with the skill.
176
188
  - **The test run scope.**
177
- Name what the sub-task runs before it calls itself done: the focused tests for the files it touches, plus the project's whole-program static check, and an explicit instruction not to run the full suite.
178
- The full suite runs once per branch, on the Review task in step 4 — give Review that scope when you create it below.
179
- Left off, every sub-task runs the whole suite on its own reasoning and the branch pays for it once per slice.
180
- The wording to put on each is in the `boop-project-mgmt-beads-planning` skill.
189
+ Each sub-task runs the focused tests for what it touches, plus the project's whole-program static check; the full suite runs once per branch, on the Review task in step 4, so give Review that scope when you create it below.
190
+ Left unstated, a sub-task that has just changed a widely called function runs the whole suite on its own reasoning.
191
+ The rule and the wording to put on each are in the section "Test run scope: what each task runs, and what runs once" in `boop-project-mgmt-beads-planning`.
192
+ - **The live checks, scoped the way the tests are.**
193
+ A live check starts a running system and watches its real behaviour, such as an end-to-end run or a browser pass over a changed page, and each run costs minutes.
194
+ Beside its run scope, each slice names the live checks that exercise what it changed, and runs only those.
195
+ The complete set runs once, at Review, against the complete branch.
196
+ A spec that asks for each stage to be verified before the next starts is satisfied by each slice's own checks plus that one complete run.
197
+ Rerun the whole set at a stage boundary only when the spec gives a reason that stage needs it, such as a stage that ships on its own.
198
+
199
+ **Audit the child issue bodies, then revise them, before this task closes.**
200
+ Writing an issue and auditing it are separate passes, and doing both at once produces bodies that read well to their author and cost their reader time.
201
+ Once every child exists, re-read them all side by side as the agent who will claim each one cold, following the section "Write, audit and revise in three separate turns" in `boop-project-mgmt-beads-planning`, then rewrite whatever the audit finds.
202
+ Some faults show only side by side: a child that says "a sibling issue handles this" without naming it, or a term the container defines and a child then uses bare.
181
203
 
182
204
  **THE TREE RECIPE — verified on bd 1.1.2.** Wire it exactly this way. The whole lifecycle was driven through a simulated loop against this shape, including a slice that decomposed itself mid-flight, and at every step the loop claimed exactly one correct issue: no leak, no deadlock, no stall.
183
205
 
@@ -225,7 +247,7 @@ Create tasks as child issues of the feature issue. The descriptions below are th
225
247
  bd dep add <reconcile-id> <closeout-id>
226
248
  ```
227
249
 
228
- **Every edge is plain `blocks`. Never `waits-for`** — in bd 1.1.2 `waits-for` is not a valid `bd dep add -t` type, and where it does exist it releases when the *first* child of its target closes, not all of them, contradicting its own documentation. See the Waiting protocol.
250
+ **Every edge is plain `blocks`. Never `waits-for`** — in bd 1.1.2 a `waits-for` edge added with `bd dep add` releases when the *first* child of its target closes, not all of them. See the Waiting protocol.
229
251
 
230
252
  > **There is no rollup-gate leaf any more, and adding one back is a regression.** Earlier versions of this recipe created a childless "all slices complete" marker task for Review to depend on. It existed only because bd refuses gating edges to or from an **epic**, so an epic container could not be depended on directly. That restriction applies to **epics alone** — `task blocks-on feature` and `feature blocks-on task` are both **accepted**. Review can simply block on the slices. The gate was an extra node, an extra agent turn, and an extra thing to forget to close.
231
253
 
@@ -262,15 +284,15 @@ Create tasks as child issues of the feature issue. The descriptions below are th
262
284
  - **It is the last link in one chain, so it cannot fire early.** Every lifecycle task is blocked-by the previous one, and Review is blocked-by every slice, so nothing downstream can run against partial work.
263
285
  - **It is a sibling of the work, so it can wait on it without holding it.** Reconcile is a childless leaf child of the *root*, never a parent of any slice — an unresolved edge on a parent holds every descendant, so a gate placed above the work would deadlock it.
264
286
 
265
- 4. **Review the work done**: This task issue must be gated on **slice completion**, not on the Decompose task — Decompose only plans. Step 3 wires this: it removes any stale Review→Decompose dep and makes each slice block Review with a plain `blocks` edge (so Review fires only when *every* slice closes), and deliberately does **not** wire Review `waits-for` the do-the-work container, because `waits-for` releases on the first slice closing and hands Review a partial branch. (If this Review issue was pre-created with a dep on Decompose, step 3 is responsible for rewiring it to slice completion.) This task reviews all changes **in the feature branch** `work/<feature-issue-id>` (confirm with `git branch` or breadcrumbs). Run `bd children <feature-issue-id>` to see what sub-tasks were created and closed, for context on what was implemented.
287
+ 4. **Review the work done**: This task issue must be gated on **slice completion**, not on the Decompose task — Decompose only plans. Step 3 wires this: it removes any stale Review→Decompose dep and makes each slice block Review with a plain `blocks` edge (so Review fires only when *every* slice closes), and deliberately does **not** wire Review `waits-for` the do-the-work container, because `waits-for` releases on the first slice closing and hands Review a partial branch. (If this Review issue was pre-created with a dep on Decompose, step 3 is responsible for rewiring it to slice completion.) This task reviews all changes **in the feature branch** `work/<feature-issue-id>` (confirm with `git branch` or breadcrumbs).
288
+ The slices are the children of the do-the-work container, so list them with `bd children <do-the-work-container-id>`; in the small shape, which has no container, they are the root's children.
289
+ In the epic shape, `bd children <root-id>` returns the container and the lifecycle tasks, not the slices.
266
290
 
267
- **Precondition check before reviewing anything (forbid reviewing a partial branch, recurs):** Review must cover the *whole* feature, not whatever happens to be built. The slice-completion wiring in step 3 is meant to hold Review until every slice closes, but a slice further decomposed at implementation time — or a mis-wired dep — can still let Review go ready against a partial branch. Before reading any code, run both checks:
291
+ **Precondition check before reviewing anything (forbid reviewing a partial branch, recurs):** Review must cover the *whole* feature, not whatever happens to be built. The slice-completion wiring in step 3 is meant to hold Review until every slice closes, but a slice further decomposed at implementation time — or a mis-wired dep — can still let Review go ready against a partial branch. Before reading any code, check the slices: list them as above, and `bd show <id>` on each, including any sub-slice a slice decomposed into during implementation (`bd children <slice-id>` shows them). Confirm **every** slice and sub-slice is `closed`. Any that is `open`, `in_progress`, or itself `blocked` means the branch is partial.
268
292
 
269
- **Check 1 — slices:** `bd children <feature-issue-id>`, and `bd show <id>` on each slice (and on any sub-slice a slice was further decomposed into during implementation). Confirm **every** slice/sub-task is `closed`. Any slice that is `open`, `in_progress`, or itself `blocked` means the branch is partial.
293
+ **Do not check the do-the-work container's own status.** It is an organising issue that nobody claims, and only Reconcile (step 7) closes it, long after Review has run. So on a finished branch the container is still `open`, and that is the healthy state; requiring it to be closed, or adding an edge onto it, would hold Review forever.
270
294
 
271
- **Check 2 — container:** `bd show <do-the-work-container-id>`. If it is `blocked`, the work stopped at a partial state.
272
-
273
- **If either check fails, stop and add a blocking edge for each still-open slice — do NOT scope the review down to the built slices and close, and do NOT set `status=blocked`.** Scoping down is precisely the failure this guard exists to prevent: it lets the largest slice ship with zero review pass. Review is waiting on the remaining slices to close, which happens on its own with no human input, so an edge is the right primitive — it holds Review out of `bd ready` and returns it automatically when the last slice closes (see "Waiting protocol" above). One edge per still-open slice ID from the failing check(s):
295
+ **If any slice is still open, stop and add a blocking edge for each one — do NOT scope the review down to the built slices and close, and do NOT set `status=blocked`.** Scoping down is precisely the failure this guard exists to prevent: it lets the largest slice ship with zero review pass. Review is waiting on the remaining slices to close, which happens on its own with no human input, so an edge is the right primitive — it holds Review out of `bd ready` and returns it automatically when the last slice closes (see "Waiting protocol" above). One edge per still-open slice ID:
274
296
  ```
275
297
  bd dep add <this-review-task-id> <every-open-slice-id> -t blocks
276
298
  bd update <this-review-task-id> --notes "Review cannot run against a partial branch; <which slices are still open, with specific IDs and statuses>. Blocking edges added; this returns to bd ready on its own once they close."
@@ -278,22 +300,39 @@ Create tasks as child issues of the feature issue. The descriptions below are th
278
300
  Review is a **sibling** of the slices, never their parent, so these edges gate Review without holding the slices themselves. Do not review, do not write the review summary, do not file a punch-list, do not close this task. Only once every slice is closed does Review return to `bd ready` and the review below run — against the complete branch.
279
301
 
280
302
  This task will:
303
+ - **Run the full test suite first, before reviewing anything.**
304
+ Every slice ran only its focused tests, so this is the first run that sees the complete branch.
305
+ Run it as one blocking call, as "Run long verification steps BLOCKING" above says, and read the summary rather than the exit code.
306
+ A red suite stops the review and becomes the first punch-list item; do not review code whose tests fail.
307
+ For a test that passes alone and fails in the full run, follow the `boop-testing-testing` skill's section "A suite that passes alone and fails in a full run is a suspect, not a verdict".
308
+ - **Then run each live check the spec's success criteria name, once.** This is the one place they all run together. A failing check becomes a punch-list item.
281
309
  - perform a code review and test review of all changes in the feature branch (use available skills for code review, test review, and any other relevant review skills).
282
- - **Verify each closed slice against its Done-when, by name.** For every closed sub-task (`bd children <feature-issue-id>`, then `bd show <id>` on each), read its Done-when / acceptance conditions and confirm **each condition is actually met on the branch** — not merely that the task is closed. A closed task only means an agent decided it was done; it does not mean the goal was reached. Check the real artifact each condition names: if a condition says a function is wired into a code path, confirm the call site exists in `src/` — not just that a test exercises the function. List any unmet Done-when condition as a punch-list item, citing the slice ID and the specific condition.
310
+ - **Verify each closed slice against its Done-when, by name.** For every closed slice and sub-slice (listed as in the precondition check, then `bd show <id>` on each), read its Done-when / acceptance conditions and confirm **each condition is actually met on the branch** — not merely that the task is closed. A closed task only means an agent decided it was done; it does not mean the goal was reached. Check the real artifact each condition names: if a condition says a function is wired into a code path, confirm the call site exists in `src/` — not just that a test exercises the function. List any unmet Done-when condition as a punch-list item, citing the slice ID and the specific condition.
283
311
  - write the review to `labs/claude-runs/{feature-issue-id}-review-summary.md`.
284
312
  - append a punch-list of issues that must be addressed before merge.
285
313
 
286
314
  **UX paired-lens pass (when the change touched UI files):** if `git diff main...HEAD -- views/ styles/ src/controllers/` shows changes, the surface needs a post-build UX review. The page now exists, so both lenses run normally against it:
287
315
 
288
- 1. Pick a port and confirm it is free before you start anything: `lsof -ti tcp:<port>` prints nothing when the port is free. Then start the dev server in the feature worktree: `PORT=<port> npm --prefix <absolute-worktree-path> run dev` — the `--prefix` form is required; `cd <worktree> && npm run dev` silently falls back to the project root and screenshots the wrong build. If the port is already held, do not kill what is there and do not assume it serves your code — several worktrees and loops can run at once. Identify the holder with `lsof -a -d cwd -p <pid> -Fn` and reuse the server only when that directory is this feature's worktree; otherwise move to the next free port.
289
- 2. Capture each changed surface with `scripts/ux-eval-capture.ts`.
316
+ 1. Pick a port and confirm it is free before you start anything: `lsof -ti tcp:<port> -sTCP:LISTEN` prints nothing when the port is free. Then start the dev server in the feature worktree: `PORT=<port> npm --prefix <absolute-worktree-path> run dev` — the `--prefix` form is required; `cd <worktree> && npm run dev` silently falls back to the project root and screenshots the wrong build. If the port is already held, do not kill what is there and do not assume it serves your code — several worktrees and loops can run at once. Identify the holder with `lsof -a -d cwd -p <pid> -Fn` and reuse the server only when that directory is this feature's worktree; otherwise move to the next free port.
317
+ 2. Capture each changed surface with `npm run ux:capture -- <path> <label>`, passing `BASE_URL=http://localhost:<port>`.
290
318
  3. Run `boop-ux-purpose-judgement` first against the screenshot plus the rendered HTML, template, controller, and route. Run `boop-ux-visual-judgement` second against the screenshot.
291
- 4. Label findings by lens (`[purpose]`, `[visual]`) in `labs/claude-runs/{feature-issue-id}-review-summary.md`, alongside the code-review findings, and feed them into the punch-list the same way code-review findings do.
292
- 5. **Stop the dev server before this task closes**, unless you reused one you found already running. Stop it by port: `lsof -ti tcp:<port> | xargs kill`. Never pattern-kill (`pkill -f nodemon`, `pkill -f tsx`, and the like) — a pattern matches every other worktree's server and the operator's own, and this project routinely has several alive at once. Never stop a server you did not start, including any port a concurrently running loop owns.
319
+ 4. Drive each changed surface against its slices' Done-when, as the section "Verifying a change someone will look at" in `boop-web-testing` describes when the project has the web capability: the lenses judge how the page reads, and that pass confirms a person gets what each issue promised.
320
+ 5. Label findings by lens (`[purpose]`, `[visual]`) in `labs/claude-runs/{feature-issue-id}-review-summary.md`, alongside the code-review findings, and feed them into the punch-list the same way code-review findings do.
321
+ 6. **Stop the dev server before this task closes**, unless you reused one you found already running.
322
+ Stop all of it, not only the process on the port.
323
+ A dev script that watches files runs a supervisor above the server, and only the server holds the port: boop's web-app profile runs `nodemon --exec tsx src/server.ts`, so killing the port holder leaves `nodemon` running while the port reads free, and `nodemon` starts the server again on the next file change.
324
+ Find the supervisor by the worktree's absolute path in its command line, `ps -eo pid=,args= | grep "<absolute-worktree-path>/node_modules/.bin/[n]odemon"`, with the dev script's own watcher in place of `nodemon` if it runs another, and kill that pid; the server under it stops too.
325
+ Then run that search again and `lsof -ti tcp:<port> -sTCP:LISTEN`, and confirm both print nothing, because a free port does not show that the supervisor is gone.
326
+ If the dev script runs no supervisor, the process on the port is the whole server, and `lsof -ti tcp:<port> -sTCP:LISTEN | xargs kill` stops it.
327
+ Never pattern-kill (`pkill -f nodemon`, `pkill -f tsx`, and the like): a pattern reaches every other worktree's server and the operator's own.
328
+ Never stop a server you did not start, or one a running loop owns.
293
329
 
294
330
  **Why the stop belongs in this step, not at Closeout.** This pass runs once per surface-touching task, so a server left behind is not one stray process but one per surface. Deferring teardown to a distant Closeout is how orphaned watchers accumulate — each holding memory, none listening, none visible unless someone goes looking. The phase that starts a process is the phase that has to stop it.
295
331
 
296
332
  5. **Add a punch-list work task**: Create a 'punch list' task issue as a child of the feature issue. Its goal: turn each item in the punch-list from the review document into a sub-task issue under this punch-list task.
333
+ **Those sub-tasks are built in the same run, before Closeout.**
334
+ Filing them is this task's job; the loop then picks each one up as ready work, and the edges below hold Closeout until every one has closed.
335
+ A run that files a punch list and stops has not finished the feature: it leaves the review's findings unaddressed on the branch the operator is asked to merge.
297
336
 
298
337
  **Hierarchy rule:** Create punch-list items with `--parent <punch-list-task-id>` so they are true hierarchical children: `bd create "..." --parent <punch-list-task-id> ...`. `bd dep add` creates sequencing only — it is not a substitute for `--parent`. Sequencing deps between siblings are fine to add after creation.
299
338
 
@@ -301,7 +340,7 @@ Create tasks as child issues of the feature issue. The descriptions below are th
301
340
 
302
341
  **Wire Closeout's dependency carefully (critical, recurs):** Closeout (step 6) must not run until the punch-list task *and all its children* are closed. The default `blocks` dep releases as soon as the punch-list task itself closes — which can happen while the just-filed punch-list fix children are still open, so Closeout would archive the spec and integrate reference docs against the *pre-fix* state.
303
342
 
304
- **Use one plain `blocks` edge per thing you are waiting on. Never `waits-for`.** `waits-for` releases as soon as the *first* child of its target closes, not all of them — so with several fix children open, the first one closing would release Closeout against pre-fix state, the exact failure this step exists to prevent (and in bd 1.1.2 `waits-for` is not even a valid `bd dep add -t` type). `blocks` is unambiguous — it resolves only when *that* issue closes — so gating on N issues means N edges. There is no cascade to rely on and none is needed.
343
+ **Use one plain `blocks` edge per thing you are waiting on. Never `waits-for`.** `waits-for` releases as soon as the *first* child of its target closes, not all of them — so with several fix children open, the first one closing would release Closeout against pre-fix state, the exact failure this step exists to prevent (that is how a `waits-for` edge added with `bd dep add` behaves in bd 1.1.2). `blocks` is unambiguous — it resolves only when *that* issue closes — so gating on N issues means N edges. There is no cascade to rely on and none is needed.
305
344
 
306
345
  **Critical order — do these steps IN ORDER, do not close Punch-list until step 4 has been verified:**
307
346
 
@@ -326,17 +365,18 @@ Create tasks as child issues of the feature issue. The descriptions below are th
326
365
 
327
366
  **Precondition check before any closeout activity (defensive layer, recurs):** the activities below — archive the spec, integrate reference docs, close the issues — are procedural, and an agent will walk through them cleanly even when the actual work is not done. The dep-wiring race (see the callout at the end of step 5) can let this task become ready before implementation has run, or before the punch-list fix children have closed. Before taking any closeout activity, run both checks:
328
367
 
329
- **Check 1 — implementation:** `bd show <do-the-work-container-id>` and confirm status is `closed`.
368
+ **Check 1 — implementation:** list the slices as in step 4's precondition check, and confirm every slice and sub-slice is `closed`.
369
+ Check the slices, not the container: only Reconcile closes the container, and Reconcile is blocked by Closeout, so requiring the container to be closed here, or adding an edge onto it, leaves the two tasks waiting on each other.
330
370
 
331
371
  **Check 2 — punch-list children:** `bd children <punch-list-task-id>` and confirm every child is `closed`. (Even if the punch-list task itself is closed, individual children can still be open — that means the Closeout dep wiring in step 5 was skipped or arrived too late, and the original `blocks` dep released prematurely.)
332
372
 
333
- **If either check fails, stop and add a blocking edge for each still-open issue — do NOT set `status=blocked`.** Closeout is almost always waiting on the implementation container and/or the punch-list children to close, which happens on its own with no human input, so an edge holds it and returns it automatically (see "Waiting protocol" above). Setting the status instead freezes the task even after the cause clears. One edge per still-open issue ID from the failing check(s):
373
+ **If either check fails, stop and add a blocking edge for each still-open issue — do NOT set `status=blocked`.** Closeout is almost always waiting on the remaining slices and/or the punch-list children to close, which happens on its own with no human input, so an edge holds it and returns it automatically (see "Waiting protocol" above). Setting the status instead freezes the task even after the cause clears. One edge per still-open issue ID from the failing check(s), pointed at the open slices and fix children themselves, never at the do-the-work container:
334
374
  ```
335
- bd dep add <this-closeout-task-id> <do-the-work-container-id-if-open> -t blocks
375
+ bd dep add <this-closeout-task-id> <every-open-slice-id> -t blocks
336
376
  bd dep add <this-closeout-task-id> <every-open-punch-list-child-id> -t blocks
337
377
  bd update <this-closeout-task-id> --notes "Closeout cannot run; <check failure summary, including specific issue IDs and statuses>. Blocking edges added; this returns to bd ready on its own once they close."
338
378
  ```
339
- Closeout is a **sibling** of the implementation container and of the punch-list, so these edges gate Closeout without holding any of that work. Never point such an edge at your own ancestor or descendant. (If the wait is instead a genuine operator decision — e.g. the feature cannot proceed without a human call — raise a **human gate** on this Closeout task instead, per the Waiting protocol; it will not auto-release.) Do not archive the spec, do not integrate reference docs, do not commit, do not close bd issues. Closeout returns to `bd ready` on its own once the edges resolve, or when the operator resolves the gate. Do not interpret a subsequent boop resume prompt as authorization to override this — the wait stands until its edges resolve or the operator confirms.
379
+ The slices sit under the container and the fix children under the punch-list, both siblings of Closeout, so these edges gate Closeout without holding any of that work. Never point such an edge at your own ancestor or descendant. (If the wait is instead a genuine operator decision — e.g. the feature cannot proceed without a human call — raise a **human gate** on this Closeout task instead, per the Waiting protocol; it will not auto-release.) Do not archive the spec, do not integrate reference docs, do not commit, do not close bd issues. Closeout returns to `bd ready` on its own once the edges resolve, or when the operator resolves the gate. Do not interpret a subsequent boop resume prompt as authorization to override this — the wait stands until its edges resolve or the operator confirms.
340
380
 
341
381
  When (and only when) the checks pass, the closeout task performs two activities:
342
382
 
@@ -347,10 +387,14 @@ Create tasks as child issues of the feature issue. The descriptions below are th
347
387
  - The archived spec and planning artifacts should be the full originals — do not edit or trim them.
348
388
 
349
389
  **b. Integrate into reference:**
350
- - Follow the `boop-product-design-reference-integration` skill to blend the new feature's knowledge into existing `reference/` pages.
351
- - This is NOT "create a new page for the feature" — it's merging knowledge into the existing concept pages (and creating new concept pages only when a genuinely new concept has no home).
390
+ - Follow the `boop-product-design-reference-integration` skill. Its goal is that a reader with a question about one subject finds one page whose title names that subject; name the subjects from what actually shipped, and let the skill decide where each one goes.
391
+ Pages named in this task's description are where to start, not the limit.
392
+ - **Write this task's description as what was learned, not as pages to edit.** When you create the Closeout task, list the knowledge the feature produced: what now exists, what changed, and what was decided. Do not list the reference pages to update. A page list written before the work can only name pages that already existed, and the session that runs Closeout tends to treat it as the whole job, which is how a subject the feature created ends up buried in a page about something else.
352
393
  - Update cross-links between affected reference pages.
353
394
  - Remove or update any reference content that is now outdated.
395
+ - **Then decide, explicitly, whether the feature changed what a customer could truthfully be told.**
396
+ If the project keeps a capability catalog and the answer is yes, update it against the rule in the reference-integration skill's section "A capability catalog, if the project keeps one".
397
+ Otherwise record "no product-facing change" in the closing comment.
354
398
 
355
399
  **c. Hand off — the loop ends at the feature branch:**
356
400
 
@@ -372,21 +416,23 @@ Create tasks as child issues of the feature issue. The descriptions below are th
372
416
 
373
417
  **Step 1 — sweep the tree and branch.** Enumerate every descendant of the root (`bd children <root-id>`, recursing into containers) and read each one's status. Branch on what you find:
374
418
 
419
+ **An open container is not work in flight.** An open `epic` or `feature` that has children is an organising container, and only Step 2 below closes it, so judge it by its children, never by its own status. An unfinished slice still means a wait, pointed at the slice; an edge onto the container would wait for this task to close it, which never happens.
420
+
375
421
  - **A descendant genuinely needs a human** (an operator decision, a safety mechanism awaiting consent). The feature is **not** done. Raise a **human gate** on *this* Reconcile task naming the held IDs, and stop:
376
422
  ```
377
423
  bd gate create --type=human --blocks <reconcile-task-id> \
378
424
  --reason="Cannot finalize; descendants <held issue IDs> need an operator decision. <summary>."
379
425
  ```
380
426
 
381
- - **Real work is still in flight** (any descendant `open` or `in_progress`). Add a blocking edge onto each in-flight ID, and stop. Reconcile returns to `bd ready` on its own once they close — no monitoring pass required:
427
+ - **Real work is still in flight** (any descendant other than an organising container is `open` or `in_progress`). Add a blocking edge onto each in-flight ID, and stop. Reconcile returns to `bd ready` on its own once they close — no monitoring pass required:
382
428
  ```
383
429
  bd dep add <reconcile-task-id> <each-in-flight-id> -t blocks
384
430
  ```
385
431
  Reconcile is a childless leaf **child of the root**, and the in-flight work sits under the do-the-work container, so these edges point at issues that are neither its ancestors nor its descendants — which is what keeps them from deadlocking the work they wait on.
386
432
 
387
- - **Every descendant is closed.** Proceed to Step 2.
433
+ - **Every descendant is closed, apart from the organising containers.** Proceed to Step 2, which closes them.
388
434
 
389
- **Step 2 — finalize (only when every descendant is closed).** In order:
435
+ **Step 2 — finalize (only when every descendant but the containers is closed).** In order:
390
436
 
391
437
  1. **Run any un-run Closeout activity.** Confirm Closeout's two knowledge-integration activities actually landed — the spec (and its `-plan.md` / `-plan-findings.md` siblings) moved to `specs/history/`, and the feature's knowledge folded into `reference/`. If Closeout never ran or left either undone, do that work here now per step 6a/6b and the `boop-product-design-reference-integration` skill, then `bd close <closeout-task-id>` if it is still open.
392
438
 
@@ -401,11 +447,13 @@ Create tasks as child issues of the feature issue. The descriptions below are th
401
447
  ```
402
448
  bd close <container-id> # the do-the-work container: a feature, closes freely
403
449
  bd close <reconcile-task-id> # close yourself — you are the last open child of the root
404
- bd epic close-eligible # now every root child is closed, so the epic root closes
450
+ bd close <root-id> # now every root child is closed, so the epic root closes
405
451
  ```
406
452
  For the **small** shape there is no container and the root is a `feature`, so it is just `bd close <reconcile-or-last-task-id>` then `bd close $ROOT`.
407
453
 
408
- **Why this order.** bd **refuses to close an epic that still has an open child** — Reconcile is that open child, so closing the root before yourself simply fails, and if the failure is swallowed the root is left open with every other issue closed. (A `feature`-typed root does allow it, which is why the order looks optional until the root is an epic.) Closing your own bd issue does not end your turn, so running `bd epic close-eligible` afterwards is fine — and it is better than `bd close <root> --force`, which closes the root while leaving Reconcile open.
454
+ **Why this order.** bd **refuses to close an epic that still has an open child** — Reconcile is that open child, so closing the root before yourself simply fails, and if the failure is swallowed the root is left open with every other issue closed. (A `feature`-typed root does allow it, which is why the order looks optional until the root is an epic.) Closing your own bd issue does not end your turn, so closing the root afterwards is fine — and it is better than `bd close <root> --force`, which closes the root while leaving Reconcile open.
455
+
456
+ **Close the root by its id, not with `bd epic close-eligible`.** That command takes no issue id: it closes every epic in the database whose children are all closed, including unrelated ones another effort left eligible.
409
457
 
410
458
  **Do this even though boop has a safety net, because the net does not cover every run.** `closeCompletedFeatureRoot` in `src/commands/loop.ts` closes a root whose children have all closed, and it accepts a `feature` *or* `epic` root — but its call site is guarded by `work && resolvedFlow && prefix`, so it fires **only in spec-driven runs (`--work --flow`)**. An issue-driven `--prefix` run never reaches it. In spec-driven mode your explicit close just makes the net a no-op, which costs nothing.
411
459
 
@@ -56,21 +56,37 @@ If the design fails, redesign now — it is far cheaper here than after an epic'
56
56
  Now swap the "implement" tail of a one-pass flow for a decomposition. In the **same session**, while grounded, emit **one bd epic** (an epic container is claim-safe) with child issues scoped to the actual wiring:
57
57
 
58
58
  - **Ground each child in the real code** — name the files, call sites, conditions, and events from *investigate*. A child issue written by the agent that read the real system is a far less lossy input to its execution session than a spec would be.
59
+ - **Name the skills each child needs, and name only their names.**
60
+ A child issue is the whole briefing its session gets: that session never reads this workflow, and it will not read every skill hunting for the few that matter.
61
+ Put on each child the skills its kind of work uses: the skill for the layer it touches, and all three testing skills — `boop-testing-testing` for which shape of test the change needs, `boop-testing-tdd-light` for the cycle, and the stack's testing skill.
62
+ Write them as the skills list that `boop-project-mgmt-beads-planning` sets out in its section "Breadcrumb the skills that carry the discipline": a `## Skills` heading, the line "Before making changes, read each of these in full.", and a path to each skill's `SKILL.md`.
63
+ Names, not extracts: a command or checklist copied out of a skill into an issue is a second copy of the method, and it drifts out of step with the skill.
64
+ - **Put the test run scope on every child.**
65
+ Each child runs the focused tests for what it touches, plus the project's whole-program static check; the full suite runs once per branch, on the review child that completes it.
66
+ Left unstated, a child that has just changed a widely called function runs the whole suite on its own reasoning.
67
+ The rule and the wording to put on each are in the section "Test run scope: what each task runs, and what runs once" in `boop-project-mgmt-beads-planning`.
59
68
  - **Keep it proportional.** The epic is the real work plus its safety tasks — not a regrown four-session front half or a reflexive 13-issue tree. But it does need to *be* an epic: this workflow's floor is a change that genuinely decomposes into several grounded children. If the work is a one-line edit that needs no decomposition, you are in the wrong workflow — file a plain bd issue or just make the change; do not spin up this flow for it.
60
69
  - **Size children to a session, not to a step.** A child issue is the unit a session picks up, and every session boundary is a cold start: the next agent re-reads the surface, re-derives the pattern, and re-runs the gates before it changes a character. So never split work that one session could carry. Group related small changes — a set of copy fixes on one template, several style corrections in one stylesheet — into a single child, and keep grouping until that child would take a session past roughly **50%** context. A one-line text change must never be its own child issue; that is a full session spent on a cold start to earn one line of diff.
61
70
  - **Include a review task and a punch-list** as children — the relocated safety net. For engine/back-end extensions especially, the review must verify the new wiring is in the **live path** (not tests-only) and handles **every** existing case it touches.
62
71
  - Use `boop-project-mgmt-beads-planning` and `boop-project-mgmt-engineering-planning` to shape the epic.
72
+ - **Audit the child issue bodies before the session ends, then revise them.**
73
+ Writing an issue and auditing it are separate passes, and doing both at once produces bodies that read well to their author and cost their reader time.
74
+ Once every child exists, re-read them all side by side as the agent who will claim each one cold, following the section "Write, audit and revise in three separate turns" in `boop-project-mgmt-beads-planning`, then rewrite whatever the audit finds.
75
+ Some faults show only side by side: a child that says "a sibling issue handles this" without naming it, or a term the epic defines and a child then uses bare.
63
76
  - **Do not create the feature branch yourself.** This decompose step runs in the *launch directory* (the planning phase runs before any worktree exists), so a `git checkout -b work/<epic-id>` here parks the launch dir on the feature branch — which then collides with the executor's `git worktree add` ("already checked out") and, worse, strands a concurrent session's next commit on your feature branch. The executor owns the branch: `boop loop` creates the worktree and its `work/<epic-id>` branch when it picks up the first child. Just create the bd tree and stop.
64
77
 
65
- The loop then picks up each child as its own execution session. That boundary is the context-budget seam, and it is fine *when the child is large enough to need one* — the children are grounded, so a fresh session can execute them. It is pure waste when the child is smaller than the cold start that precedes it, which is what the sizing rule above exists to prevent. It creates the worktree and feature branch itself; the decompose session above must not.
78
+ The loop then picks up each child as its own execution session. That boundary is the context-budget seam, and it is fine *when the child is large enough to need one* — the children are grounded, so a fresh session can execute them. It is pure waste when the child is smaller than the cold start that precedes it, which is what the sizing rule above exists to prevent. The loop creates the worktree and feature branch itself; the decompose session above must not.
66
79
 
67
80
  ### 6. Run the epic — implement, review, punch-list
68
81
  The loop implements each child (`boop-coding-development`, `boop-testing-tdd-light`), then the review and punch-list run against the whole branch (`boop-coding-review-changes`). Do not treat these as leftover process — they are where the independent perspective the single front session lacked actually happens. Verify each child against its goal, not merely that it closed.
69
82
 
70
83
  ### 7. Verify and close out
71
84
  - **Run the real path, not just the suite.** For UI, capture the render and re-critique against it. For back-end, drive the real end-to-end flow against a throwaway environment — a green suite proves structure compiles, not that the goal is served.
72
- - Run the targeted tests for what you touched, and the full suite before closeout.
85
+ - The full suite runs once, on the review child that completes the branch; every other child ran its focused tests and the whole-program static check.
73
86
  - Integrate knowledge into `reference/` (`boop-product-design-reference-integration`) and archive anything the change completed.
87
+ - **Decide whether the change altered what a customer could truthfully be told, and say so in the handoff.**
88
+ If the project keeps a capability catalog and the answer is yes, update it against the catalog rule in `boop-product-design-reference-integration`.
89
+ Otherwise record "no product-facing change", which is the expected answer for most changes rather than a skipped step.
74
90
  - Leave the branch for review. **Do not merge to main** — the human owns the merge.
75
91
 
76
92
  ## Front-end, back-end, full-stack: what "investigate" means
@@ -93,7 +109,7 @@ The trap is symmetric across all three: designing from the summary (the issue, t
93
109
  | Greenfield: a new subsystem, data model, or API driven from a spec | [`boop-feature-dev-workflow`](../boop-feature-dev-workflow/SKILL.md) |
94
110
  | An open-ended "make this page better / find what's wrong" eval that should grow the judgement skill | `boop-ux-eval-and-refine-workflow` |
95
111
  | A page UX delivery campaign with a finding budget and per-finding decomposition | `boop-ux-app-ui-dev-workflow` |
96
- | A noisy backlog of small lingering items to clear in a themed sweep | [`boop-issue-sweep-workflow`](../boop-issue-sweep-workflow/SKILL.md) |
112
+ | A noisy backlog of small lingering items to clear in a themed sweep | `boop-project-mgmt-issue-sweep-workflow` |
97
113
 
98
114
  **Bounded on both ends.** *Above:* if *investigate* or *design* reveals the work is actually greenfield — a genuinely new subsystem, a real data-model design, no existing pattern to extend — it has left this workflow's domain; say so and escalate to `boop-feature-dev-workflow` rather than forcing a redesign through a single grounded session. *Below:* if the change is a one-liner or a lone edit that does not decompose into several grounded issues, it is beneath this workflow — a plain bd issue or a direct fix is the right tool, not an epic.
99
115