Found while fixing #10677 (os migrate duplicates), in the shared module that card's seam resolution lives in. Not fixed there — the blast radius is the boot path of every memory-driver app, which is a different verification surface from a CLI report.
The defect
backfillSeedTenancy (packages/metadata-protocol/src/migrations/seed-tenancy-backfill.ts) runs at boot from runtime/src/app-plugin.ts and metadata-protocol/src/plugin.ts. On the memory driver it returns status: 'no-split' — "I looked, there is no split" — having answered nothing.
Same root cause as #10677: InMemoryDriver.execute() (memory-driver.ts:300-302) logs Raw execution not supported in InMemory driver and returns null. It neither throws nor is absent, so:
if (!seam?.exec) return { status: 'no-driver' } does not fire — resolveSeedTenancySeam's canRun tests typeof d.execute === 'function', which a no-op execute satisfies.- Step 1's
absent branch is unreachable. The counter-table presence probe is written as
// 1. Is there a counter table at all? Absent on a memory engine, and on any// install that has never allocated an autonumber.try{awaitexec(buildSequencesPresenceSql(client));}catch{return{status: 'absent', ...empty};}
The comment states the intent exactly — "Absent on a memory engine" — but the no-op seam returns rather than throwing, so the catch never runs and the memory engine never reaches absent. - Step 2 then does
normalizeRows(await exec(buildSplitProbeSql(client), …)). normalizeRows(null) is [] (:351, if (!result) return [];), so splits.length === 0 and the function returns no-split.
The distinction being lost is the one #10677 turned out to be about: a seam that cannot answer is absent, not empty.null is a fourth thing next to the three dialect result-set shapes normalizeRows flattens — it means "I did not run your query", and normalizeRows maps it onto "your query returned no rows".
Severity
Lower than #10677: this is a boot-time migration whose no-op on a seamless driver is the correct action, so no data is mishandled. What is wrong is the reported status, which is the value a caller would use to tell "nothing to repair" from "could not look" — and the module's own comment shows absent was meant to be reachable here.
Suggested direction (not a ruling)
The consumer-side shape #10677 landed for the CLI applies: judge the seam by whether it returns a result set, not by whether execute exists. normalizeRows is the natural home for the distinction since it is where the conflation happens today, but making resolveSeedTenancySeam or backfillSeedTenancy return absent/no-driver for a non-answering seam changes boot behaviour for every memory-driver app and example, so it wants its own triage rather than a rider.
⛔ Note the constraint that shaped #10677: the maintainer's 2026-08-05 investment freeze covers the driver-memory/driver-mongodb family, so making InMemoryDriver.execute() throw is not available without a maintainer ruling, however much tidier it looks.
The mongodb branch is not claimed here — that driver was not loaded while measuring this.
Refs: #10677 · PR #10788
Found while fixing #10677 (
os migrate duplicates), in the shared module that card's seam resolution lives in. Not fixed there — the blast radius is the boot path of every memory-driver app, which is a different verification surface from a CLI report.The defect
backfillSeedTenancy(packages/metadata-protocol/src/migrations/seed-tenancy-backfill.ts) runs at boot fromruntime/src/app-plugin.tsandmetadata-protocol/src/plugin.ts. On the memory driver it returnsstatus: 'no-split'— "I looked, there is no split" — having answered nothing.Same root cause as #10677:
InMemoryDriver.execute()(memory-driver.ts:300-302) logsRaw execution not supported in InMemory driverand returnsnull. It neither throws nor is absent, so:if (!seam?.exec) return { status: 'no-driver' }does not fire —resolveSeedTenancySeam'scanRunteststypeof d.execute === 'function', which a no-opexecutesatisfies.absentbranch is unreachable. The counter-table presence probe is written ascatchnever runs and the memory engine never reachesabsent.normalizeRows(await exec(buildSplitProbeSql(client), …)).normalizeRows(null)is[](:351,if (!result) return [];), sosplits.length === 0and the function returnsno-split.The distinction being lost is the one #10677 turned out to be about: a seam that cannot answer is absent, not empty.
nullis a fourth thing next to the three dialect result-set shapesnormalizeRowsflattens — it means "I did not run your query", andnormalizeRowsmaps it onto "your query returned no rows".Severity
Lower than #10677: this is a boot-time migration whose no-op on a seamless driver is the correct action, so no data is mishandled. What is wrong is the reported
status, which is the value a caller would use to tell "nothing to repair" from "could not look" — and the module's own comment showsabsentwas meant to be reachable here.Suggested direction (not a ruling)
The consumer-side shape #10677 landed for the CLI applies: judge the seam by whether it returns a result set, not by whether
executeexists.normalizeRowsis the natural home for the distinction since it is where the conflation happens today, but makingresolveSeedTenancySeamorbackfillSeedTenancyreturnabsent/no-driverfor a non-answering seam changes boot behaviour for every memory-driver app and example, so it wants its own triage rather than a rider.⛔ Note the constraint that shaped #10677: the maintainer's 2026-08-05 investment freeze covers the
driver-memory/driver-mongodbfamily, so makingInMemoryDriver.execute()throw is not available without a maintainer ruling, however much tidier it looks.The mongodb branch is not claimed here — that driver was not loaded while measuring this.
Refs: #10677 · PR #10788