The mesh runs its own registry, certifies its own names, and computes its own filtering
Issue 003 is answered in both halves: manifests are parsed strictly, and a module says what it listens on and from where rather than carrying a key nothing reads. The design records what was built and how each part is checked. Issue 013 is new, found by reading while writing the first module that has both a computed file and a service that needs it. The file arrived second. It failed, then the next reconcile fixed it, which is why nothing caught it.
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
---
|
||||
status: open
|
||||
status: resolved
|
||||
opened: 2026-08-22
|
||||
located-in: []
|
||||
fixed-by:
|
||||
amended-design:
|
||||
located-in: [mesh-control]
|
||||
fixed-by: mesh-control — a machine's filtering is computed from what it was assigned
|
||||
amended-design: 03-DESIGN/01-to-be/08-connectivity.md
|
||||
---
|
||||
|
||||
# 003 — A firewall rule's `scope:` is read by no code
|
||||
@@ -38,3 +38,29 @@ any check.
|
||||
- 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.
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
---
|
||||
status: resolved
|
||||
opened: 2026-08-31
|
||||
located-in: [mesh-control]
|
||||
fixed-by: mesh-control — what the mesh computes is applied before what the module declared
|
||||
amended-design:
|
||||
---
|
||||
|
||||
# 013 — A file the mesh computes arrives after the service that needs it
|
||||
|
||||
## Symptom
|
||||
|
||||
Everything the control plane computes for a module — a certificate, a sealed credential, a bound
|
||||
file, a rule set — was placed **after** that module's own resources in the declaration. The host
|
||||
applies resources in the order it is given and
|
||||
[does not sort](../../02-DECISIONS/0005-the-node-host.md), so a service or container declared in a
|
||||
manifest was applied **before** the file it depends on existed.
|
||||
|
||||
On the first apply the service starts against a missing file and fails. The next reconcile finds
|
||||
the file there and starts it.
|
||||
|
||||
## Why this matters
|
||||
|
||||
**It repairs itself, which is why nothing caught it.** A fault that is gone by the second attempt
|
||||
is worse than one that persists: what gets remembered is that the thing works, and the failed
|
||||
first apply is read as a machine that was briefly slow. The mesh reports a failure, then reports
|
||||
success, and nobody looks again.
|
||||
|
||||
It was also invisible to every test that existed, because none of them combined the two halves.
|
||||
Modules with computed files declared no service; modules with a service needed no computed file.
|
||||
The fault lived exactly in the gap between two repositories' assumptions — the control plane
|
||||
deciding an order, the host promising not to change it — which is the shape this folder exists for.
|
||||
|
||||
Found by reading, while writing the first module that has both: a firewall whose service must
|
||||
reflect a rule set the mesh computes.
|
||||
|
||||
## Evidence
|
||||
|
||||
`internal/catalogue/declaration.go` built each module's resource list as
|
||||
`append(module's own, computed...)` in six places — certificate, authority, needs, secrets, grants,
|
||||
bindings. `internal/apply/apply.go` iterates `d.Resources` in order, and
|
||||
`internal/declaration/declaration_test.go` states the rule directly: *order is stated, not derived.
|
||||
The host must not sort.*
|
||||
|
||||
## What was done
|
||||
|
||||
The computed resources are assembled first and the module's own resources follow. Nothing the mesh
|
||||
computes is derived from a module's resources, so the order is unconditionally right rather than a
|
||||
heuristic — there is no case where a module's resource must precede a file the mesh made for it.
|
||||
|
||||
Merged after the computed-resources branch, which replaces a module's resources wholesale and
|
||||
would otherwise discard everything the mesh had made for it.
|
||||
|
||||
*Checked by a module declaring a service that reflects a rule set, asserting the rule set is first;
|
||||
and by a module whose resources are computed elsewhere, asserting its credential survives and is
|
||||
still first — the case the merge point exists for.*
|
||||
Reference in New Issue
Block a user