ADR 0169 → 0170: the firewall seat's record renumbered after a collision on main; its built note; cycle.py refuses two records sharing a number

Another session's 0169 landed first. The collision check from issue 155
covered issue folders only; it covers decision records now, and would have
refused this.
This commit is contained in:
2026-10-02 14:51:22 +02:00
parent 91bbe648a8
commit 98eb3aa76f
6 changed files with 42 additions and 7 deletions
+16
View File
@@ -131,6 +131,22 @@ def main():
else:
seen[number] = name
# And decision records, which 155's fix left out: on 2026-10-02 two ADRs numbered 0169 landed
# on main from two sessions within the hour, and every check passed.
seen_records = {}
for path in sorted(glob.glob(os.path.join(ROOT, "02-DECISIONS", "[0-9]*.md"))):
name = os.path.basename(path)
number = name.split("-", 1)[0]
if not number.isdigit():
continue
if number in seen_records:
bad(os.path.join("02-DECISIONS", name),
"is numbered %s, and so is %s -- a record's number is how it is cited. Take the next "
"free number across main AND every open pull request; the branch that lands last "
"renumbers" % (number, seen_records[number]))
else:
seen_records[number] = name
for path in sorted(glob.glob(os.path.join(ROOT, "04-ISSUES", "*", "00-report.md"))):
front = frontmatter(path)
if front is None:
@@ -7,7 +7,7 @@ reconstructed: false
extends: 02-DECISIONS/0168-a-converged-machine-is-filtered-by-the-mesh-alone.md
---
# 169. The firewall seat serves its verbs, and a foreign rule set is removed through one of them
# 170. The firewall seat serves its verbs, and a foreign rule set is removed through one of them
## Context
@@ -78,6 +78,25 @@ how the act reaches the machine, recorded on the bus like every other, instead o
| A container's capabilities reach the runtime and its spec; an unknown name is refused | host tests |
| Live | `node-packet-filter.remove@<node>` on the home server and the control node; `node show` reads *the mesh alone* on both; `status` is well |
## Built and proven live, 2026-10-02
> **Progressive insight — 2026-10-02.** The decision stands; these are the facts of its building.
> Written as 0169 for three hours and renumbered to 0170: another record took 0169 on main first,
> and the check that refuses a shared number covered issues only (now records too).
Built in mesh-host 68 (`capabilities` on a container), mesh-controller 212 (the seat's three verbs)
and 213 (the filter file a module names under `filtering.into` counts as declared for a mount — the
module's first build was refused without it), mesh-catalog 216 (the nftables module's runtime and
verbs) and mesh-tools 27 (the console lists a node-scoped seat's verbs with their scope and carries the
machine; before it, the verbs were live on four machines and unreachable from the console —
[issue 199](../04-ISSUES/199-a-node-scoped-seats-verb-could-not-be-called-through-the-console/00-report.md)).
Each machine's holder was issued its bus account with `mesh-controller.issue`, the broker node pushed
first. At 12:46Z the five rule sets ADR 0168 had named were removed through
`node-packet-filter.remove`, three on the home server and two on the control node, each answering
with the commands it ran; the next report read *the mesh alone* on all four machines and `status`
listed nothing under `filtered`. The live row is read. What it cost on the way is
[issue 200](../04-ISSUES/200-the-controllers-answer-to-the-console-is-refused-by-the-bus/00-report.md).
## References
- [ADR 0168](0168-a-converged-machine-is-filtered-by-the-mesh-alone.md), [ADR 0154](0154-the-meshs-own-verbs-are-the-controller-seats-tools.md), [ADR 0159](0159-a-tool-call-names-the-machine-and-a-holder-serves-its-seats-verbs.md), [ADR 0121](0121-a-system-seat-is-named-for-its-scope-and-modules-define-their-own.md)
+1 -1
View File
@@ -180,7 +180,7 @@ python3 00-META/checks/index.py fail if stale
- **0167** — [A membership carries what its module receives, and who the mesh is](0167-a-membership-carries-what-its-module-receives-and-who-the-mesh-is.md)
- **0168** — [A converged machine is filtered by the mesh alone, and the host says what else refuses](0168-a-converged-machine-is-filtered-by-the-mesh-alone.md)
- **0169** — [A machine joins through the tunnel, and the bus is never public](0169-a-machine-joins-through-the-tunnel-and-the-bus-is-never-public.md)
- **0169** — [The firewall seat serves its verbs, and a foreign rule set is removed through one of them](0169-the-firewall-seat-serves-its-verbs.md)
- **0170** — [The firewall seat serves its verbs, and a foreign rule set is removed through one of them](0170-the-firewall-seat-serves-its-verbs.md)
- **0172** — [The lab is a module, and runs a bed when the mesh asks](0172-the-lab-is-a-module-and-runs-a-bed-when-the-mesh-asks.md)
### Its tiers, from the bottom up
+2 -2
View File
@@ -9,7 +9,7 @@ code:
- mesh-host internal/apply (the service that reflects a rule set)
updated: 2026-10-02
decisions:
- 02-DECISIONS/0169-the-firewall-seat-serves-its-verbs.md
- 02-DECISIONS/0170-the-firewall-seat-serves-its-verbs.md
- 02-DECISIONS/0169-a-machine-joins-through-the-tunnel-and-the-bus-is-never-public.md
- 02-DECISIONS/0168-a-converged-machine-is-filtered-by-the-mesh-alone.md
- 02-DECISIONS/0167-a-membership-carries-what-its-module-receives-and-who-the-mesh-is.md
@@ -767,7 +767,7 @@ tests over a fixture report check the recording, the preview's fates, the status
predicate. Live: the home server's record names the predecessor's chain as *other* and `status`
names the machine until the chain is removed by hand.
*2026-10-02, [ADR 0169](../../02-DECISIONS/0169-the-firewall-seat-serves-its-verbs.md):* removing what
*2026-10-02, [ADR 0170](../../02-DECISIONS/0170-the-firewall-seat-serves-its-verbs.md):* removing what
the host reports as *other* is reached through the packet filter seat's `remove` verb, an operator's act
by name on the bus; the seat also serves `rules` and `reload`, and its holder's runtime declares the
`NET_ADMIN` capability on the machine's network. See design 33.
@@ -4,7 +4,7 @@ status: implemented
code: [mesh-controller, mesh-tools]
updated: 2026-10-02
decisions:
- 02-DECISIONS/0169-the-firewall-seat-serves-its-verbs.md
- 02-DECISIONS/0170-the-firewall-seat-serves-its-verbs.md
- 02-DECISIONS/0160-the-mesh-issues-an-assignments-subjects-and-a-runtime-serves-what-it-is-issued.md
- 02-DECISIONS/0159-a-tool-call-names-the-machine-and-a-holder-serves-its-seats-verbs.md
- 02-DECISIONS/0154-the-meshs-own-verbs-are-the-controller-seats-tools.md
@@ -172,7 +172,7 @@ seats' schemas beyond the names their manifests already list.
## The firewall seat's verbs, 2026-10-02
[ADR 0169](../../02-DECISIONS/0169-the-firewall-seat-serves-its-verbs.md). The first node-scoped seat
[ADR 0170](../../02-DECISIONS/0170-the-firewall-seat-serves-its-verbs.md). The first node-scoped seat
to carry verbs: `node-packet-filter` serves `rules` (the filter as the machine enforces it, nftables
and legacy), `reload` (the mesh's own filter from its file) and `remove` (one rule set the mesh did
not write, named as the host reports it under ADR 0168; refusing the mesh's tables, the runtime's
@@ -11,7 +11,7 @@ amended-design:
## What was observed
2026-10-02, the first time a node-scoped seat declared verbs
([ADR 0169](../../02-DECISIONS/0169-the-firewall-seat-serves-its-verbs.md)). The packet filter's
([ADR 0170](../../02-DECISIONS/0170-the-firewall-seat-serves-its-verbs.md)). The packet filter's
holder on every machine served `rules`, `reload` and `remove` on the seat's per-machine subjects, and
the bus admitted them. The console answered every call with *nothing serves
node-packet-filter.rules@<machine>*.