Issues 011 and 012 — what the manifest review could not fix #12
@@ -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?
|
||||||
Reference in New Issue
Block a user