# Closed world: when silence means "no" In all previous tutorials a missing fact yielded `NEITHER`: law stays silent. That is the right default caution: from the archive not knowing about your accreditation it does not follow that you have none. But sometimes it does. The archive keeps the accreditation registry, and keeps it **exhaustively**: if a person is not in it, she has no accreditation. Not "unknown" but no. That is a legal fact about the registry's completeness, and it must be **declared**, not implied. ```law language "law.core" version "0.2"; package tutorial.archive version "0.4.0"; namespace "urn:law:tutorial:archive"; entity Person; relation known_reader(p: Person) kind institutional; relation accredited(p: Person) kind institutional; relation in_researcher_registry(p: Person) kind institutional; relation must_be_escorted(p: Person) kind institutional; ``` ## Declaring completeness ```law closure AccreditationClosure { predicate accredited; domain known_reader; snapshot ARCHIVE_ACCREDITATION_2026; complete_as_of @2026-03-01T00:00:00+00:00; derive_explicit_negative true; } ``` It reads like this: the predicate `accredited` is **exhaustively** described by the `ARCHIVE_ACCREDITATION_2026` snapshot as of 1 March 2026, but only for those falling into the `known_reader` domain. The four fields carry four different obligations, and none is spare: | Field | What is declared | |---|---| | `predicate` | exactly which predicate is closed: not the package, not the ontology as a whole | | `domain` | about whom the registry may speak exhaustively | | `snapshot` | against which source; this is an address, not a word | | `complete_as_of` | at which moment completeness is claimed: the registry is complete **as of a date**, not forever | `derive_explicit_negative true` means a missing entry produces a **full negative fact**, not a mere lookup failure. The difference shows in the proof: such a negation carries a closure certificate, and the report states on what ground the system decided the entry is absent. ## What the engine answers | Reader | Facts | `accredited` | |---|---|---| | Ivanova | in domain, entry present | `TRUE_ONLY` | | Ivanova | in domain, no entry | `FALSE_ONLY` | | visiting researcher | outside domain | `NEITHER` | The middle row is what `closure` is written for. The top and bottom rows are the same without it. **Closure is local.** About those outside the domain the registry says nothing, and the system answers `NEITHER`. The engine is not being cautious here but reads the declaration literally: the archive claimed completeness about its own readers, not about all people in the world. The temptation to write `domain` wider is worth resisting: widening the domain widens the claim the archive answers for. ## Why this belongs in a norm Negation in a rule body works only where negation can be established. ```law rule EscortRequired strict { for p: Person; when in_researcher_registry(p) and not accredited(p); then must_be_escorted(p); } ``` | Reader | Facts | `must_be_escorted` | |---|---|---| | Ivanova | in domain, in researcher registry, no accreditation | `TRUE_ONLY` | | visitor | outside domain, in researcher registry | `NEITHER` | Without a declared closure this rule would **never** fire: `not accredited(p)` requires an established negation, and there is nowhere to take it from. There is no negation by failure in the core; the silence of rules remains silence (we saw that in the second tutorial). `closure` is the only way to turn a missing entry into a fact, and that way requires an explicit claim about the source's completeness. ## What it costs Closure is a strong claim about the world, and it ages. `complete_as_of` fixes a moment; a norm executed at a later date relies on a snapshot that may be stale. Checking the snapshot's freshness is the job of the process around the system, not of the engine: the core executes what was declared and does not guess when the declaration stopped being true. Hence the practical rule: `closure` is declared where completeness has a **holder**, an authority obliged to keep the registry and answering for its completeness. If there is no such authority, `NEITHER` is the honest answer, and replacing it with `FALSE` by declaring completeness means shifting onto the system a responsibility nobody took. ## How law answers "no" The three tools with which law answers "no" can now be told apart: | Mechanism | Answer | Ground | |---|---|---| | norm with a negative head | `FALSE_ONLY` | the norm directly forbids | | `closure` | `FALSE_ONLY` | the registry is declared complete | | `defeater` | `NEITHER` | the ground of application has lapsed | | none of the above | `NEITHER` | the input is incomplete | Next is [the test in the language of law](/tutorials/writing-tests/): a check a lawyer will read is written in the same language as the norm. After it comes a real act: article 175 of the Social Code of the Republic of Kazakhstan, its source, the content-hash anchor, and reconciliation with the pinned edition. The exercise for this page is [/tutorials/exercise-closed-world/](/tutorials/exercise-closed-world/).