Files
fusion/packages/engine/src
gsxdsm 4eaa509024 test(engine): prove merge finalization on a renamed board — 3 ledger entries closed, and the ledger itself corrected (#2508)
Test-only. Closes three `auto-merge-finalization` entries from the
unproven-sites ledger.

## Why this one first

It is the **last move a card makes**. Keyed on the literal `done`, a
renamed board's proven-merged card is moved to a column its own workflow
does not declare — or refused and left stranded in review **with the
work already landed**. That is the most expensive failure shape in the
lifecycle, and nothing had run it against a renamed workflow.

## The ledger was wrong, and is corrected in this PR

My own ledger said this family *"needs a REAL git worktree, branch, and
squash … an engine-slow real-git lane, not another table row"*.

`finalizeProvenAutoMergeTask` **needs no git at all** — the merge proof
is a field on the row. It was reachable the whole time. The inference
came from *the family the code sits in* rather than from what the
function actually touches, and it parked reachable coverage for a slice.
The correction is written into the ledger so the remaining entries get
re-checked the same way rather than inheriting the assumption.

## A second correction, from mutation-testing rather than reading

I first claimed `resolveMergeOrchestrationColumn` as covered because it
sits in the same resolver as the other two. **All cases passed with it
hardcoded.** It changes only whether finalization records a
column-mismatch *repair* — never where the card lands, which is why the
other cases are blind to it.

It got its own case. Keyed on `in-review`, a renamed board's card
resting in `checking` compares unequal, so **every ordinary finalization
would be audited as repairing a mismatch that never existed** — a
healthy board reads as one constantly self-healing, and the audit trail
operators use to spot real strandings fills with false positives.

Sitting next to covered code is not coverage.

## Mutation-verified independently

| mutation | result |
|---|---|
| `completeColumn` → `"done"` | 3 fail — both renamed cases + the
differential |
| `isCompleteColumn` → `id === "done"` | exactly the already-done case
fails |
| `mergeColumn` → `"in-review"` | exactly the new audit case fails |

## Shared fixture extracted (pure move)

The vocabulary + IR builder moved to `_workflow-vocabulary-fixture.ts`
so the two suites cannot drift into testing different workflows — two
copies of a differential fixture is precisely how a renamed-workflow
test starts passing for reasons unrelated to the code under test. The
lifecycle suite is unchanged: **20/20 before and after**. The
`mergeOrchestration` trait is an opt-in option so the existing suite's
IR stays byte-identical.

## Fixture note worth keeping

Seeding needed **completed steps**: task creation parses three pending
steps out of the bootstrap PROMPT even with `applyDefaultWorkflowSteps:
false`, and `getTaskHardMergeBlocker` refuses on them (`"task has
incomplete steps"`). Found by the suite blocking on **both**
vocabularies — the signature of a broken fixture rather than a broken
guard.

## Verification

- 51/51 across the lifecycle, merge-family, ratchet and hold-release
suites
- engine `tsc --noEmit` clean
- `pnpm test:gate` green (307 + 10 + 71)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 17:15:35 -07:00
..
…
…
2026-07-26 14:42:06 -07:00