D1 was the one item on the coverage list with genuinely no criterion. Measured by
mutation, not by grepping test names:
corrupt vector handling: skip -> throw
phase-b-h 137/137 green, phase-b-a 38/38 green, recall-accounting 5/5 green
-> 145 criteria, zero red
That is decision §0.4 unguarded: "the vector side failing must not take the main
path down". One bad row would cost the whole turn its memory, and nothing noticed.
## The same probe found three items that ARE covered
Recorded because the parent's coverage matrix derived "zero hits" from grepping
criteria IDs against test names, and three of those were false negatives — the
criteria exist, they are just named after their subject rather than their ID:
C6 centroid partitioned by fingerprint loadCentroid ignoring it -> 3 red
(ticket②, ticket②-strong, W8)
W1 exec.signal reaches embedText dropping it -> 2 red (W5, W9c)
F1 fingerprint from provider info() deriving locally -> 5 red
So the matrix under-reports as well as over-reports. Only mutation distinguishes
"labelled" from "enforced".
## What the criterion does
Writes a corrupt payload straight into the row and requires the recall to survive:
store.raw().prepare('UPDATE memory_blocks SET vector = ? WHERE id = ?')
.run('["a","b","c","d"]', broken.id) // right length, non-numeric elements
Two guards narrowed what "corrupt" can mean, both measured and documented in the
criterion:
· DDL enforces `json_valid(vector)` — a syntactically broken payload is refused
outright (`ERR_SQLITE_ERROR: malformed JSON`), so it cannot reach the read path;
· a trigger re-derives `vector_dim`, so a wrong-LENGTH payload is filtered in SQL
before scoring sees it.
An array of the right length with non-numeric elements clears both and still cannot
be scored — which is exactly what a provider that changed its encoding, or a
migration that stringified values, would leave behind.
Assertions: no throw, the healthy neighbour is still recalled, and the bad row is
counted in `skippedUnscoreable` (D1's other half is D2's rule: skipping silently is
the same defect).
Mutation — a non-numeric component throws instead of skipping:
not ok 6 - D1: a corrupt vector payload cannot take the recall path down
error: D1: a single corrupt vector payload threw out of the recall path
(M-D1: non-numeric vector component). Decision §0.4: ...
Gates: npm test 304/304 (0 skipped), npm run check 12/12.