A seeded file is created once (0087); the foundation filters before anything listens (0088); a machine becomes the last thing it was told (design 05). Each says how it is checked.
64 lines
3.1 KiB
Markdown
64 lines
3.1 KiB
Markdown
---
|
|
topic: what runs on it
|
|
status: accepted
|
|
date: 2026-09-21
|
|
deciders: jochen
|
|
reconstructed: false
|
|
extends: 02-DECISIONS/0010-delivery.md
|
|
---
|
|
|
|
# 87. A seeded file is created once, and what grows in it is not the mesh's
|
|
|
|
## Context
|
|
|
|
A declaration is complete for what the host owns, and the host reconciles what is declared
|
|
([ADR 0010](0010-delivery.md)): a file with this content, held to it. That is the only thing a
|
|
manifest could say about a file, and it is the wrong thing for a file a module needs to **exist
|
|
before first start** and something else then legitimately writes into — an access list a
|
|
provisioner appends consumers to and the program persists back, a bootstrap configuration a
|
|
program rewrites. Every reconcile restored the seed behind the running program, erased what had
|
|
grown in it, and reported success
|
|
([issue 035](../04-ISSUES/035-reconciling-a-seed-file-wipes-what-grew-in-it/00-report.md)).
|
|
|
|
A run-once step ([ADR 0052](0052-a-step-that-runs-once-before-a-container.md)) can write a seed
|
|
only if absent, and that closed the instance for a broker whose seed is a program's job. It left
|
|
the general case: a plain file the mesh writes and never overwrites.
|
|
|
|
## Considered Options
|
|
|
|
1. **Two owners never share a file: the provisioner owns it, and first-start ordering is solved
|
|
another way.** Rejected as the only answer — some software refuses to start without the file,
|
|
and a module that must ship a program merely to write an empty file has been made to write a
|
|
program to say one word.
|
|
2. **A create-once semantic on a file.** Adopted.
|
|
|
|
## Decision
|
|
|
|
A file resource may say `create-once`. The host writes it when it is absent and, when it is
|
|
present, leaves it entirely alone — content, mode and owner — and reports it as **kept**, not
|
|
corrected. What is in the file then is somebody else's work the mesh asked for. The mesh removes
|
|
nothing it did not create ([ADR 0030](0030-data-outlives-the-mesh-that-declared-it.md)); it now
|
|
also does not overwrite what it created once and handed over.
|
|
|
|
On the security question ADR 0010 asks of every new resource behaviour: this **narrows** what a
|
|
declaration can do to a machine. A create-once file gives a compromised control plane one fewer
|
|
way to change a machine repeatedly — it can seed, once, and never again.
|
|
|
|
## Consequences
|
|
|
|
A module says which of its files are seeds, and the difference is visible in the manifest rather
|
|
than in whether the file happened to be revisited. A later change to a seed's declared content
|
|
does not reach a machine that already has the file; that is the meaning of a seed, and a module
|
|
that needs the new content ships it as a run-once step that migrates the existing file.
|
|
|
|
## How it is checked
|
|
|
|
The host's apply tests: a seed is created, grown into by hand, reconciled, and the growth survives
|
|
with the outcome `kept`. The vault bed declares one on a real node, grows it, pushes again, and
|
|
reads it back.
|
|
|
|
## References
|
|
|
|
- [issue 035](../04-ISSUES/035-reconciling-a-seed-file-wipes-what-grew-in-it/00-report.md)
|
|
- [ADR 0010](0010-delivery.md), [ADR 0030](0030-data-outlives-the-mesh-that-declared-it.md), [ADR 0052](0052-a-step-that-runs-once-before-a-container.md)
|