|
| 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