Compare commits

..
9 changed files with 45 additions and 66 deletions
@@ -1,8 +1,8 @@
---
status: located
status: resolved
opened: 2026-09-22
located-in: [mesh-controller cmd/mesh-controller/adoption.go (take previews nothing), mesh-host internal/apply (the comparison and the record)]
fixed-by:
fixed-by: mesh-controller 201 (the preview names the narrowing and the port's reach), 206 (`take --yes <digest>` acts on the preview read)
amended-design:
---
@@ -46,3 +46,7 @@ host first, then the controller's `take`.
mesh-controller 201 and the pull request after it: the preview names it, and `take --yes <digest>`
acts on the preview that was read. Stays located until a take is read on an adopted machine — every
machine of this mesh is converged today, so the record's live row has not been run.
## Resolved, 2026-10-02
Closed on the operator's decision of 2026-10-02 with the built and tested code live on every machine (mesh-controller 206, mesh-host 64), not on a take read on an adopted machine: every machine of this mesh is converged, so none holds a found thing to compare, and the record's live row — ADR 0163's last — will be read at the next real adoption rather than staged. Said here so nobody later believes that row was run.
@@ -1,8 +1,8 @@
---
status: located
status: resolved
opened: 2026-09-22
located-in: [mesh-controller cmd/mesh-controller/adoption.go (take previews nothing), mesh-host internal/apply (the comparison and the record)]
fixed-by:
fixed-by: mesh-host 64 (genesis raises the forge as `gitea`, on the module's image digest, with the module's data directory at /data; a test holds the installer to the module's manifest)
amended-design:
---
@@ -63,3 +63,7 @@ to the module's manifest where the catalogue is checked out beside it. The netwo
left: the bootstrap forge runs on the machine's network to reach the store on its loopback, the module
runs bridged and publishes its ports, and the take says so. Closing waits for group 9's genesis test —
a mesh raised, the module assigned, and the module found holding rather than raising a second forge.
## Resolved, 2026-10-02
Closed on the operator's decision of 2026-10-02. Name, image and data directory align; the network does not — the bootstrap forge runs on the machine's network to reach the store on its loopback, the module runs bridged — and a take says so rather than hides it. Whether genesis should move the forge onto a bridge, and the test that raises a mesh and finds the module holding rather than raising a second forge, belong to group 9's genesis work and are not owed by this record any more.
@@ -1,8 +1,8 @@
---
status: located
status: resolved
opened: 2026-09-23
located-in: [mesh-controller cmd/mesh-controller/adoption.go (take previews nothing), mesh-host internal/apply (the comparison and the record)]
fixed-by:
fixed-by: mesh-host 63 (the kept original's difference), mesh-controller 201 (shown; a differing file refuses unless `--replace <path>`)
amended-design:
---
@@ -74,3 +74,7 @@ host first, then the controller's `take`.
mesh-host 63 reports the difference between the kept original and the declared content; mesh-controller
201 shows it in the preview and refuses a differing file unless `--replace <path>` names it, or the
module declares the file partially. Stays located until a take is read on an adopted machine.
## Resolved, 2026-10-02
Closed on the operator's decision of 2026-10-02 with the built and tested code live on every machine (mesh-controller 206, mesh-host 64), not on a take read on an adopted machine: every machine of this mesh is converged, so none holds a found thing to compare, and the record's live row — ADR 0163's last — will be read at the next real adoption rather than staged. Said here so nobody later believes that row was run.
@@ -1,8 +1,8 @@
---
status: located
status: resolved
opened: 2026-09-23
located-in: [mesh-controller cmd/mesh-controller/adoption.go (take previews nothing), mesh-host internal/apply (the comparison and the record)]
fixed-by:
fixed-by: mesh-host 63 (both images' creation dates), mesh-controller 201 (DOWNGRADE said; refused unless `--downgrade`)
amended-design:
---
@@ -71,3 +71,7 @@ host first, then the controller's `take`.
mesh-host 63 reports the found image and both images' creation dates; mesh-controller 201 says
DOWNGRADE and refuses unless `--downgrade` is said. Stays located until a take is read on an adopted
machine.
## Resolved, 2026-10-02
Closed on the operator's decision of 2026-10-02 with the built and tested code live on every machine (mesh-controller 206, mesh-host 64), not on a take read on an adopted machine: every machine of this mesh is converged, so none holds a found thing to compare, and the record's live row — ADR 0163's last — will be read at the next real adoption rather than staged. Said here so nobody later believes that row was run.
@@ -1,8 +1,8 @@
---
status: located
status: resolved
opened: 2026-09-23
located-in: [mesh-controller cmd/mesh-controller/adoption.go (take previews nothing), mesh-host internal/apply (the comparison and the record)]
fixed-by:
fixed-by: mesh-controller 201 (`secret accept --provider` reaches a required secret), 206 (a module's secrets listed with origin; a minted one for found data refuses unless `--mint <name>`)
amended-design:
---
@@ -78,3 +78,7 @@ The pull request after it reads every secret a module holds on a machine with it
of a module whose data was found refuses a minted, unaccepted one — naming the accept that carries
the existing value in, or `--mint <name>` to let the service take the new one. Stays located until
a take is read on an adopted machine.
## Resolved, 2026-10-02
Closed on the operator's decision of 2026-10-02 with the built and tested code live on every machine (mesh-controller 206, mesh-host 64), not on a take read on an adopted machine: every machine of this mesh is converged, so none holds a found thing to compare, and the record's live row — ADR 0163's last — will be read at the next real adoption rather than staged. Said here so nobody later believes that row was run.
@@ -1,8 +1,8 @@
---
status: located
status: resolved
opened: 2026-09-23
located-in: [mesh-controller cmd/mesh-controller/adoption.go (take previews nothing), mesh-host internal/apply (the comparison and the record)]
fixed-by:
fixed-by: mesh-controller 201 (the neighbours on a found network are named), 206 (the per-machine `networks` setting), mesh-host 64 (the taken container joins the kept network)
amended-design:
---
@@ -73,3 +73,7 @@ The preview names every neighbour on a found network (mesh-controller 201). The
adds the per-machine setting `networks` — a container id to the found networks it keeps — judged for an
adopted machine only, and mesh-host 64 has the taken container join each once it runs. Stays located
until a take is read on an adopted machine.
## Resolved, 2026-10-02
Closed on the operator's decision of 2026-10-02 with the built and tested code live on every machine (mesh-controller 206, mesh-host 64), not on a take read on an adopted machine: every machine of this mesh is converged, so none holds a found thing to compare, and the record's live row — ADR 0163's last — will be read at the next real adoption rather than staged. Said here so nobody later believes that row was run.
@@ -1,8 +1,8 @@
---
status: located
status: resolved
opened: 2026-10-02
located-in: [mesh-host internal/apply (removeOrphan: a former target of a kind with no removal was fatal), mesh-host internal/store (Record keeps a former target for every kind, the host's own archive included)]
fixed-by:
fixed-by: mesh-host 65 — a former target of a kind the host cannot remove is left in place, said and forgotten; a dropped archive still refuses
amended-design:
---
@@ -62,3 +62,10 @@ because the alternative was four machines that could apply nothing.
- Is there a bed that replaces a host under the current rules before the live mesh does
(the proof row of [ADR 0141](../../02-DECISIONS/0141-the-host-delivers-its-own-successor.md) was
a single crossover, before former targets existed)?
## Resolved, 2026-10-02
mesh-host 65, merged 07:35Z. Recovered as the record above says: the operator dropped the one
`@former:` entry from each machine's host record and pushed; the fixed host then ran on all four and
its first apply said `forgotten mesh-host.next@former:… a former target left in place` and applied the
rest. The open questions stand as questions for the host's own versions, not as faults.
@@ -1,38 +0,0 @@
---
status: located
opened: 2026-10-02
located-in: [mesh-host internal/outward (Links reported only the links carrying a default route)]
fixed-by:
amended-design: []
---
# 197 — A physical link that is down is not filtered when it comes up
## What was observed
A sweep of every machine's filter on 2026-10-02. A laptop-class machine connected by its radio has a
wired port that was unplugged. Its filter guarded the radio and the tunnel, and accepted everything
arriving on any other link:
```
iifname != { "mesh0", "<radio>" } accept
```
The wired port was not in the list. Plugged in, everything arriving on it would have been accepted,
every port of the machine open to whatever network the cable reached. That would last until the
machine reported again and was pushed a new filter.
## Why it matters
**The filter's one rule about links fails open.** [ADR 0140](../../02-DECISIONS/0140-the-filter-constrains-what-arrives-from-outside.md)
has the filter constrain what arrives from outside, and has the machine say which links face outside.
Everything not named is treated as the machine's own, its containers and bridges. So a link the machine
fails to name is not filtered at all. The host named only the links carrying a default route at the
moment it reported. A cable plugged in later is the ordinary case for a laptop. A second wired network
that never carries the default route, such as a direct link to a storage box, is never named at all.
## Open questions
- A virtual link that faces outside (a VPN client's interface, a USB tether that appears as a virtual
device) has no physical device behind it. It is named only while it carries the default route. Is
that enough?
@@ -1,14 +0,0 @@
# Diagnosis
*2026-10-02.*
**Located in `mesh-host` `internal/outward`.** `Links` read the kernel's routing tables and returned the
interfaces carrying a default route. An unplugged port carries none, so it was never reported, and the
controller rendered the filter around the links it was given.
**The fix.** A link faces outside if it carries a default route **or** has a physical device behind it.
The kernel lists every interface under `/sys/class/net`, with a `device` entry for one backed by
hardware. A bridge, a veth, the tunnel and the loopback have none, so they stay the machine's own. The
wired port is now reported up or down, and the filter guards it before anything is plugged in. Tested
with a radio carrying the default route and an unplugged wired port beside a bridge, a veth, the docker
bridge, the tunnel and the loopback: the two physical links are reported, nothing else.