Files
hq/04-ISSUES/003-firewall-scope-is-read-by-no-code/00-report.md
T
jochen daa9f171ae
mesh/merge-gate pass: the change touches no module of the mesh's graph
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery delivered
Issue reports carry only opened: the tracker holds every status, so no copy can drift
The import of slice 3 (ADR 0275) was checked against every folder: no report changed since the
commit it read, and the tracker holds each report's status, owner, fix, design amendment, replay
and closing day. The keys are removed from all 361 reports, cycle.py refuses them in any report,
and the playbooks, skills and READMEs that still pointed at them name the tracker instead.
2026-10-10 17:44:18 +02:00

63 lines
3.0 KiB
Markdown

---
opened: 2026-08-22
---
# 003 — A firewall rule's `scope:` is read by no code
## Symptom
Five module manifests declare a `scope:` key on firewall rules. The key is not part of the
firewall rule type and nothing reads it. Real scoping is expressed by a different field.
A manifest can therefore appear to restrict a port and restrict nothing.
## Why this matters
This is the failure mode [`how-we-build.md`](../../00-META/how-we-build.md) names directly:
*an unenforced rule is indistinguishable from a wrong one, and costs more, because people
believe it.* Here it is worse than unenforced — the declaration reads as a restriction, so a
reviewer checking whether a port is scoped will find that it is, and be wrong.
It also says something about the manifest as a whole: an unknown key is accepted silently. Any
misspelled or invented key behaves this way, and this one was found by reading rather than by
any check.
## Evidence
- Five manifests carry the key. Zero code paths consume it.
- Recorded as an observation on 2026-08-22.
## Open questions
- Should the manifest reject unknown keys outright? That is the general fix; this is one
instance of it.
- Were the five declarations intended to restrict something that is currently open? Each needs
checking against what the node actually exposes — the declaration cannot be trusted either
way.
## How it is answered
*2026-08-31.* Both halves, in Novox Mesh. HAL keeps the fault until its provisioning is switched
off, which is what this issue is now waiting on rather than a fix of its own — patching `scope:`
into something that works would mean implementing it twice, in the system being replaced.
**The unknown key.** A manifest is parsed strictly: an unknown key is refused with the key named,
the discipline the host's declaration parser has always had. `scope:` would not survive being
written today, and neither would a misspelling of anything else. This is the general fix — the
issue's own observation was that *any* invented key behaved this way, and that the one instance
was found by reading rather than by any check.
**The rule that restricts nothing.** `scope:` is not reimplemented. A module says what it listens
on and **who may reach it**, and saying from where is required rather than defaulted: a rule with
no source is open, and must say so rather than appear to restrict something. A machine's whole
rule set is then derived from every module assigned to it — so there is no second list to keep in
step, which is the condition that let the first one drift out of use unnoticed.
**And it is enforced, which is the part that makes this different from before.** The mesh renders
the rule set; a service on the node is declared to reflect that file, so replacing it restarts
what loads it. Proven in the lab against two real ports on a real machine: the declared one
answers from another machine, the undeclared one does not, and removing the module that wanted the
port closes it with nobody editing a rule.
The design is [`03-DESIGN/01-to-be/08-connectivity.md`](../../03-DESIGN/01-to-be/08-connectivity.md) §4.