Files
fusion/packages/core
gsxdsm 89284df85e E2E: table-driven converted-sweep coverage, two new sites, and an honest unproven-sites ledger (#2485)
Follow-up to #2475 (merged). Test-only, plus one test-utility seam.

## Why a table

#2475 proved one converted sweep. The count has since gone to **three**,
twice while this work was open — `surfaceStalePausedTodos` appeared
during #2475's review, and #2478 landed `recovery-reconciler.ts` while
this branch was open. A suite with a bespoke `describe` per sweep is a
coverage claim that quietly becomes false.

Replaced with a table of `(seed, run, acted, roles, observability)`. The
driver derives four assertions per entry:

| | positive | negative |
|---|---|---|
| **renamed vocabulary** | acts on the card | inert in a non-target
column |
| **default vocabulary** | acts (regression floor) | inert |

Adding a converted sweep is **one entry** — the #2478 site proved that
in practice, not in principle. `actsOnRole`/`inertRole` are keys of
`Vocabulary`, not column strings, so an entry cannot hardcode `todo` and
pass for the wrong reason.

## Two findings, both from mutation rather than reading

**1. The census was wrong about `recovery-reconciler.ts:198.`** It was
flagged as a `resolveLifecycleColumns` site, so the row was first
labelled as covering it. **Destroying that role resolution leaves all 18
tests green** — `decideRecovery` looks policy up by *column id* and
never consults a role. The row is relabelled to what it actually proves,
and mutation-verified against that instead: keying the reconciler's
policy lookup on the `todo` literal fails exactly its renamed test.

**2. `resolveRoleRecovery` is an unreachable export.** It is the only
use of `resolveLifecycleColumns` in that file and has **no production
caller anywhere** in engine, core, or dashboard. So that census line is
not a live converted site — it is a helper written ahead of its
consumer. **Not fixed here:** it is production code owned by the U4
slice, and whether the consumer is still to land or it should be deleted
is its author's call.

## Observability is now explicit in the type

`persisted-row` is the strong form. `returned-decision` is recorded as
**weaker evidence** and the reconciler row uses it, because
`reconcileRecovery` decides and does not apply — there is no row to
read. Naming it in the type is what stops a return-value assertion from
quietly passing as observed state, and it is what keeps the ledger
truthful per site.

## Harness seam

`PgTestHarness` now exposes its raw admin SQL client. The store
**stamps** `updatedAt`/`columnMovedAt` on every write, so `updateTask`
cannot express an aged row at all — the patch is accepted and the value
silently replaced with `now`. **Found by the new case failing on BOTH
vocabularies**, which is what distinguishes a broken fixture from a
broken guard. Seeding only; assertions still read back through the real
`getTask` path.

## Mutation verification

| Mutation | Result |
|---|---|
| revert **only** `recoverStrandedCompletedTodoTasks`'s resolution |
**exactly** that row's renamed test fails |
| revert **only** `surfaceStalePausedTodos`'s resolution | **exactly**
its own renamed test fails |
| reconciler policy lookup keyed on `todo` | exactly the reconciler
row's renamed test fails |
| `resolveRoleRecovery` role resolution destroyed | **nothing fails** →
finding #2 |
| `hold-release` `isHeldTask` keyed on `todo` | 5 of 18 fail; default
spine survives |
| `markMoveInFlight` dropped | both spine tests fail |

Per-site verification matters here: three rows could all be riding one
guard. They are not.

## The honest number

**Proven end to end: 5** (two self-healing sweeps, the reconciler's
policy lookup at the weaker observability, hold-release's capacity
release, and the graph boundary + `moveTask` + post-commit bus).

**Not proven: 11 call sites** — `merger.ts:324-326`,
`merger-ai.ts:1022,1039`, `auto-merge-finalization.ts:20-22`,
`executor.ts:1763,6339,6341`, `self-healing.ts:713,6732`,
`mesh-lease-manager.ts:61`, `task-agent-sync.ts:59`,
`core/task-store/reads.ts:130`, `core/live-agent-count.ts:63-75`, and
four dashboard route sites.

The ledger lives in the file, not just here, so it stays with the code.

## Where the table does not fit — reported, not papered over

The **merge/rebound family** cannot be a table row: those sweeps have no
observable persisted effect without a real git repository, so `acted`
cannot be written against the row at all. They need an engine-slow
real-git lane. The dashboard sites need an HTTP route test with a live
store. Both are different lanes, not missing entries.

## Verification

- 18/18 green; engine + core `tsc --noEmit` clean; `pnpm test:gate`
green (299 + 10 + 71)
- full core PG suite run (the harness is shared): 1036 passed, 3 failed
in `central-archive-secrets` and `workflow-settings-project-identity` —
**reproduce identically with this change stashed**, pre-existing

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

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-27 15:25:17 -07:00
..
2026-07-26 18:11:47 -07:00