Merge pull request 'Issues 011 and 012 — what the manifest review could not fix' (#12) from issues/manifest-review into main

This commit was merged in pull request #12.
This commit is contained in:
2026-09-05 03:52:32 +02:00
2 changed files with 99 additions and 0 deletions
@@ -0,0 +1,48 @@
---
status: open
opened: 2026-09-02
located-in: []
fixed-by:
amended-design:
---
# 011 — 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?
@@ -0,0 +1,51 @@
---
status: open
opened: 2026-09-02
located-in: []
fixed-by:
amended-design:
---
# 012 — Six modules own what they must share
## The symptom, as observed
Found by review of the catalogue examples (2026-09-02). The media stack is several modules —
a library server, the acquisition managers, a download client and their satellites — and each
of them declares the same library and download directories as its own resources.
The resolver refuses two modules that declare one path on one node, with no exemption for
identical content and no merge. That rule is right in general: two owners of one path is the
class of fault this repository keeps recording. But sharing those directories on one machine
is the entire point of this stack — the download client and the managers must see the same
downloads, the library server must see the same libraries. So the set, as written, refuses
its own only sensible assignment.
No test co-resolves any two of them, which is why the manifests pass today. The first machine
to be assigned the stack together is where the refusal would have surfaced.
## Why it matters beyond the instance
The manifests can express *a directory I own* and nothing else, so a directory that is the
shared workspace of several modules was written six times as six private ones. The intention
— several modules, one filesystem contract between them — has no vocabulary, and this is not
a media-stack peculiarity: any pipeline of modules handing files to each other on one machine
(an ingest directory, a spool, a drop folder) hits the same wall.
It is also a fork in the design the catalogue has otherwise avoided: the fix could be a new
owning module the others depend on, a shared-resource concept in the manifest, or a statement
that co-located file handoff is not a thing the mesh supports and these modules are one
module. Each answer changes what a module *is*, which is why this is an issue and not a patch.
## Open questions
- Is the unit wrong — is a stack that must share a filesystem one module with several
containers, the way the mail module already is?
- If it stays several modules: does one of them own the directories and the rest require
them, and is *requiring a directory from a neighbour* a provision, a claim, or a third
thing?
- The duplicate-path rule protects against genuinely rivalrous owners. Whatever expresses
sharing must not weaken it for the cases where refusal is the right answer — what
distinguishes the two, machine-checkably?
- The mesh's own rule is that a rule states how it is checked: whichever shape is chosen,
what test co-resolves the stack so this class of refusal is caught before a machine is?