From 6ee20d98176b04a68513845feda717c2129f3840 Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Tue, 28 Jul 2026 17:15:16 -0700 Subject: [PATCH] docs(U9): correct merge-stack slice statuses to measured wiring state (#2504) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **U9, PR2.** Docs-only, no changeset (AGENTS.md: internal docs). ## Why All seven slices in `docs/plans/workflow-owned-merge-stack/` were marked `draft-stack-handoff` — accurate when drafted 2026-06-09, wrong now. **A worker picking up this stack cold would have re-implemented S04, which has already landed.** I nearly did. ## Measured, against `main @ 46f35323c` | Slice | Was | Now | Evidence | |---|---|---|---| | S02 projection | draft | `landed-unwired` | `projectMergeRequestToWorkflowWorkItem` implemented, **0 production callers** | | S03 scheduler claim | draft | `landed-unwired` | `claimDueWorkflowWorkItem` implemented; its only caller is S05's processor, itself unwired | | S04 IR regions | draft | **`landed`** | `merge-gate`, `merge-retry`, `manual-merge-hold`, `merge-attempt`, `recovery-router` present in the coding IR | | S05 runtime driver | draft | `landed-unwired` | `runWorkItem` / `processDueWorkflowWorkItem` implemented, exported from `index.ts`, **0 production callers** | | S06/S07/S08 | draft | `not-started` | merge still runs through `merger.ts` + the live `ProjectEngine.mergeQueue` pump | ## The finding that changes U9's sequencing `WorkflowWorkItemKind` is `task | merge | retry | manual-hold | recovery`. The only live pump — `InProcessRuntime.drainWorkflowContinuations` — filters `kinds: ["task"]`. The generic processor that would claim the other four kinds has **no production caller**. So the entire merge-lane work-item vocabulary is dormant: **zero writers, zero readers.** **I checked whether this is a live bug and it is not.** Nothing in production writes a non-`task` kind — the only two writers (`plan-review-continuation.ts`, `workflow-column-boundary-hooks.ts`) both go through `replaceActiveTaskWorkflowContinuation`. Nothing is stranded today. I'd rather say that plainly than let a scary-sounding finding stand unqualified. But it produces a hard ordering constraint, now recorded in S07: > **S07 must not land before S03/S05 are actually driven.** S07 is the slice that starts writing `merge`-kind work items. If it lands first, those items are created and never claimed — a card that reaches the merge boundary and silently stops. This also reframes U9's job on S02/S03/S05: **wire them, don't build them.** ## Scope discipline Docs-only — `git diff --stat` is 9 files, all under `docs/`. No production code, no tests, no behavior. `pnpm lint` clean. I also fixed the three parent-plan lines asserting the slices are "all still `draft-stack-handoff`", and the four landed slices' Stack Role paragraphs that would otherwise contradict their own new Measured State block. Leaving those stale would recreate exactly the defect this PR fixes. Related: #2494 pins the S04 caveat — the IR regions are declared but their config is read by nothing. 🤖 Generated with [Claude Code](https://claude.com/claude-code) ## Summary by CodeRabbit - **Documentation** - Updated workflow-owned merge planning documents with current implementation and wiring statuses. - Added measured wiring details showing which workflow capabilities are active, implemented but unused, or not started. - Clarified sequencing requirements to ensure merge processing is not enabled before prerequisite workflow paths are operational. - Corrected slice metadata and references to reflect the latest measured state. --------- Co-authored-by: Claude Opus 5 (1M context) --- ...-refactor-workflow-owned-lifecycle-plan.md | 6 +- .../s02-merge-request-projection.md | 16 +++-- .../s03-generic-scheduler-claim.md | 16 +++-- .../s04-builtin-ir-regions.md | 16 +++-- .../s05-runtime-work-item-driver.md | 16 +++-- .../s06-git-merge-capabilities.md | 16 +++-- .../s07-completion-handoff-merge-work.md | 16 +++-- .../s08-workflow-owned-merge-processing.md | 16 +++-- docs/workflow-policy-ownership-map.md | 58 +++++++++++++++++++ 9 files changed, 145 insertions(+), 31 deletions(-) diff --git a/docs/plans/2026-07-26-001-refactor-workflow-owned-lifecycle-plan.md b/docs/plans/2026-07-26-001-refactor-workflow-owned-lifecycle-plan.md index 1212e3818b..c39620a0ac 100644 --- a/docs/plans/2026-07-26-001-refactor-workflow-owned-lifecycle-plan.md +++ b/docs/plans/2026-07-26-001-refactor-workflow-owned-lifecycle-plan.md @@ -102,7 +102,7 @@ The durable substrate already exists (`workflow_work_items` with leases and stat Triage discovers and seeds; the executor supplies primitives and node runners; the reviewer and merger expose capabilities. Node behavior moves to runners, policy moves to the IR. The vocabulary for this already exists in `CONCEPTS.md` — Workflow Runtime Primitive, Node Runner, Workflow Service — so this is completing a stated architecture, not inventing one. **KTD-5. Adopt the existing workflow-owned merge design; do not redesign it.** -`docs/plans/2026-06-09-003-refactor-workflow-owned-merge-full-migration-slices-plan.md` (status `active`) already specifies the merge lane's target state and slices it S02–S08 in `docs/plans/workflow-owned-merge-stack/` — all still `draft-stack-handoff`. Its target state ("workflow IR/runtime owns merge policy, retry policy, scheduling policy, recovery routing, and git operation flow; the engine keeps substrate") is exactly this program's R4 for the merge lane. U9 sequences and lands those slices rather than authoring a parallel design. +`docs/plans/2026-06-09-003-refactor-workflow-owned-merge-full-migration-slices-plan.md` (status `active`) already specifies the merge lane's target state and slices it S02–S08 in `docs/plans/workflow-owned-merge-stack/`. **Their statuses were corrected 2026-07-28** after a U9 pre-flight audit: S04 has LANDED, S02/S03/S05 are implemented but have zero production callers, and only S06–S08 are genuinely not started. Its target state ("workflow IR/runtime owns merge policy, retry policy, scheduling policy, recovery routing, and git operation flow; the engine keeps substrate") is exactly this program's R4 for the merge lane. U9 sequences and lands those slices rather than authoring a parallel design. **KTD-6. Delete the parity machinery rather than update it — but only what is provably dead.** `isWorkflowColumnsEnabled` returns a literal `true` with 8 live branches reading it. `workflow-parity.ts` asserts the default workflow's adjacency equals the legacy `VALID_TRANSITIONS`; once the default deliberately diverges, that assertion is not stale — it is wrong, and updating it would re-encode the shape we chose to break. Both are safe deletions. @@ -470,7 +470,7 @@ The measurable goal is that the executor stops deciding *what happens next* — **Files:** `packages/engine/src/merger.ts`, `packages/engine/src/merger-ai.ts`, `packages/engine/src/reviewer.ts`, `packages/engine/src/merge-trait.ts`, `packages/engine/src/auto-merge-finalization.ts`, `packages/engine/src/pr-nodes.ts`, plus the merge/review test suites -**Approach:** Adopt `docs/plans/2026-06-09-003-refactor-workflow-owned-merge-full-migration-slices-plan.md` and its S02–S08 slices (`docs/plans/workflow-owned-merge-stack/`, all `draft-stack-handoff`) rather than authoring a parallel design (KTD-5). Sequence them behind U8 so the merge lane converts onto an executor that is already substrate. The reviewer follows the same shape as the planning service: a capability the graph's review nodes call. +**Approach:** Adopt `docs/plans/2026-06-09-003-refactor-workflow-owned-merge-full-migration-slices-plan.md` and its S02–S08 slices (`docs/plans/workflow-owned-merge-stack/`) rather than authoring a parallel design (KTD-5). **Re-measure before sequencing:** S04 landed and S02/S03/S05 are built-but-undriven, so U9's job on those is to WIRE them, not to build them — see `docs/workflow-policy-ownership-map.md` → "Measured Wiring State". Sequence them behind U8 so the merge lane converts onto an executor that is already substrate. The reviewer follows the same shape as the planning service: a capability the graph's review nodes call. **S1 prerequisite — already landed.** *(PR #2463 review — greptile P1.)* S02 and S03 declare a direct dependency on S1 (workflow work-item schema + store API), and every later slice depends on it transitively. S1 is **in main**: the schema ships in `packages/core/src/postgres/migrations/0031_workflow_task_continuations.sql` and the store API (`listDueWorkflowWorkItems`, `acquireWorkflowWorkItemLease`, `transitionWorkflowWorkItem`, `replaceActiveTaskWorkflowContinuation`) is live and already drives the plan-review continuation path. Verify this at the start of U9 rather than assuming it — if any slice reaches for a store method that does not exist, land that gap as S1-completion work before continuing. @@ -614,7 +614,7 @@ The measurable goal is that the executor stops deciding *what happens next* — - `docs/solutions/architecture-patterns/workflow-node-column-placement-and-graph-entry-contract.md` — the entry contract, the plan-in-place chain, and the measured failure table from three reverted attempts. - `docs/plans/2026-07-21-001-fix-truthful-workflow-lifecycle-plan.md` — the five-column contract and suspend/resume protocol. Its R18 deferred "migrating `builtin:coding` node placement"; this plan is that deferred work. -- `docs/plans/2026-06-09-003-refactor-workflow-owned-merge-full-migration-slices-plan.md` (`status: active`) and `docs/plans/workflow-owned-merge-stack/` S02–S08 (all `draft-stack-handoff`) — the merge lane's existing target state and slices, adopted by U9 per KTD-5. +- `docs/plans/2026-06-09-003-refactor-workflow-owned-merge-full-migration-slices-plan.md` (`status: active`) and `docs/plans/workflow-owned-merge-stack/` S02–S08 (statuses corrected 2026-07-28; see each slice's Measured State block) — the merge lane's existing target state and slices, adopted by U9 per KTD-5. - `CONCEPTS.md` — Column, Column Trait, Hold, Slot, Workflow Runtime Primitive, Node Runner, Workflow Service. The Task entry enumerating the six legacy columns needs updating in U12. - `STRATEGY.md` — the orchestration-layer approach; a workflow that actually drives the lifecycle is the product claim this program makes true. - Session measurement (2026-07-26): 82 column guards, 43 column writes, 59 dashboard literals; `isWorkflowColumnsEnabled` returns a literal `true` with 8 live branches; `workflow-parity.ts` asserts equality with the legacy transition graph; lane service sizes as tabulated in Problem Frame. diff --git a/docs/plans/workflow-owned-merge-stack/s02-merge-request-projection.md b/docs/plans/workflow-owned-merge-stack/s02-merge-request-projection.md index 59b86eba17..4c34626172 100644 --- a/docs/plans/workflow-owned-merge-stack/s02-merge-request-projection.md +++ b/docs/plans/workflow-owned-merge-stack/s02-merge-request-projection.md @@ -1,7 +1,8 @@ --- title: "S02: merge request projection onto work items" type: refactor -status: draft-stack-handoff +status: landed-unwired +measured_against: "main @ 46f35323c (2026-07-28)" date: 2026-06-09 slice: S02 milestone: "Foundation" @@ -11,11 +12,18 @@ stack_base: feature/workflow-owned-merge-retry-scheduling-plan # S02: merge request projection onto work items +## Measured State (2026-07-28, U9 pre-flight) + +`projectMergeRequestToWorkflowWorkItem` is implemented in `packages/core/src/task-store/workflow-workitems-ops.ts` and has **zero production callers**. The projection exists; nothing invokes it. + +Status corrected from `draft-stack-handoff`, which was accurate when drafted on +2026-06-09 and is not now. See `docs/workflow-policy-ownership-map.md` → +"Measured Wiring State" for the whole-stack table. + ## Stack Role -This draft PR reserves the S02 review slot in the workflow-owned merge, -retry, scheduling, and recovery migration stack. It is intentionally a handoff -artifact, not the completed implementation for this slice. +This slot was drafted 2026-06-09 as a handoff artifact. It is **no longer** +only that — see the Measured State block above for what has actually landed. ## Milestone diff --git a/docs/plans/workflow-owned-merge-stack/s03-generic-scheduler-claim.md b/docs/plans/workflow-owned-merge-stack/s03-generic-scheduler-claim.md index dfa89bbd7f..516ac34003 100644 --- a/docs/plans/workflow-owned-merge-stack/s03-generic-scheduler-claim.md +++ b/docs/plans/workflow-owned-merge-stack/s03-generic-scheduler-claim.md @@ -1,7 +1,8 @@ --- title: "S03: generic scheduler claim path" type: refactor -status: draft-stack-handoff +status: landed-unwired +measured_against: "main @ 46f35323c (2026-07-28)" date: 2026-06-09 slice: S03 milestone: "Foundation" @@ -11,11 +12,18 @@ stack_base: feature/workflow-owned-merge-s02-merge-request-projection # S03: generic scheduler claim path +## Measured State (2026-07-28, U9 pre-flight) + +`claimDueWorkflowWorkItem` is implemented in `packages/engine/src/workflow-work-scheduler.ts` and wired into `workflow-work-processor.ts` — but that processor has **zero production callers**, so the claim path never runs. + +Status corrected from `draft-stack-handoff`, which was accurate when drafted on +2026-06-09 and is not now. See `docs/workflow-policy-ownership-map.md` → +"Measured Wiring State" for the whole-stack table. + ## Stack Role -This draft PR reserves the S03 review slot in the workflow-owned merge, -retry, scheduling, and recovery migration stack. It is intentionally a handoff -artifact, not the completed implementation for this slice. +This slot was drafted 2026-06-09 as a handoff artifact. It is **no longer** +only that — see the Measured State block above for what has actually landed. ## Milestone diff --git a/docs/plans/workflow-owned-merge-stack/s04-builtin-ir-regions.md b/docs/plans/workflow-owned-merge-stack/s04-builtin-ir-regions.md index ebf0d9cf0d..65c42b5ae6 100644 --- a/docs/plans/workflow-owned-merge-stack/s04-builtin-ir-regions.md +++ b/docs/plans/workflow-owned-merge-stack/s04-builtin-ir-regions.md @@ -1,7 +1,8 @@ --- title: "S04: built-in merge retry recovery IR regions" type: refactor -status: draft-stack-handoff +status: landed +measured_against: "main @ 46f35323c (2026-07-28)" date: 2026-06-09 slice: S04 milestone: "Gate A" @@ -11,11 +12,18 @@ stack_base: feature/workflow-owned-merge-s03-generic-scheduler-claim # S04: built-in merge retry recovery IR regions +## Measured State (2026-07-28, U9 pre-flight) + +The merge/retry/manual-hold/branch-group/recovery regions are **present** in `packages/core/src/builtin-coding-workflow-ir.ts` (`merge-gate`, `merge-retry`, `manual-merge-hold`, `merge-attempt`, `recovery-router`). Do not re-implement. Caveat: the declared node *config* (`maxAttempts`, `release`, `maxReworkCycles`) is read by nothing — pinned by `u9-merge-region-node-config-authority.test.ts` in the merge gate. + +Status corrected from `draft-stack-handoff`, which was accurate when drafted on +2026-06-09 and is not now. See `docs/workflow-policy-ownership-map.md` → +"Measured Wiring State" for the whole-stack table. + ## Stack Role -This draft PR reserves the S04 review slot in the workflow-owned merge, -retry, scheduling, and recovery migration stack. It is intentionally a handoff -artifact, not the completed implementation for this slice. +This slot was drafted 2026-06-09 as a handoff artifact. It is **no longer** +only that — see the Measured State block above for what has actually landed. ## Milestone diff --git a/docs/plans/workflow-owned-merge-stack/s05-runtime-work-item-driver.md b/docs/plans/workflow-owned-merge-stack/s05-runtime-work-item-driver.md index ac433eba34..b55291ccc2 100644 --- a/docs/plans/workflow-owned-merge-stack/s05-runtime-work-item-driver.md +++ b/docs/plans/workflow-owned-merge-stack/s05-runtime-work-item-driver.md @@ -1,7 +1,8 @@ --- title: "S05: runtime work-item driver" type: refactor -status: draft-stack-handoff +status: landed-unwired +measured_against: "main @ 46f35323c (2026-07-28)" date: 2026-06-09 slice: S05 milestone: "Runtime" @@ -11,11 +12,18 @@ stack_base: feature/workflow-owned-merge-s04-builtin-ir-regions # S05: runtime work-item driver +## Measured State (2026-07-28, U9 pre-flight) + +`WorkflowTaskRuntime.runWorkItem` and `processDueWorkflowWorkItem` are implemented; the processor is exported from `packages/engine/src/index.ts` and has **zero production callers**. The only live pump, `InProcessRuntime.drainWorkflowContinuations`, filters `kinds: ["task"]` and does not use this path. + +Status corrected from `draft-stack-handoff`, which was accurate when drafted on +2026-06-09 and is not now. See `docs/workflow-policy-ownership-map.md` → +"Measured Wiring State" for the whole-stack table. + ## Stack Role -This draft PR reserves the S05 review slot in the workflow-owned merge, -retry, scheduling, and recovery migration stack. It is intentionally a handoff -artifact, not the completed implementation for this slice. +This slot was drafted 2026-06-09 as a handoff artifact. It is **no longer** +only that — see the Measured State block above for what has actually landed. ## Milestone diff --git a/docs/plans/workflow-owned-merge-stack/s06-git-merge-capabilities.md b/docs/plans/workflow-owned-merge-stack/s06-git-merge-capabilities.md index b30c591dfb..99b9f835ff 100644 --- a/docs/plans/workflow-owned-merge-stack/s06-git-merge-capabilities.md +++ b/docs/plans/workflow-owned-merge-stack/s06-git-merge-capabilities.md @@ -1,7 +1,8 @@ --- title: "S06: git and merge capability extraction" type: refactor -status: draft-stack-handoff +status: not-started +measured_against: "main @ 46f35323c (2026-07-28)" date: 2026-06-09 slice: S06 milestone: "Runtime" @@ -11,11 +12,18 @@ stack_base: feature/workflow-owned-merge-s05-runtime-work-item-driver # S06: git and merge capability extraction +## Measured State (2026-07-28, U9 pre-flight) + +Merge still runs through `packages/engine/src/merger.ts` (11,273 lines). `workflow-merge-nodes.ts` is a 76-line shim over the `requestMerge` primitive, not the capability extraction this slice describes. + +Status corrected from `draft-stack-handoff`, which was accurate when drafted on +2026-06-09 and is not now. See `docs/workflow-policy-ownership-map.md` → +"Measured Wiring State" for the whole-stack table. + ## Stack Role -This draft PR reserves the S06 review slot in the workflow-owned merge, -retry, scheduling, and recovery migration stack. It is intentionally a handoff -artifact, not the completed implementation for this slice. +Not started. Merge still runs through `merger.ts`; this slot remains the plan of +record for extracting those procedures into workflow node capabilities. ## Milestone diff --git a/docs/plans/workflow-owned-merge-stack/s07-completion-handoff-merge-work.md b/docs/plans/workflow-owned-merge-stack/s07-completion-handoff-merge-work.md index 7ab5820093..1b552f8c19 100644 --- a/docs/plans/workflow-owned-merge-stack/s07-completion-handoff-merge-work.md +++ b/docs/plans/workflow-owned-merge-stack/s07-completion-handoff-merge-work.md @@ -1,7 +1,8 @@ --- title: "S07: completion handoff creates merge work" type: refactor -status: draft-stack-handoff +status: not-started +measured_against: "main @ 46f35323c (2026-07-28)" date: 2026-06-09 slice: S07 milestone: "Runtime" @@ -11,11 +12,18 @@ stack_base: feature/workflow-owned-merge-s06-git-merge-capabilities # S07: completion handoff creates merge work +## Measured State (2026-07-28, U9 pre-flight) + +**Ordering constraint (corrected 2026-07-28 after PR #2504 review).** The writer already exists: `createCompletionHandoffWorkflowWork` writes `merge`/`manual-hold` items from the live handoff-to-review path, and nothing claims or reconciles them, so they accumulate non-terminal today. That is benign — the legacy `ProjectEngine.mergeQueue` still drives the actual merge. What this slice changes is making those items **authoritative**. Landing it before S03/S05 are driven converts a benign row leak into cards that reach the merge boundary and stop. S07 must not land before S03/S05 are driven, and the pre-existing unclaimed rows need a reconcile/backfill decision as part of this slice. + +Status corrected from `draft-stack-handoff`, which was accurate when drafted on +2026-06-09 and is not now. See `docs/workflow-policy-ownership-map.md` → +"Measured Wiring State" for the whole-stack table. + ## Stack Role -This draft PR reserves the S07 review slot in the workflow-owned merge, -retry, scheduling, and recovery migration stack. It is intentionally a handoff -artifact, not the completed implementation for this slice. +Not started, and gated on S03/S05 actually being driven — see the corrected +ordering constraint above. This slot remains the plan of record. ## Milestone diff --git a/docs/plans/workflow-owned-merge-stack/s08-workflow-owned-merge-processing.md b/docs/plans/workflow-owned-merge-stack/s08-workflow-owned-merge-processing.md index 92fd4a4c04..6ec25a12ea 100644 --- a/docs/plans/workflow-owned-merge-stack/s08-workflow-owned-merge-processing.md +++ b/docs/plans/workflow-owned-merge-stack/s08-workflow-owned-merge-processing.md @@ -1,7 +1,8 @@ --- title: "S08: workflow-owned merge queue processing" type: refactor -status: draft-stack-handoff +status: not-started +measured_against: "main @ 46f35323c (2026-07-28)" date: 2026-06-09 slice: S08 milestone: "Gate B" @@ -11,11 +12,18 @@ stack_base: feature/workflow-owned-merge-s07-completion-handoff-merge-work # S08: workflow-owned merge queue processing +## Measured State (2026-07-28, U9 pre-flight) + +`ProjectEngine.mergeQueue` + `drainMergeQueue` remain the live merge pump. + +Status corrected from `draft-stack-handoff`, which was accurate when drafted on +2026-06-09 and is not now. See `docs/workflow-policy-ownership-map.md` → +"Measured Wiring State" for the whole-stack table. + ## Stack Role -This draft PR reserves the S08 review slot in the workflow-owned merge, -retry, scheduling, and recovery migration stack. It is intentionally a handoff -artifact, not the completed implementation for this slice. +Not started. `ProjectEngine.mergeQueue` + `drainMergeQueue` remain the live merge +pump; this slot remains the plan of record for replacing them. ## Milestone diff --git a/docs/workflow-policy-ownership-map.md b/docs/workflow-policy-ownership-map.md index ada7625224..c167267ca4 100644 --- a/docs/workflow-policy-ownership-map.md +++ b/docs/workflow-policy-ownership-map.md @@ -62,6 +62,64 @@ mutating git state: semantics and the shared-branch member integration exception. - Run-audit correlation for git operations and recovery facts. +## Measured Wiring State (2026-07-28, U9 pre-flight) + +The S02–S08 substrate is further along than the slice docs claim, but a large part +of it is **built and not driven**. Measured against `main` at `46f35323c`. Recorded +here because "the code exists and its tests pass" reads as landed, and for four of +these that is not the same as running. + +| Capability | Implementation | Production callers | Reality | +|---|---|---|---| +| S1 work-item schema + store API | `0031_workflow_task_continuations.sql`, `store.ts` | live | **Wired.** Drives the plan-review continuation path. | +| S02 merge-request projection | `projectMergeRequestToWorkflowWorkItem` | **none** | Built, never invoked. | +| S03 generic scheduler claim | `claimDueWorkflowWorkItem` (`workflow-work-scheduler.ts`) | only the S05 processor, which is itself unwired | Built, never invoked. | +| S04 built-in IR merge regions | `merge-gate`, `merge-retry`, `manual-merge-hold`, `merge-attempt`, `recovery-router` in the coding IR | n/a — declarations | **Landed.** Node *config* is unread; see `u9-merge-region-node-config-authority.test.ts`. | +| S05 runtime work-item driver | `WorkflowTaskRuntime.runWorkItem`, `processDueWorkflowWorkItem` | **none** (exported from `index.ts` only) | Built, never invoked. | +| S06 git/merge capabilities | — | — | Not started. Merge runs through `merger.ts`. | +| S07 completion handoff creates merge work | — | — | Not started. | +| S08 workflow-owned merge processing | — | — | Not started. `ProjectEngine.mergeQueue` is the live pump. | + +**The consequence that matters for U9.** `WorkflowWorkItemKind` is +`task | merge | retry | manual-hold | recovery`. The only live pump is +`InProcessRuntime.drainWorkflowContinuations`, and it filters `kinds: ["task"]`. +The generic processor that would claim the other four kinds +(`processDueWorkflowWorkItem`) has no production caller. + +**Non-`task` work items are already being written, and nothing claims them.** +`createCompletionHandoffWorkflowWork` (`workflow-workitems-ops.ts:68`) writes +`kind: "merge"` when auto-merge is on and `kind: "manual-hold"` when it is off. It +is called from the LIVE handoff-to-review path (`moves.ts:438` and `:1150`), inside +the move transaction. The kind is computed into a variable +(`autoMerge ? "merge" : "manual-hold"`), which is why a literal grep for +`kind: "merge"` finds nothing — an earlier revision of this section wrongly +concluded there were zero writers on exactly that basis. + +So the current state is: + +| | State | +|---|---| +| Writers of `merge` / `manual-hold` | **Live** — every task that reaches review writes one | +| Claimers | **None** — the only pump filters `kinds: ["task"]` | +| Reconcilers | **None** — self-healing's continuation check also filters `kinds: ["task"]` (`self-healing.ts:6575`) | +| Only terminalization | The NEXT `createCompletionHandoffWorkflowWork` for the same task cancels prior ones as `superseded-by-completion-handoff` | + +These rows therefore **accumulate in a non-terminal state** (`runnable` / +`manual-required`), one per task that reaches review, cleared only if that same task +hands off again. + +**This does not stall any merge.** The actual merge is enqueued by +`enqueueMergeQueueInTransaction` in the same transaction, and the legacy +`ProjectEngine.mergeQueue` pump still drives it. The work items are parallel +bookkeeping that nothing consumes yet — accumulating dead rows, not stuck cards. + +**What this means for S07.** S07 does not introduce the writer; the writer is +already here. What S07 changes is making those items *authoritative* for the merge +lane. Until the generic pump (S03/S05) is actually driven, promoting these rows from +bookkeeping to authority converts a benign row leak into cards that reach the merge +boundary and stop. **S07 must not land before S03/S05 are driven** — and the +pre-existing unclaimed rows need a reconcile/backfill decision as part of that work. + ## Deletion Gates - No production caller may start checkout, branch integration, squash, or finalize