Stage 2 begins. The host stops only reporting and starts doing its one
job (ADR 0037): take an ordered list of typed resources and make the
machine match it, from a local file, with no mesh present.
What lands in this slice — the network-free vocabulary ADR 0043 names
first:
- Parse: JSON, refused WHOLE on an unknown version, type, field, a
missing id/type/path, or a duplicate id. An older host cannot be
handed a newer vocabulary and do half of it.
- directory and file appliers, each reading back after it writes —
mode and owner asserted against the machine, content compared byte
for byte. A value that did not take is a failed apply, not a success.
- store: the applied-state record, authoritative while disconnected,
written atomically. It is what makes removal possible.
- Convergence: apply in the stated order (the host never reorders),
record each success AFTER it works (ADR 0035), and remove what was
applied before and is no longer declared — in reverse order, so a
file goes before the directory that held it.
- The data-loss guard: the host removes ONLY what it created, never
what it adopted, and a created directory that now holds data is
refused (os.Remove, never RemoveAll) rather than deleted (ADR 0018,
0030). created is sticky across re-applies — caught by running the
real binary, not just the unit tests: recomputing it from disk made
a re-applied resource look adopted and leak on the next drop.
- Addressing: a declaration for another node is refused; a host with
no identity yet applies its bundle (the first-node path).
Not yet: sealed secrets, and the types that need the network or a
runtime (container, package, network, service, archive, user, action)
— they follow, and until then the host refuses them rather than doing
part of a declaration.
CLI: mesh-host apply [--store P] FILE.
Claude-Session: https://claude.ai/code/session_01LrgweAeERJYBg88c5cKDzF