Review of the to-be layer: check what the documents claim against what runs
First pass of a design review, done by reading documents against code and against a raised mesh rather than against each other. Every error below was invisible to a proofread. **Statuses were stale, and nothing checked them.** Ten to-be documents said `designed` while naming working, lab-proven code — several with a *What was built* or *Raised, and observed* section. Added a `status-vs-code` check: naming a file is a claim that the file implements this, so a document that points at one has stopped being merely designed. It failed on all ten before it passed, per the rule this folder sets for its own checks. **The bundle carries three images, not two.** 07 reasoned about which substrate services go in and overlooked that the control plane is in there too — it is what the substrate exists to start, and there is nothing to fetch it with yet. Counted, not deduced. **The bootstrap uses four shapes, not six.** It listed `file` and `directory`, which substrate-first-node.lock never asks for. The claim that mattered — nothing is blocked on the host — was true either way, which is why the wrong count survived. **The eight capabilities were documented nowhere.** Implemented in internal/profile/detectors.go and enumerated in no document, including the one about the host that detects them. A vocabulary modules write against, readable only by reading the code. Now written down, with the seat/graphical-session distinction that is wrong in both directions if collapsed. **MinIO swept out of the to-be layer** per 0028. The gate now fails on one thing left deliberately: ADR 0024 is `proposed` while two documents rest on it and the feature it decides is built and lab-proven. Accepting a decision is not mine to do.
This commit is contained in:
@@ -26,6 +26,7 @@ indistinguishable from one that cannot.
|
||||
| `numbering` | the number in the filename is the number in the heading | — |
|
||||
| `topics` | every record names a topic the index knows | — |
|
||||
| *(index.py)* | the written reading order matches what the records say | — |
|
||||
| `status-vs-code` | a to-be document naming specific code is not still `designed` | **ten documents**, several with a *What was built* section, describing lab-proven code |
|
||||
|
||||
## What is deliberately not checked
|
||||
|
||||
|
||||
@@ -284,6 +284,37 @@ def check_numbering(failures, records):
|
||||
)
|
||||
|
||||
|
||||
def check_status_against_code(failures):
|
||||
"""A design document naming specific code may not still call itself `designed`.
|
||||
|
||||
**Naming a file is a claim that the file implements this**, so the two fields have to agree.
|
||||
They drifted: ten to-be documents named working, lab-proven code — several with a *What was
|
||||
built* or *Raised, and observed* section — while still saying nothing had been built.
|
||||
|
||||
Deliberately weak, and that is the point of it being mechanical. It cannot tell whether the
|
||||
prose is true, only that a document has stopped claiming to be unbuilt once it points at
|
||||
something. `code: [mesh-control]` — a repository with no path — is a plan and stays
|
||||
`designed`.
|
||||
"""
|
||||
for path in markdown_files():
|
||||
if not rel(path).startswith("03-DESIGN/01-to-be/") or path.endswith("README.md"):
|
||||
continue
|
||||
front = frontmatter(read(path))
|
||||
if front.get("status") != "designed":
|
||||
continue
|
||||
for entry in front.get("code") or []:
|
||||
named = re.sub(r"\s*\(.*\)$", "", entry).strip().split(None, 1)
|
||||
if len(named) > 1:
|
||||
failures.add(
|
||||
"status-vs-code",
|
||||
rel(path),
|
||||
f"`designed`, but names {named[1]!r} in {named[0]}. Naming a file claims "
|
||||
f"it implements this — use `in-progress`, or `implemented` once it is "
|
||||
f"defensible from that repository's main branch.",
|
||||
)
|
||||
break
|
||||
|
||||
|
||||
def main():
|
||||
failures = Failures()
|
||||
records = load_records()
|
||||
@@ -293,6 +324,7 @@ def main():
|
||||
check_supersession_symmetry(failures, records)
|
||||
check_numbering(failures, records)
|
||||
check_topics(failures, records)
|
||||
check_status_against_code(failures)
|
||||
print(f"records: {len(records)} decision records checked")
|
||||
return failures.report()
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
layer: to-be
|
||||
status: designed
|
||||
status: in-progress
|
||||
code: [mesh-lab]
|
||||
updated: 2026-08-28
|
||||
updated: 2026-08-31
|
||||
decisions:
|
||||
- 02-DECISIONS/0016-the-lab.md
|
||||
- 02-DECISIONS/0010-delivery.md
|
||||
|
||||
@@ -180,7 +180,10 @@ what it is. No control plane, no declarations, no network. Verifiable immediatel
|
||||
the first node's path, and it is the claim the skeleton's Move 1 rests on and has never proved:
|
||||
that one host can raise the substrate alone.
|
||||
|
||||
Raising the substrate needs six shapes in the host's vocabulary, and **all six are built**:
|
||||
Raising the substrate uses **four** shapes — `package`, `container`, `service`, `action` —
|
||||
counted from the bundle that exists rather than reasoned about. `file` and `directory` are listed
|
||||
below because they are the cheapest to be sure of and a substrate that needed them would find them
|
||||
ready; the current bundle simply does not. **All of them are built:**
|
||||
|
||||
| | | |
|
||||
|---|---|---|
|
||||
@@ -272,6 +275,34 @@ nowhere else to get it — the detector is the only thing that looked.
|
||||
most.** *This machine has no container runtime* is the answer; *docker is not installed* is why.
|
||||
The first is the mesh's to say and the second is only the machine's.
|
||||
|
||||
### The eight, and what each one is evidence of
|
||||
|
||||
*Written 2026-08-31 from `internal/profile/detectors.go`, because the set was implemented and
|
||||
enumerated in no document. A vocabulary a module writes against, that exists only in code, is one
|
||||
nobody can write against without reading the code.*
|
||||
|
||||
| capability | what a detection proves |
|
||||
|---|---|
|
||||
| `container-runtime` | a runtime is **running**, not installed |
|
||||
| `package-manager` | the machine's own package manager works |
|
||||
| `service-manager` | an init that can be asked for state — including *degraded*, which reports on stdout and exits non-zero |
|
||||
| `firewall` | a filter this host can write rules into |
|
||||
| `overlay` | the private network can be joined |
|
||||
| `graphical-session` | a display server **is running** — state |
|
||||
| `seat` | hardware where one **could** run — and assignment needs this one, not the row above |
|
||||
| `privileged` | the host can change the machine |
|
||||
|
||||
**`seat` and `graphical-session` are the pair worth reading twice**, because collapsing them is
|
||||
the obvious economy and it is wrong in both directions: a machine with a seat and no session can
|
||||
be given a display server, and a machine with a session running is not thereby able to host a
|
||||
second one.
|
||||
|
||||
**A detection runs something that only succeeds if the thing is *functioning*, never `--version`.**
|
||||
A version string proves a binary is on disk, which
|
||||
[`04-ISSUES/007`](../../04-ISSUES/007-an-installed-package-is-not-a-capability/00-report.md)
|
||||
records as false in the way that matters: the package was installed and the daemon was not
|
||||
running.
|
||||
|
||||
**Never reported and reported nothing stay different.** One machine has not run the host yet; the
|
||||
other ran it and can do nothing. Both refuse everything that requires a capability, and the
|
||||
remedies are not remotely alike.
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
---
|
||||
layer: to-be
|
||||
status: designed
|
||||
status: in-progress
|
||||
code:
|
||||
- mesh-control
|
||||
updated: 2026-08-29
|
||||
updated: 2026-08-31
|
||||
decisions:
|
||||
- 02-DECISIONS/0001-mesh-brokers-nodes-host-agents-think.md
|
||||
- 02-DECISIONS/0005-the-node-host.md
|
||||
@@ -177,7 +177,7 @@ volume genuinely argues against a relational store.
|
||||
node except through the host.
|
||||
- **Not a surface.** Tier 3 is how people and agents reach it. It has one interface; the
|
||||
surfaces are what speak to that interface.
|
||||
- **Not the substrate.** It *runs on* tier 1 — PostgreSQL, LavinMQ, MinIO, an OCI registry
|
||||
- **Not the substrate.** It *runs on* tier 1 — PostgreSQL, LavinMQ, an OCI registry
|
||||
([ADR 0006](../../02-DECISIONS/0006-the-substrate-and-the-control-plane.md)) — and cannot start without
|
||||
them, which is what makes them a lower tier.
|
||||
- **Not privileged on a node.** It has no more access to a machine than the declaration
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
layer: to-be
|
||||
status: designed
|
||||
status: in-progress
|
||||
code:
|
||||
- mesh-host examples/substrate-first-node.lock
|
||||
- mesh-host internal/apply
|
||||
@@ -117,15 +117,20 @@ Being substrate and being in the bundle are two different questions:
|
||||
|---|---|---|
|
||||
| PostgreSQL | yes — the control plane's own state lives in it | **yes** — there is nowhere to put that state otherwise |
|
||||
| LavinMQ | yes — it cannot grant itself a virtual host | **yes** — the control plane reaches a node only over the link, and the link is the broker ([ADR 0006](../../02-DECISIONS/0006-the-substrate-and-the-control-plane.md)) |
|
||||
| MinIO | yes — it cannot grant itself a bucket | no — nothing is delivered before the mesh exists |
|
||||
| the OCI registry | yes — it cannot grant itself a repository | no — the first node fetches upstream ([ADR 0006](../../02-DECISIONS/0006-the-substrate-and-the-control-plane.md)) |
|
||||
|
||||
The two on the bottom rows are **substrate by role and ordinary by delivery**: by the time they
|
||||
are wanted there is a control plane, and it provisions them the way it provisions anything.
|
||||
That keeps the bundle to two images rather than four, which is what makes it small enough for the
|
||||
review [ADR 0005](../../02-DECISIONS/0005-the-node-host.md) requires. It was one until
|
||||
[ADR 0006](../../02-DECISIONS/0006-the-substrate-and-the-control-plane.md) established that the broker has
|
||||
to precede the control plane.
|
||||
The registry is **substrate by role and ordinary by delivery**: by the time it is wanted there is
|
||||
a control plane, and it provisions it the way it provisions anything. That keeps the bundle small
|
||||
enough for the review [ADR 0005](../../02-DECISIONS/0005-the-node-host.md) requires — one
|
||||
substrate image until
|
||||
[ADR 0006](../../02-DECISIONS/0006-the-substrate-and-the-control-plane.md) established that the
|
||||
broker has to precede the control plane, and two since.
|
||||
|
||||
*Corrected 2026-08-31, from counting what the bundle holds rather than reasoning about it.* **It
|
||||
carries three images, not two** — PostgreSQL, LavinMQ, and the control plane itself, which the
|
||||
sentence above had overlooked by counting only substrate services. The control plane is what the
|
||||
substrate exists to start, and it is in the bundle for the same reason they are: there is nothing
|
||||
to fetch it with yet. It also carries seven actions, a package and a service.
|
||||
|
||||
**Why pinned:** the bundle is applied when no mesh exists, so nothing can resolve a version, ask
|
||||
a registry, or check a constraint. What the host carries must already be exact.
|
||||
@@ -150,8 +155,8 @@ The order, from [research 011](../../01-RESEARCH/011-the-module-graph/worked-pro
|
||||
5 a virtual host, a credential, and actions, run locally
|
||||
a self-signed certificate
|
||||
6 the control plane starts and only now is there a mesh
|
||||
7 MinIO, the registry, and everything the ordinary path
|
||||
else are provisioned
|
||||
7 the registry, and everything else the ordinary path
|
||||
are provisioned
|
||||
```
|
||||
|
||||
**Steps 4 and 5 are why the bundle is not one image**
|
||||
@@ -185,10 +190,13 @@ what it is called differs per system. It is:
|
||||
- a package, which needs the machine's own package manager and a network — both permitted by
|
||||
[ADR 0006](../../02-DECISIONS/0006-the-substrate-and-the-control-plane.md).
|
||||
|
||||
So the host's bootstrap vocabulary is six shapes: **package**, **container**, **file**,
|
||||
**directory**, **service**, and **action**. **All six are built**
|
||||
([`05-the-node-host.md`](05-the-node-host.md) stage 2), so nothing in this bootstrap is
|
||||
blocked on the host any longer.
|
||||
So the bootstrap uses four shapes: **package**, **container**, **service** and **action** —
|
||||
*counted from `substrate-first-node.lock`, which is the only bundle there is*. It had said six,
|
||||
adding `file` and `directory`, which this bootstrap never asks for.
|
||||
|
||||
All four are built, as are the host's other four
|
||||
([`05-the-node-host.md`](05-the-node-host.md) stage 2), so nothing in this bootstrap is blocked
|
||||
on the host any longer — which is the claim that mattered, and it was true either way.
|
||||
|
||||
**Steps 2 and 3 happen before there is a mesh to do them**, which is why provisioning is part of
|
||||
the bootstrap rather than a service consumers use later. They are **actions** the bundle
|
||||
@@ -220,7 +228,7 @@ host's vocabulary grows by one shape rather than by one resource type per substr
|
||||
question was whether the host must learn what a database is, and it must not. The bundle
|
||||
declares an **action**; the host runs it and verifies it, and what a database means stays with
|
||||
the module that provides one.
|
||||
- **Whether one host can raise all four.** The claim under stage 2 of
|
||||
- **Whether one host can raise all three.** The claim under stage 2 of
|
||||
[the node host](05-the-node-host.md), never proved. If it is false, the tier boundary moves.
|
||||
- **How the substrate is updated once a mesh exists.** Pinned by hand at bootstrap; afterwards
|
||||
the control plane could deliver it like anything else, and nothing says whether it does.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
layer: to-be
|
||||
status: designed
|
||||
status: in-progress
|
||||
code:
|
||||
- mesh-control internal/catalogue/filtering.go
|
||||
- mesh-control examples/route-proxy
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
layer: to-be
|
||||
status: designed
|
||||
status: in-progress
|
||||
code:
|
||||
- mesh-host internal/link/run.go
|
||||
- mesh-host internal/link/enrol.go
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
layer: to-be
|
||||
status: designed
|
||||
status: in-progress
|
||||
code:
|
||||
- mesh-control internal/builder
|
||||
- mesh-control cmd/mesh-control (build, build --behind, push, status)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
layer: to-be
|
||||
status: designed
|
||||
status: in-progress
|
||||
code:
|
||||
- mesh-control cmd/mesh-control/board.go
|
||||
- mesh-control cmd/mesh-control/readable.go
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
layer: to-be
|
||||
status: designed
|
||||
status: in-progress
|
||||
code:
|
||||
- mesh-control internal/builder
|
||||
- mesh-control internal/catalogue/build.go
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
layer: to-be
|
||||
status: designed
|
||||
status: in-progress
|
||||
code:
|
||||
- mesh-control internal/inventory/secrets.go
|
||||
- mesh-control cmd/mesh-control/rotate.go
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
layer: to-be
|
||||
status: designed
|
||||
status: in-progress
|
||||
code:
|
||||
- mesh-control internal/licences
|
||||
- mesh-control cmd/mesh-control/licence.go
|
||||
|
||||
Reference in New Issue
Block a user