Issue 066 resolved: a file and its reader are guarded by a gate, proven by the coupled-pair spike; design 20 says so
This commit is contained in:
@@ -5,8 +5,9 @@ code:
|
|||||||
- mesh-catalog modules/showcase
|
- mesh-catalog modules/showcase
|
||||||
- mesh-controller internal/builder
|
- mesh-controller internal/builder
|
||||||
- mesh-sdk src
|
- mesh-sdk src
|
||||||
updated: 2026-09-15
|
updated: 2026-09-21
|
||||||
decisions:
|
decisions:
|
||||||
|
- 02-DECISIONS/0053-a-step-that-runs-on-a-schedule.md
|
||||||
- 02-DECISIONS/0074-the-wire-is-specified-not-the-types.md
|
- 02-DECISIONS/0074-the-wire-is-specified-not-the-types.md
|
||||||
- 02-DECISIONS/0040-what-a-module-is.md
|
- 02-DECISIONS/0040-what-a-module-is.md
|
||||||
- 02-DECISIONS/0039-what-the-sdk-holds-and-refuses.md
|
- 02-DECISIONS/0039-what-the-sdk-holds-and-refuses.md
|
||||||
@@ -178,3 +179,22 @@ knows. Putting the Plex client anywhere else is the shared-library disease with
|
|||||||
the builder records that as the build edge — but *a mesh that can rebuild a commit and get a
|
the builder records that as the build edge — but *a mesh that can rebuild a commit and get a
|
||||||
different library* is a real change from how everything else here works, and it should be a
|
different library* is a real change from how everything else here works, and it should be a
|
||||||
decision rather than a consequence.
|
decision rather than a consequence.
|
||||||
|
|
||||||
|
## A file and the thing that reads it are guarded by a gate
|
||||||
|
|
||||||
|
*Written 2026-09-21, from resolving [04-ISSUES/066](../../04-ISSUES/066-a-partly-applied-declaration-leaves-a-mixed-state-with-no-rollback/00-report.md).*
|
||||||
|
|
||||||
|
The apply is not a transaction: every resource is attempted, every failure reported, and only a
|
||||||
|
failed gate stops what follows it ([ADR 0053](../../02-DECISIONS/0053-a-step-that-runs-on-a-schedule.md)).
|
||||||
|
So a push can half-happen, and the pairing that matters is a configuration file beside the
|
||||||
|
service that reads it. A module keeps that pair correct by declaring them in this order: the file;
|
||||||
|
a `run-once` container that validates it; the service, with `restart-on` naming the file. A file
|
||||||
|
the validator refuses reaches the disk and nothing else — the gate fails, the service after it is
|
||||||
|
left as it was, and the machine reports the push failed. The service never serves what the
|
||||||
|
validator refused. That is the grouping, made from what the manifest already has; no primitive
|
||||||
|
withholds a file from the disk, and a service that reads its file live rather than at start is the
|
||||||
|
one shape this does not protect, and should not be written.
|
||||||
|
|
||||||
|
*How it is checked:* the lab's coupled-pair spike declares exactly this pair, pushes a refused
|
||||||
|
file, and asserts the file on disk is the new one, the service serves the old one, and the machine
|
||||||
|
reports the push failed.
|
||||||
|
|||||||
+3
-3
@@ -1,9 +1,9 @@
|
|||||||
---
|
---
|
||||||
status: located
|
status: resolved
|
||||||
opened: 2026-09-20
|
opened: 2026-09-20
|
||||||
located-in: [mesh-host internal/apply, mesh-controller internal/inventory (node_report)]
|
located-in: [mesh-host internal/apply, mesh-controller internal/inventory (node_report)]
|
||||||
fixed-by:
|
fixed-by: nothing new — a run-once validator before a service that restarts on the file is the grouping (ADR 0053); the lab's coupled-pair spike proves the service never serves what the validator refused; the visible half was issue 065
|
||||||
amended-design:
|
amended-design: 03-DESIGN/01-to-be/20-writing-a-module.md
|
||||||
---
|
---
|
||||||
|
|
||||||
# 066 — A partly applied declaration leaves a mixed state, with no rollback
|
# 066 — A partly applied declaration leaves a mixed state, with no rollback
|
||||||
|
|||||||
+9
@@ -18,3 +18,12 @@
|
|||||||
the grouping question alone; it closes when a coupled pair that must not be half-applied is
|
the grouping question alone; it closes when a coupled pair that must not be half-applied is
|
||||||
found in a module, and the declaration gains a way to say so — or when enough modules have run
|
found in a module, and the declaration gains a way to say so — or when enough modules have run
|
||||||
that the absence is evidence. The visibility half is done.
|
that the absence is evidence. The visibility half is done.
|
||||||
|
|
||||||
|
*2026-09-21, later.* The pairing was made on purpose, in a lab spike: a config file, a run-once
|
||||||
|
validator, a service that reads the file once at start and restarts on it. The second push changed
|
||||||
|
the file and made the validator refuse it. Observed: the file on disk was the new one, the service
|
||||||
|
served the old one, and the machine reported the push failed. The half-state exists — and it is
|
||||||
|
harmless, because the gate held: the refused configuration never reached the service. The grouping
|
||||||
|
the report asked for is this order of three resources, made from what a manifest already has. The
|
||||||
|
one shape it does not protect is a service that reads its file live, which a module should not
|
||||||
|
write. Resolved; the pattern is in design 20 with the spike as its check.
|
||||||
|
|||||||
Reference in New Issue
Block a user