Nothing in this repository was verified by anything but reading, which is how a superseded decision stayed live in the constitution and in the to-be README at the same time. Both were found by a person looking, and nothing stopped a third. Five checks: links resolve; `decisions:`/`extends:` name records that exist and are accepted; a governing document citing a superseded record must name its replacement in the same paragraph; supersession is symmetric; filename number matches heading number. Each was made to fail before it was made to pass. The live-citation check was verified against a reconstruction of the actual incident -- the to-be README citing ADR 0017 as live guidance -- and reports it with file and line. It found one thing nobody had noticed: ADR 0018 never declared that it superseded 0011, though 0011 has named 0018 as its superseder since August. Fixed. Deliberately not checked, and said so in the README: 02-DECISIONS and 01-RESEARCH may cite superseded records freely, because a decision record discusses history and research records what was observed. 00-as-is may rest on one, per 0056. Flagging those would put noise on correct documents, and a check that cries wolf gets suppressed -- which costs more than not having it. Two bugs found by running it: the frontmatter reader iterated an inline list as characters, and the as-is exemption was missing entirely.
5.5 KiB
status, date, deciders, reconstructed, supersedes, extends
| status | date | deciders | reconstructed | supersedes | extends |
|---|---|---|---|---|---|
| accepted | 2026-08-23 | jochen | false | 0011-the-installer-owns-linking.md | 0011-the-installer-owns-linking.md |
18. The mesh creates no symlinks — a derived file is a copy
Context
ADR 0011 responded to production data loss — a hand-made link, resolved through a container engine's volume handling, pointing a mount somewhere it should not have — by centralising linking in the installer and forbidding it everywhere else.
That narrowed the incident class. It did not close it. The hazard is not who made the link; it is that a path can resolve somewhere other than where it appears to. A link made by the installer resolves exactly the same way as a link made by hand. The rule made the mechanism rarer and better-governed while leaving the mechanism in place.
Two things have changed since, and together they remove the argument that kept it.
The original case for linking was staleness. A copy of a service definition goes stale silently while the catalogue moves on, so a link was the cheap way to guarantee the running node reads a current definition. That argument assumes the node's copy is unmanaged.
It is not. ADR 0004 established that everything on a node's disk is derived from the mesh and regenerated when its inputs change, and the installer already reconciles links rather than assuming them — repointing stale ones, adopting real files it finds where a link belongs. Reconciling content is the same operation as reconciling a pointer, plus a comparison.
So the mesh already has the machinery that makes a copy safe, and is using a link to solve a problem that machinery solves better. Worse, a link is conceptually the wrong shape: it makes the node's runtime state a pointer into source, which is the one thing ADR 0003 and ADR 0004 exist to prevent. State is derived onto nodes; it does not reach back.
Considered options
- Keep ADR 0011 as the final position — centralised linking, forbidden elsewhere. Rejected as the status quo. It governs the mechanism rather than removing it, and the failure it was written for remains reachable by any code path the installer trusts.
- Keep links but harden them — canonicalise before mounting, refuse a link that escapes an expected root. Rejected: it is a check bolted onto a hazard, and it has to be correct in every consumer, including container engines the mesh does not control.
- Copy, reconciled by the installer, with staleness detected rather than assumed away. Proposed here.
Decision
Accepted 2026-08-25. The position is settled; the migration is not designed. See "Open" below.
The mesh creates no symlinks. A file a node needs is placed on that node as a real file, derived from the mesh and reconciled by the installer like every other managed file (ADR 0004).
The prohibition in ADR 0011 stands and widens: it ceases to be "only the installer may link" and becomes "nothing links, the installer included".
When this is accepted, ADR 0011 becomes superseded rather than edited — its reasoning is why the rule exists at all, and the incident behind it is the reason anyone believes either record.
Consequences
- The path-resolution hazard is removed rather than governed. There is no link for a container engine to resolve, so the class of failure that cost production data is closed by construction.
- A node's runtime state stops pointing into source. What a node holds is derived output, which is what the mesh's model already says it is everywhere else.
- Staleness becomes a real problem that must be answered, not assumed away. This is the cost, and it is the whole cost: today a link cannot be stale, and a copy can. The answer has to be detection — the installer comparing what is on disk against what the mesh says should be — and it must be loud, because a silently stale definition is exactly the failure shape this mesh keeps producing (ADR 0008).
- Reconciliation gets more expensive: comparing content rather than checking a pointer's target, on every module, on every node.
- Disk usage rises, trivially, and is not a consideration.
- Existing links must be converted. A node mid-migration holds both forms, so reconciliation has to handle finding a link where a file now belongs — the mirror image of the adoption it already does.
Open
- How staleness is detected. Content hash, version marker, or regeneration on every reconcile. This is the decision that makes or breaks the change and it is not taken here.
- Whether anything must keep a link for reasons outside the mesh's control. If something does, that is a finding worth recording rather than an exception worth granting quietly.
- Migration order. Converting a node's links is a change to how its services resolve their own definitions, which is not a change to make everywhere at once.
Until those are answered this record stays proposed, and ADR 0011 remains the governing rule.
References
- ADR 0011 — the incident, and the rule this widens.
- ADR 0004 — the machinery that makes a copy safe.
03-DESIGN/00-as-is/05-runtime-and-installation.md— what the installer does today, including reconciliation and adoption.