TacidOS
Developers
Documentation

Decision 0072

0072. The only thing outside a machine is what somebody carried out of it

Architecture decision record 0072: 0072. The only thing outside a machine is what somebody carried out of it

Status
accepted
Date
2026-09-07

Status: accepted. Builds the answer ADR-0060 named and left unbuilt, twice.

Context

The journal is a hash chain, and the chain is anchored to a TPM NV counter root cannot wind back. Between them they catch a journal edited without the chip: truncated, restored from a backup, rolled back with /persist, copied off a disk. ADR-0060 named what they do not catch, and today’s amendment to it named a second case:

  • a root that rewrites the journal and moves the seal on. Nothing on a machine stops a root that drives the machine’s own TPM.
  • a surgical edit that leaves the last seal standing. The counter detects the removal of a seal, not the removal of a record.

Both entries end the same way: what would close this is an off-machine witness — the owner’s remote, holding the head — and it is not built.

The reason it is the answer is not incidental. Every other mechanism here has one ceiling: it is a claim the machine makes about itself, checked by the machine. Adding a better claim does not raise that ceiling. Only a fact held somewhere the machine cannot reach does.

Decision

A witness is one line the owner carries off the machine.

tacid-witness:1 records=42 head=<64 hex> at=1757260000000

tacid-keeper witness prints it. tacid-keeper witness '<line>' asks whether the journal still carries what the owner saw. The machine cannot fabricate the answer: a record’s hash commits to every record before it, so a chain that still holds record N with hash H has not had records 0..N altered, and one that does not, has.

Two refusals, because they are different news. Shorter means records were removed — not “may have been”, since a chain only grows and the owner saw this many. Rewritten means the chain to that point is not the chain the owner witnessed; it is not “one record changed”, because the hash at a position is the whole of the history before it.

It is not signed, and signing it would be ceremony rather than security. The owner took the line themselves, so they already know where it came from; and a machine willing to forge a witness would forge a signature with it. What makes a witness worth anything is where it is kept, not what is stamped on it.

It is not automatic, and cannot be. Nothing on a schedule can carry a fact off a machine and leave the machine unable to reach it — an automated copy is a copy the machine can write, which is exactly the property being bought back. So the mechanism is a person doing one deliberate thing at a moment they trust, and the command says so when it prints one.

Nothing keeps a copy here. Not the journal, not a state file. A witness this machine held would be a witness this machine could edit.

Zero records is a witness worth taking. A journal is anchored at birth, and a machine emptied down to nothing looks to a counter exactly like a birth — the case ADR-0060 lists as the one the anchor leaves open. An owner who witnessed the birth can tell those apart.

Consequences

  • The installation leg proves it on a booted machine, beside the truncation it already performs: a witness is taken, the journal is cut back, and the owner’s line refuses by a different route from the counter’s. That is the half that would still speak if the chip had been driven along with the file.
  • WitnessError is not Clone or Eq, because JournalError is neither — it carries an io::Error, and a failure to read a file is not a value to be compared.
  • The two sentences the machine test matches on are pinned by a test in the crate that writes them, which is the rule the fifth seam test established today.
  • What this still does not do is notice on its own. A witness held and never checked is a witness that catches nothing, and nothing here reminds anybody. A machine cannot usefully remind an owner to check a thing whose value is that the machine is not involved — but a second machine could, and that is the fleet transport of ADR-0030 rather than anything here.

Alternatives rejected

Have the machine push its head to a remote the owner runs. The obvious reading of “the owner’s remote, holding the head”, and it is weaker than it looks: the machine chooses what to send, so a compromised machine sends a head for a journal it has already rewritten. It helps only against a machine compromised after the push, which is a real but much narrower case — and it buys that by adding a network path out of the keeper, which is the one daemon with IPAddressDeny=any. Worth building on top of the fleet transport, where the other machine pulls; not worth a socket here.

Sign the witness with the machine’s key. See the decision. It authenticates the wrong end.

Write the witness to a file for the owner to copy. A file on the machine is a file the machine can rewrite between the owner taking it and the owner reading it. Printing it to a terminal a person is looking at is the smallest thing that actually leaves.