Skip to content

Commit 38bc74e

Browse files
Elon Muskclaude
andauthored
fix(metadata-protocol): a seam that cannot answer is absent, not empty (#10789) (#10964)
`backfillSeedTenancy` reported `no-split` over a driver it never queried. A no-op `execute` returns `null` — it neither throws nor is absent — so the `no-driver` guard's shape test passed, `normalizeRows(null)` flattened to `[]`, and the module's own `absent` branch was unreachable on a memory engine despite its comment naming exactly that case. The READ probes are now held to the standard that separates the two: a driver that answers returns a RESULT SET. Write statements stay on the bare seam (an UPDATE returns no result set on every dialect), a throwing seam keeps its existing `absent` route, and an empty result set in all three dialect spellings is still an ANSWER — so a healthy SQL install still reports `no-split`. Consumer-side only; no driver package was modified (#5499 freeze). Claude-Session: https://claude.ai/code/session_019yDEhPBC3tcGkW9bkce1HM Co-authored-by: Claude <noreply@anthropic.com>
1 parent 926778b commit 38bc74e

4 files changed

Lines changed: 562 additions & 9 deletions

File tree

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
---
2+
"@objectstack/metadata-protocol": patch
3+
---
4+
5+
`backfillSeedTenancy` no longer reports `no-split` over a driver it never queried
6+
(#10789). The boot-time seed/API tenancy repair answered `status: 'no-split'`
7+
*"I looked, there is no split"* — on the memory driver, having looked at nothing,
8+
and its own `absent` branch was unreachable there despite the branch's comment
9+
saying *"Absent on a memory engine"*.
10+
11+
`InMemoryDriver.execute()` logs `Raw execution not supported in InMemory driver`
12+
and returns `null`. It neither throws nor is absent, so `resolveSeedTenancySeam`'s
13+
shape test (`typeof d.execute === 'function'`) was satisfied and the `no-driver`
14+
guard never fired; `normalizeRows(null)` is `[]`, which is also what a real driver
15+
returns for a SELECT that matched nothing. Every branch of this migration reads
16+
"no rows" as "healthy install, nothing to do", so the two collapsed into one
17+
answer.
18+
19+
The migration now separates the cases the guard used to conflate: **a seam that
20+
cannot answer is absent, not empty.** Its READ probes are held to the standard
21+
that actually distinguishes them — a driver that answers returns a RESULT SET —
22+
so a probe that hands back no result set reports `absent` (with a `detail` naming
23+
the reason) instead of being read as zero rows. Nothing names a driver: any host
24+
with the same no-op shape is covered without an allowlist to maintain. This is the
25+
consumer-side shape #10677 / PR #10788 landed for `os migrate duplicates`, applied
26+
to this module's own probes. No driver package was modified.
27+
28+
Three behaviours are deliberately unchanged:
29+
30+
- **A real SQL install does not move.** An empty result set is an ANSWER in every
31+
dialect spelling — a bare `[]`, `{ rows: [] }`, and the `[rows, fields]` tuple —
32+
so a healthy install still reports `no-split`. The counter-table presence probe
33+
is a `WHERE 1 = 0` SELECT that matches nothing by construction and runs on every
34+
boot, which is exactly why "no rows" must stay distinct from "no answer".
35+
- **Write statements are not held to "must answer".** An UPDATE or DELETE does not
36+
return a result set on every dialect, so the repair's stamp and counter-merge
37+
statements stay on the bare seam.
38+
- **A seam that THROWS keeps its behaviour.** Throwing is a driver present and
39+
refusing loudly, and step 1's `catch` already reported it as `absent`; only a
40+
seam that RETURNS a non-answer was invisible.
41+
42+
Boot-time behaviour is otherwise untouched: neither status logs anything, and
43+
neither writes a ledger receipt, so a memory-driver boot logs exactly what it
44+
logged before. What changes is the reported `status`, which is the value a caller
45+
uses to tell "nothing to repair" from "could not look".

0 commit comments

Comments
 (0)