Both from the 2026-09-02 review of the catalogue examples, and both design gaps rather than defects in a file: a seed file the host reconciles back to empty over the grants that grew in it, and a module stack refused co-assignment because six manifests each own the directories they exist to share. Fixing either in place would have been picking an answer the records do not yet hold. Claude-Session: https://claude.ai/code/session_01LrgweAeERJYBg88c5cKDzF
49 lines
2.4 KiB
Markdown
49 lines
2.4 KiB
Markdown
---
|
|
status: open
|
|
opened: 2026-09-02
|
|
located-in: []
|
|
fixed-by:
|
|
amended-design:
|
|
---
|
|
|
|
# 008 — Reconciling a seed file wipes what grew in it
|
|
|
|
## The symptom, as observed
|
|
|
|
Found by review of the catalogue examples (2026-09-02), not by an outage — the outage is the
|
|
part the design permits to be silent.
|
|
|
|
The cache module declares its access-control file as an ordinary file resource with fixed,
|
|
empty content. The program that consumes the file requires it to exist at startup, which is
|
|
why the manifest declares it at all. But the same file is the one the provisioner writes
|
|
consumer users into, and the one the running program persists ACL changes back to.
|
|
|
|
A declaration is complete for what the host owns, and the host reconciles what is declared
|
|
([ADR 0043](../../02-DECISIONS/0043-a-declaration-is-an-ordered-list-of-owned-resources.md)).
|
|
So every apply that revisits this resource restores the declared content — empty — behind the
|
|
running program. Every consumer credential granted since the last apply is removed, the apply
|
|
reports success, and nothing anywhere says a grant vanished.
|
|
|
|
## Why it matters beyond the instance
|
|
|
|
The manifest needed *the file to exist before first start*, and the only vocabulary available
|
|
was *the file has this content, forever*. Those are different intentions, and the gap between
|
|
them is generic: any resource that a module seeds and something else then legitimately mutates
|
|
— an ACL file, a bootstrap configuration a program rewrites, an htpasswd a provisioner appends
|
|
to — has the same two owners and the same silent loss on reconcile.
|
|
|
|
It is also the mirror image of the boundary ADR 0043 draws so carefully on the *removal* side:
|
|
the host never removes what it did not create, but it happily overwrites what it *did* create,
|
|
even when what grew inside since is somebody else's work the mesh asked for.
|
|
|
|
## Open questions
|
|
|
|
- Is the missing thing a create-once file semantic ("present with this content if absent,
|
|
untouched otherwise"), or is the real fault that two owners share one file — and the
|
|
provisioner, not the declaration, should own it entirely, with first-start ordering solved
|
|
some other way?
|
|
- ADR 0043 treats every added resource type as a security artefact. Does a create-once
|
|
semantic widen what a compromised control plane can express, or narrow it?
|
|
- Are there other seeded-then-mutated files already in the catalogue that this failure is
|
|
waiting inside?
|