--- topic: checking it status: accepted date: 2026-08-24 deciders: jochen reconstructed: false extends: 0017-a-test-defends-a-decision.md --- # 18. A picture of a system is read from the system, never from what asked for it ## Context A scenario declaration is a file. A raised scenario is a set of machines, links and rulesets. The two are supposed to correspond, and the entire value of the lab rests on noticing when they do not — [ADR 0017](0017-a-test-defends-a-decision.md) says a claim nothing checks is a claim that will quietly stop being true. Drawing a scenario makes that concrete, and forces a choice that looks cosmetic and is not. A diagram of a running system can be produced two ways: parse the declaration and lay it out, or interrogate the system and lay *that* out. The first is far easier — the declaration is already parsed, already validated, already in memory. It is also worthless for the only question worth asking of such a picture: *is what is running what I asked for?* A drawing built from the request and captioned **as raised** answers that question with the request, which always agrees with itself. This is the same fault as [04-ISSUES/003](../04-ISSUES/003-firewall-scope-is-read-by-no-code/00-report.md) — a firewall key declared in five manifests and read by no code, so a manifest appears to restrict a port and restricts nothing. The declaration was never wrong. Nothing ever asked the system. ## Considered options 1. **Draw the declaration, and label it honestly.** Cheap, and useful for review before anything is raised. Insufficient alone: it can never disagree with itself. 2. **Draw the system, inferring the rest from the declaration where the system is silent.** The tempting middle. Rejected — a picture where some facts are observed and some are assumed has no honest caption, and the assumed ones are exactly the interesting ones. 3. **Two pictures, one layout, neither borrowing from the other.** Chosen. ## Decision **A picture captioned *as raised* reads only the running system.** It never opens the declaration, not even for a fact the system happens not to record. Where the hypervisor does not natively hold a fact the picture needs — whether a segment is public, what a gateway translates, whether a machine refuses inbound — **the raise records it on the resource** as metadata, and the picture reads it back from there. That recording carries its own rule, which is the substance of this decision rather than an implementation note: > **A behavioural tag is written after the behaviour works, never when the resource is > created.** Written at creation, a tag restates the request in a new location and inherits none of the authority of having happened. A failed raise deliberately leaves its wreckage standing, so a tag written up front would let a picture of that wreckage badge translation the gateway was never configured to do — reproducing, inside the tool built to catch the fault, exactly the fault. So: the gateway is tagged after its ruleset applies; the machine after the read-back proves its firewall loaded. Both pictures render through **one layout**, so they can be put side by side and the difference read off directly. ## Consequences - **It earned itself on the first comparison.** Drawn side by side, every virtual machine in the live picture held no addresses at all. A container's interface carries the name of the device it was configured as; a virtual machine names its own — so joining addresses to devices by name attached every address to a container and none to a VM. Nothing failed; a whole class of machine silently lost its addresses. The two pictures disagreed, so it was visible in seconds. It is now joined on MAC. - Raise does more work, and writes metadata it does not itself consume. Accepted: the cost is a few config keys, and it is what makes a raised instance self-describing. - A resource raised before a tag existed is missing it. The reader says so rather than filling the gap from the declaration — an untagged link draws as unknown, not as what the file said it should be. - **The rule generalises past diagrams.** Anything reporting on the mesh — a status view, an inventory, a health check — is subject to it. A report assembled from the intended state is not a report. - The declared picture stays, and stays useful: it is review before raising, and it is one half of the comparison. It carries no runtime status, because it cannot know any. - **The constitution sync is now owed.** Accepted 2026-08-25, so §5 carries the rule unqualified and playbook [05](../00-META/process/05-constitution-sync.md) is due. Until it runs, the mesh does not enforce this — an unsynced rule is a rule the mesh does not enforce, whatever this document says. ## References - [ADR 0017](0017-a-test-defends-a-decision.md) — a claim nothing checks stops being true. - [ADR 0016](0016-the-lab.md) — why the lab must not supply what the mesh is responsible for; the same instinct, applied to facts rather than to configuration. - [04-ISSUES/003](../04-ISSUES/003-firewall-scope-is-read-by-no-code/00-report.md) — the fault in production form.