ADR 0033: a router is scenery, not a node #7

Closed
jschoubben wants to merge 0 commits from design/the-router-is-scenery into main
Owner

ADR 0016 makes a lab node a virtual machine, and its reasoning is fidelity: a node boots a stock image and runs the real install, so it has to be a real machine or the thing under test is not the thing that ships.

That reasoning does not reach a router. Nothing under test runs on one, it holds no identity, the mesh never installs anything on it, and no assertion is ever made about its internals. It exists so packets behave the way they behave in the world — which is the definition of scenery.

So a router is a system container. What it must reproduce is kernel behaviour — translation, connection tracking, filtering, forwarding — and a container has the same kernel.

Verified before deciding, not assumed. In a plain unprivileged container: ip_forward and IPv6 forwarding both settable, nftables masquerade accepted and listed back, and the conntrack timeouts mapping_ttl depends on both writable. No privileged mode, no nesting, no capability grants.

Rejected letting the hypervisor provide NAT, on a stronger ground than speed: it makes the lab provide what the declaration is supposed to own, and it cannot express a mapping that expires, a gateway that refuses to forward, or policy between siblings. The model would shrink to fit the tool.

The distinction is now load-bearing and has to stay legible: node means something under test, scenery means something that makes the test real. If the mesh ever installs anything on a router, it has become a node and this record no longer covers it.

Implemented and verified in novox/mesh-lab — routers, NAT, port forwarding, policy, mapping expiry, and a transit router across unrelated public networks.

ADR 0016 makes a lab node a virtual machine, and its reasoning is **fidelity**: a node boots a stock image and runs the real install, so it has to be a real machine or the thing under test is not the thing that ships. That reasoning does not reach a router. Nothing under test runs on one, it holds no identity, the mesh never installs anything on it, and no assertion is ever made about its internals. It exists so packets behave the way they behave in the world — which is the definition of scenery. So a router is a **system container**. What it must reproduce is kernel behaviour — translation, connection tracking, filtering, forwarding — and a container has the same kernel. **Verified before deciding, not assumed.** In a plain unprivileged container: `ip_forward` and IPv6 forwarding both settable, nftables masquerade accepted and listed back, and the conntrack timeouts `mapping_ttl` depends on both writable. No privileged mode, no nesting, no capability grants. Rejected letting the hypervisor provide NAT, on a stronger ground than speed: it makes the *lab* provide what the declaration is supposed to own, and it cannot express a mapping that expires, a gateway that refuses to forward, or policy between siblings. The model would shrink to fit the tool. **The distinction is now load-bearing and has to stay legible:** *node* means something under test, *scenery* means something that makes the test real. If the mesh ever installs anything on a router, it has become a node and this record no longer covers it. Implemented and verified in `novox/mesh-lab` — routers, NAT, port forwarding, policy, mapping expiry, and a transit router across unrelated public networks.
jschoubben closed this pull request 2026-08-24 20:29:56 +00:00

Pull request closed

This pull request cannot be reopened because the branch was deleted.
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: novox/hq#7