Skip to content

ADR-0032: A missing Corpus is its own answer, and it is never Not Stated

Status: Accepted Date: 2026-09-08

Decisions

D-72 Corpus Unavailable is a distinct state from Not Stated, and the two may never be collapsed

Not Stated is a statement about a document: the SDS does not say. Corpus Unavailable is a statement about the device: this device holds no verifiably complete Corpus, so no document was consulted at all. One is a curated fact, the other is an infrastructure failure, and they must never render as the same answer.

D-73 The client verifies its Corpus at startup, and anything not verifiably complete is treated as absent

Completeness is checked against the snapshot version the sync recorded. A Corpus that does not verify is Corpus Unavailable in full — not a smaller Corpus, and not a Corpus with holes. There is no partial state to read.

D-74 Escalation, hotline 1669 and the standing statement remain available with no Corpus at all

None of them is a Corpus read. A device with an evicted store still shows the escalation route and the D-07 standing statement, because a phone number is more use during a spill than a blank screen.

Context

ADR-0020 accepted that web storage is weaker than the native assumption ADR-0005 was written under (D-42), and the spec recorded the consequence as an open action: "decide what the app does when it starts and finds its Corpus missing or partial. That path is unspecified here, and it is the realistic failure — not the total absence of the app." This ADR closes that action.

R-02's speed-of-access framing and R-03's four settings are why the Corpus is on the device at all, and R-13's spill scenario is the worked case where the network is absent. R-17's "Cloud Database" was already reinterpreted by ADR-0005 as origin of truth rather than point of read; what neither document settled was what the point of read does when it holds nothing.

The danger is specific and it is not the blank screen. §2 already requires Corpus replacement to be atomic, so an interrupted sync cannot produce a half-applied Corpus. Eviction is a different mechanism and no atomicity rule covers it. A store that has lost records still starts, still renders, and still answers — and under D-03 the honest-looking answer it gives is Not Stated.

That is a false answer wearing a correct one's clothes. A Handler reads "not stated in this SDS" and concludes the supplier is silent on gloves. The truth is that the document is gone. This is the failure ADR-0002 exists to prevent, arriving through storage rather than through a model, and nothing in the spec caught it because the vocabulary had no word for the second case.

§4 makes the same point from the other side: a recency cache is insufficient "because the emergency case is the unfamiliar chemical." An evicted store degrades into exactly that rejected recency cache, and does it silently.

Decision

The client checks at startup whether it holds a complete Corpus for a known snapshot version. If it does not, every safety surface reports Corpus Unavailable — naming what is missing, when the Corpus was last complete, and what to do about it — while Escalation, hotline 1669 and the standing statement continue to work. Not Stated is reserved for what a consulted SDS does not say.

Rejected options

  • Degrade: serve whatever records survived, and answer Not Stated for the rest — rejected. It is the option that produces the false answer above, and it silently reconstitutes the recency cache §4 rejected on the grounds that the emergency case is the unfamiliar chemical.
  • Fail closed entirely: no Corpus, no app — rejected. Honest, but it throws away the one thing that needs no data. Hotline 1669 is a phone number, and a blank app during a spill is worse than a phone number.
  • Report a partial Corpus as partial and let the user judge — rejected. It asks a Handler holding a drum to reason about database completeness, and it puts a third state into every safety surface for a case the atomicity rule already says must not be readable.
  • Treat eviction as out of scope for a prototype — rejected. D-42 already recorded it as a real risk of the platform decision, and the spec already called this the realistic failure rather than a hypothetical one.

This ruling may not be re-decided

If a change contradicts this ADR: stop and raise it. Do not implement over it.

Specifically: do not route Corpus Unavailable through the Not Stated component because the two look alike in a mockup; do not add a partial-Corpus mode because a full re-sync feels expensive on a slow connection; and do not hide the Corpus Unavailable state during a demo because it makes the app look broken. It is the app working correctly with no data.

Consequences

What becomes easy. Seam 4's zero-network assertion gains a companion case that is mechanically checkable: with the Corpus removed, every safety surface must report Corpus Unavailable and none may report Not Stated. That is a stronger test than either state alone.

What becomes hard. Recovery needs a network, and the moment the Corpus is discovered missing is frequently the moment there is no signal. This ADR does not solve that and does not pretend to; it makes the failure legible instead of silent. Installability (US-32) becomes more load-bearing, because an installed app is less likely to be evicted.

What is now closed off. Any design in which a safety surface answers from a Corpus it has not verified.

Coverage

UpstreamLanded inEvidenceNote
R-02D-74speed of access is why escalation survives an empty CorpusADR-0005 covers R-02's offline half
R-13D-72, D-74the spill case is where a false Not Stated would be acted on
R-17D-73"Cloud Database" as origin of truth means the device copy must be verifiableADR-0005 made the reinterpretation; this fixes what happens when the copy fails