Reconcile: adopt initialization's consolidated HQ as canonical, re-home this session's new work #24
@@ -2,7 +2,7 @@
|
||||
layer: to-be
|
||||
status: designed
|
||||
code: [hal]
|
||||
updated: 2026-08-23
|
||||
updated: 2026-08-29
|
||||
decisions: [02-DECISIONS/0001-mesh-brokers-nodes-host-agents-think.md]
|
||||
---
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
layer: to-be
|
||||
status: in-progress
|
||||
code: [mesh-lab]
|
||||
updated: 2026-08-23
|
||||
updated: 2026-08-28
|
||||
decisions:
|
||||
- 02-DECISIONS/0016-the-lab.md
|
||||
- 02-DECISIONS/0016-the-lab.md
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
layer: to-be
|
||||
status: in-progress
|
||||
code: [mesh-lab]
|
||||
updated: 2026-08-25
|
||||
updated: 2026-08-28
|
||||
decisions:
|
||||
- 02-DECISIONS/0016-the-lab.md
|
||||
- 02-DECISIONS/0016-the-lab.md
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
layer: to-be
|
||||
status: in-progress
|
||||
code: [mesh-lab]
|
||||
updated: 2026-08-25
|
||||
updated: 2026-08-28
|
||||
decisions:
|
||||
- 02-DECISIONS/0016-the-lab.md
|
||||
- 02-DECISIONS/0016-the-lab.md
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
layer: to-be
|
||||
status: designed
|
||||
code: [mesh-lab]
|
||||
updated: 2026-08-24
|
||||
updated: 2026-08-28
|
||||
decisions:
|
||||
- 02-DECISIONS/0016-the-lab.md
|
||||
- 02-DECISIONS/0010-delivery.md
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
layer: to-be
|
||||
status: in-progress
|
||||
code: [mesh-host]
|
||||
updated: 2026-08-30
|
||||
updated: 2026-08-31
|
||||
decisions:
|
||||
- 02-DECISIONS/0019-how-this-repository-works.md
|
||||
- 02-DECISIONS/0004-a-node-and-how-it-joins.md
|
||||
@@ -190,6 +190,19 @@ Raising the substrate needs six shapes in the host's vocabulary, and **all six a
|
||||
| `container` | **built** | pinned by digest ([ADR 0006](../../02-DECISIONS/0006-the-substrate-and-the-control-plane.md)); identified by a label carrying a digest of the declaration that made it, because a runtime normalises what it is given and that is indistinguishable from drift |
|
||||
| `action` | **built** | bundle-only ([ADR 0005](../../02-DECISIONS/0005-the-node-host.md)); verify is mandatory and is the idempotency check as well as the read-back |
|
||||
|
||||
**A service says what it must reflect, and that is declared state rather than a command.**
|
||||
`restart-on` names files whose change means the unit must be restarted — because a running service
|
||||
does not re-read its configuration, and replacing a file, finding the service already running and
|
||||
doing nothing leaves a machine behaving the way it did before while every check passes. A *command*
|
||||
to restart would be an action, and the link may not carry one, so this is the shape that rule
|
||||
leaves rather than a way around it.
|
||||
|
||||
**It may name a file another module put there**, written `<module>.<id>`. The case that needed it:
|
||||
a resolver restarting when the mesh rewrites the names, which are computed by the mesh and belong
|
||||
to its module rather than to the daemon's. Without it the daemon serves the names it started with
|
||||
for ever — every machine that joined afterwards unreachable by name, and every check passing. An
|
||||
unqualified name still means *my own*, so the common case reads as it always did.
|
||||
|
||||
**An action's verify is the definition of what the action is for**, and the action's own idea of
|
||||
being finished must be the same one. *Written 2026-08-31, after this went wrong.* If an action
|
||||
waits on one test and its verify reads back another, the two can disagree — and then the action
|
||||
|
||||
@@ -5,7 +5,7 @@ code:
|
||||
- mesh-host examples/substrate-first-node.lock
|
||||
- mesh-host internal/apply
|
||||
- mesh-lab test/integration/mesh.test.ts (a bare machine becomes a mesh)
|
||||
updated: 2026-08-30
|
||||
updated: 2026-08-31
|
||||
decisions:
|
||||
- 02-DECISIONS/0004-a-node-and-how-it-joins.md
|
||||
- 02-DECISIONS/0005-the-node-host.md
|
||||
|
||||
@@ -420,17 +420,28 @@ tmpfiles — is shaped that way. Until there is one, a module ships a unit that
|
||||
the better shape: how a machine enforces rules is a fact about the machine, and the mesh has no
|
||||
business depending on what a distribution happens to package.
|
||||
|
||||
**One thing is derived from what is assigned and not yet from the overlay's shape**, and it is
|
||||
stated here rather than discovered: **a hub's own listening port.** A hub accepts inbound
|
||||
connections from every node at other sites; a node that is not a hub dials out and needs nothing
|
||||
open, because a reply to a flow it started is already accepted. So the two want different rules on
|
||||
an identical module — and `listens` is a static field on a manifest, while the overlay module's
|
||||
resources are computed per node.
|
||||
**One rule is derived from the overlay's shape rather than from what is assigned: a hub's own
|
||||
listening port.** A hub accepts inbound connections from every node at other sites; a machine that
|
||||
is not a hub dials out and needs nothing open, because a reply to a flow it started is already
|
||||
accepted. The two want different rules on an *identical module*, so `listens` — a static field —
|
||||
cannot say it. The machine a static answer gets wrong is the one facing the public internet, which
|
||||
is the machine that most needs filtering.
|
||||
|
||||
A machine that is not a hub is therefore correct today, and **a hub would have its own port closed
|
||||
by a rule set derived this way.** The fix is that a computed module contributes listens the way it
|
||||
contributes resources; until it exists, the firewall belongs on machines that are not hubs, and
|
||||
this paragraph is the reason rather than an oversight to find later.
|
||||
*Recorded as a gap on 2026-08-31 and closed the same day.* **A computed module now contributes
|
||||
listens the way it contributes resources.** The port comes from the endpoint, which is where the
|
||||
interface takes its `ListenPort` from — one source, so a rule set cannot open a port the interface
|
||||
is not on. It is open to *everywhere* deliberately: a node at another site is not on the private
|
||||
network until this port lets it on, so restricting it to the mesh would be a rule that can never
|
||||
be satisfied by the thing it exists for.
|
||||
|
||||
**A generator that cannot say what a machine opens is refused, not read as silence.** Closing a
|
||||
port on the evidence of a failure to look is how a machine is severed by a fault somewhere else —
|
||||
and the machine it would sever is the hub, whose only route to being repaired is the network it
|
||||
just closed.
|
||||
|
||||
*Checked by filtering the hub and then requiring the mesh to keep working: a declaration still
|
||||
reaches the other machine, and the other machine still reaches the hub. A rule file that looks
|
||||
right and a mesh that has stopped are exactly what that guards against.*
|
||||
|
||||
**And it is enforced, which is what separates this from `scope:`.** Checked on two real machines:
|
||||
two ports opened, one declared, and from the other machine the declared one answers and the
|
||||
|
||||
@@ -8,7 +8,7 @@ code:
|
||||
- mesh-host packaging/nox-mesh-host-network.sh
|
||||
- mesh-control internal/token
|
||||
- mesh-control internal/inventory/nodes.go
|
||||
updated: 2026-08-27
|
||||
updated: 2026-08-31
|
||||
decisions:
|
||||
- 02-DECISIONS/0004-a-node-and-how-it-joins.md
|
||||
- 02-DECISIONS/0005-the-node-host.md
|
||||
|
||||
@@ -5,7 +5,7 @@ code:
|
||||
- mesh-control internal/builder
|
||||
- mesh-control cmd/mesh-control (build, build --behind, push, status)
|
||||
- mesh-control internal/inventory/builds.go
|
||||
updated: 2026-08-28
|
||||
updated: 2026-08-31
|
||||
decisions:
|
||||
- 02-DECISIONS/0010-delivery.md
|
||||
- 02-DECISIONS/0009-modules-and-the-graph.md
|
||||
|
||||
Reference in New Issue
Block a user