From 17cc36069f15bb19a1f9b816c742603984bd08e5 Mon Sep 17 00:00:00 2001 From: jochen Date: Tue, 22 Sep 2026 01:13:29 +0200 Subject: [PATCH 1/4] Issue 079: every machine named twice over, found by the large mesh bed; what running that bed cost, on 074 --- .../01-diagnosis.md | 11 +++++++ .../00-report.md | 32 +++++++++++++++++++ .../01-diagnosis.md | 12 +++++++ 3 files changed, 55 insertions(+) create mode 100644 04-ISSUES/079-every-machine-is-named-twice-over/00-report.md create mode 100644 04-ISSUES/079-every-machine-is-named-twice-over/01-diagnosis.md diff --git a/04-ISSUES/074-a-mesh-test-wears-a-catalogue-modules-name/01-diagnosis.md b/04-ISSUES/074-a-mesh-test-wears-a-catalogue-modules-name/01-diagnosis.md index 03ab2ab..6801b0b 100644 --- a/04-ISSUES/074-a-mesh-test-wears-a-catalogue-modules-name/01-diagnosis.md +++ b/04-ISSUES/074-a-mesh-test-wears-a-catalogue-modules-name/01-diagnosis.md @@ -47,3 +47,14 @@ its long idleness had hidden: the consumer fixture's login exceeded a backend's upstream artifact by bare image ID, which a registry copy cannot fetch since ADR 0096 — retired, since genesis installs the catalogue's builder and proves the same. The large test as a whole has not been run end to end; its renamed tests and the tests around them have. + +*2026-09-22.* The large mesh test was run end to end, for the first time in weeks: 12 of 25 passed. +Everything that failed was the bed lagging the mesh, and one defect of the mesh's own. The bed now +derives the anchor's filter after placing it on the overlay (ADR 0088), declares the ports its +fixtures listen on, waits for an image pulled at apply, starts the hand-started host and builder +once on a warm return, and reads the resolver modules from the catalogue instead of the example +modules that moved there. Three more tests were retired for the catalogue beds that prove them +(the modules resolving together and the forge, whole-mesh-novox; the cache grant, the grant bed) +and one for what every later test proves (the hub filtered without severing the mesh). The +defect: every machine named twice over in the files the mesh writes +([issue 079](../079-every-machine-is-named-twice-over/00-report.md)). diff --git a/04-ISSUES/079-every-machine-is-named-twice-over/00-report.md b/04-ISSUES/079-every-machine-is-named-twice-over/00-report.md new file mode 100644 index 0000000..c375cb0 --- /dev/null +++ b/04-ISSUES/079-every-machine-is-named-twice-over/00-report.md @@ -0,0 +1,32 @@ +--- +status: resolved +opened: 2026-09-22 +located-in: [mesh-controller internal/catalogue (facts)] +fixed-by: mesh-controller multiple-fixes (the facts take a name as the control plane keys it, internal or bare, and write each machine once); a unit test holds both keyings to the same files +--- + +# 079 — Every machine is named twice over in the hosts file and the resolver's zones + +## Symptom + +The hosts file the mesh writes on every machine, and the zones file it hands a resolver, name each +machine as `.internal.internal`, with the intended name `.internal` in the +hosts file's second column. Names still resolve on the machine itself, because the second column +matches, so nothing noticed. A resolver serving the zones answers for `*..internal.internal` +and for nothing under `.internal`, so a service named under a machine does not resolve +from anywhere. + +Found by running the large mesh bed end to end for the first time since the mesh's knowledge became +a fact a module asks for: its name test read the zones back. No smaller bed reads them. + +## Why it matters beyond the instance + +Two functions agreed on a contract nobody wrote down: the caller keyed the map by the internal name, +the facts appended the suffix to a bare one. Each was tested alone, with its own keying, and both +passed. A file the mesh writes and nothing reads back in a test is a file that can be wrong for +as long as it takes someone to look. + +## What would close it + +The facts take either keying and write each machine once, held by a test that feeds both. And a bed +reads the files back — the large mesh bed does now. diff --git a/04-ISSUES/079-every-machine-is-named-twice-over/01-diagnosis.md b/04-ISSUES/079-every-machine-is-named-twice-over/01-diagnosis.md new file mode 100644 index 0000000..a56b7af --- /dev/null +++ b/04-ISSUES/079-every-machine-is-named-twice-over/01-diagnosis.md @@ -0,0 +1,12 @@ +# Diagnosis — 2026-09-22 + +1. The control plane collects every placed machine's name and address for a resolution keyed by + the internal name (`homer.internal`), because that is the map every container is given as its + hosts. The facts that render the hosts file and the resolver's zones took the same map as bare + names and appended `.internal` to each — their unit tests fed them bare names and passed. +2. Fixed in the facts: a name is read as either form, and each machine is written once as + `.internal` with its bare name beside it. A test feeds both keyings and holds the files + equal, and holds the zones free of a doubled suffix. + +**Located in:** the facts. Not a decision. Proven by the unit test and by the large mesh bed's name +tests, once its controller image is rebuilt from the fix. -- 2.54.0 From e31e077fc8aff32d578619a12f27d40ccea84829 Mon Sep 17 00:00:00 2001 From: jochen Date: Tue, 22 Sep 2026 01:27:53 +0200 Subject: [PATCH 2/4] Issue 079: the suffix is handed down, not written twice --- .../079-every-machine-is-named-twice-over/01-diagnosis.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/04-ISSUES/079-every-machine-is-named-twice-over/01-diagnosis.md b/04-ISSUES/079-every-machine-is-named-twice-over/01-diagnosis.md index a56b7af..6942653 100644 --- a/04-ISSUES/079-every-machine-is-named-twice-over/01-diagnosis.md +++ b/04-ISSUES/079-every-machine-is-named-twice-over/01-diagnosis.md @@ -10,3 +10,8 @@ **Located in:** the facts. Not a decision. Proven by the unit test and by the large mesh bed's name tests, once its controller image is rebuilt from the fix. + +*On review.* The first fix wrote the suffix a second time, in the facts, which is the shape that +produced the defect: two places composing one name. The control plane now hands the suffix it +composed the names with down to the facts, so an operator who chose another gets that one and +nothing appended. What remains unproven by a bed is a mesh with a suffix other than the default. -- 2.54.0 From f760bf632c921eece4655572fc49053146ad020a Mon Sep 17 00:00:00 2001 From: jochen Date: Tue, 22 Sep 2026 01:39:29 +0200 Subject: [PATCH 3/4] Issue 080: a cache grant let the consumer flush the server; 079: the names follow the resolver's rule for the private network --- .../01-diagnosis.md | 7 +++++ .../00-report.md | 29 +++++++++++++++++++ .../01-diagnosis.md | 9 ++++++ 3 files changed, 45 insertions(+) create mode 100644 04-ISSUES/080-a-cache-grant-lets-the-consumer-flush-the-server/00-report.md create mode 100644 04-ISSUES/080-a-cache-grant-lets-the-consumer-flush-the-server/01-diagnosis.md diff --git a/04-ISSUES/079-every-machine-is-named-twice-over/01-diagnosis.md b/04-ISSUES/079-every-machine-is-named-twice-over/01-diagnosis.md index 6942653..c60b1ae 100644 --- a/04-ISSUES/079-every-machine-is-named-twice-over/01-diagnosis.md +++ b/04-ISSUES/079-every-machine-is-named-twice-over/01-diagnosis.md @@ -15,3 +15,10 @@ tests, once its controller image is rebuilt from the fix. produced the defect: two places composing one name. The control plane now hands the suffix it composed the names with down to the facts, so an operator who chose another gets that one and nothing appended. What remains unproven by a bed is a mesh with a suffix other than the default. + +*Later.* With the suffix right, the large bed's name test asked the second half of its question: +a machine that leaves the private network must not be answered for. The names were every placed +machine with an address, while the resolver's "on the private network" is a machine that also +runs the module that puts it there. The names follow the resolver's rule now — one predicate, +used by both — held by a controller test that unassigns one machine's networking and reads the +names back. diff --git a/04-ISSUES/080-a-cache-grant-lets-the-consumer-flush-the-server/00-report.md b/04-ISSUES/080-a-cache-grant-lets-the-consumer-flush-the-server/00-report.md new file mode 100644 index 0000000..5eae272 --- /dev/null +++ b/04-ISSUES/080-a-cache-grant-lets-the-consumer-flush-the-server/00-report.md @@ -0,0 +1,29 @@ +--- +status: resolved +opened: 2026-09-22 +located-in: [mesh-catalog modules/redis (the provisioner's ACL)] +fixed-by: mesh-catalog multiple-fixes (the consumer's ACL user loses the dangerous command category); proven by the grant end-to-end bed, which now asserts a write outside the consumer's keys and FLUSHALL are refused +--- + +# 080 — A cache grant lets the consumer flush the server + +## Symptom + +The cache provider's provisioner creates each consumer an ACL user confined to keys under its own +login and allowed every command. A key pattern confines only commands that name keys. `FLUSHALL`, +`FLUSHDB`, `CONFIG`, `SHUTDOWN` and the rest of the dangerous category name none, so a consumer +granted "its own keys" could wipe every other consumer's, or stop the server. + +Found by carrying the large mesh bed's retired tenancy assertions into the grant end-to-end bed: +`FLUSHALL` as the consumer answered `OK`. + +## Why it matters beyond the instance + +A grant is the mesh's promise that a consumer gets what it asked for and nothing else. The +promise was checked on the key pattern and never on the command set, and the one bed that had +asked was retired before it was run against the catalogue's module. + +## What would close it + +The ACL user is allowed the ordinary command set minus the dangerous category, and the grant bed +asserts a write outside the consumer's keys and a `FLUSHALL` are both refused. diff --git a/04-ISSUES/080-a-cache-grant-lets-the-consumer-flush-the-server/01-diagnosis.md b/04-ISSUES/080-a-cache-grant-lets-the-consumer-flush-the-server/01-diagnosis.md new file mode 100644 index 0000000..0795dff --- /dev/null +++ b/04-ISSUES/080-a-cache-grant-lets-the-consumer-flush-the-server/01-diagnosis.md @@ -0,0 +1,9 @@ +# Diagnosis — 2026-09-22 + +1. The provisioner's `ACL SETUSER` gave `~:*` and `+@all`. Redis applies a key pattern to + commands that take keys; a command taking none is governed by the command categories alone, + and `@all` includes `@dangerous`. +2. Fixed with `-@dangerous` after `+@all`. `KEYS` goes with the category; `SCAN` stays, and is + what a consumer scoped to a prefix should use. + +**Located in:** the redis module's client. Not a decision. Proven by the grant end-to-end bed. -- 2.54.0 From 35e44c3e5e30e711de436bc2ec7383d9abc2c394 Mon Sep 17 00:00:00 2001 From: jochen Date: Tue, 22 Sep 2026 02:04:29 +0200 Subject: [PATCH 4/4] Issue 081 opened (a cache consumer does not use its login); 079 and 080 diagnoses carry the review's consequences --- .../01-diagnosis.md | 7 +++++ .../01-diagnosis.md | 5 +++ .../00-report.md | 31 +++++++++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 04-ISSUES/081-a-cache-consumer-does-not-use-the-login-it-was-granted/00-report.md diff --git a/04-ISSUES/079-every-machine-is-named-twice-over/01-diagnosis.md b/04-ISSUES/079-every-machine-is-named-twice-over/01-diagnosis.md index c60b1ae..85fc440 100644 --- a/04-ISSUES/079-every-machine-is-named-twice-over/01-diagnosis.md +++ b/04-ISSUES/079-every-machine-is-named-twice-over/01-diagnosis.md @@ -22,3 +22,10 @@ machine with an address, while the resolver's "on the private network" is a mach runs the module that puts it there. The names follow the resolver's rule now — one predicate, used by both — held by a controller test that unassigns one machine's networking and reads the names back. + +Two consequences of the one predicate, on review. The filter's "from the mesh" set is that same +set now, so a rule admits exactly the machines the mesh names. And a machine whose assigned set +fails to resolve is no longer on the network in the mesh's eyes: its name leaves every other +machine's hosts file and every resolver's zones on the next push, and the mesh's report of that +machine's failure is what says why — the stated preference for a name that fails at once over a +connection that hangs, at the cost of one machine's failure being visible mesh-wide. diff --git a/04-ISSUES/080-a-cache-grant-lets-the-consumer-flush-the-server/01-diagnosis.md b/04-ISSUES/080-a-cache-grant-lets-the-consumer-flush-the-server/01-diagnosis.md index 0795dff..5951201 100644 --- a/04-ISSUES/080-a-cache-grant-lets-the-consumer-flush-the-server/01-diagnosis.md +++ b/04-ISSUES/080-a-cache-grant-lets-the-consumer-flush-the-server/01-diagnosis.md @@ -7,3 +7,8 @@ what a consumer scoped to a prefix should use. **Located in:** the redis module's client. Not a decision. Proven by the grant end-to-end bed. + +*On review.* `INFO` is in the dangerous category and several client libraries ask it at connect; +it reads nothing a consumer keeps, so it is allowed back. Whether the catalogue's two cache +consumers need anything else the category removes is unverified — and moot until they present the +login they were granted ([issue 081](../081-a-cache-consumer-does-not-use-the-login-it-was-granted/00-report.md)). diff --git a/04-ISSUES/081-a-cache-consumer-does-not-use-the-login-it-was-granted/00-report.md b/04-ISSUES/081-a-cache-consumer-does-not-use-the-login-it-was-granted/00-report.md new file mode 100644 index 0000000..6e1d91d --- /dev/null +++ b/04-ISSUES/081-a-cache-consumer-does-not-use-the-login-it-was-granted/00-report.md @@ -0,0 +1,31 @@ +--- +status: open +opened: 2026-09-22 +located-in: [mesh-catalog modules/n8n, mesh-catalog modules/baserow] +--- + +# 081 — A cache consumer does not use the login it was granted + +## Symptom + +Two catalogue modules require the cache and are given a login and a password under a keyspace of +their own ([issue 080](../080-a-cache-grant-lets-the-consumer-flush-the-server/00-report.md)), +and neither tells its software the login: each hands it the host, the port and the password only, +so the software authenticates as the server's default user and writes wherever it likes — or is +refused, if the default user is closed. The grant is honoured by the provider and ignored by the +consumer. + +Found on review of issue 080, by reading the two manifests. Not run: no bed installs either +module against the catalogue's cache and reads what it wrote. + +## Why it matters beyond the instance + +A grant is two ends agreeing. The provider's end is checked by the grant bed; the consumer's end, +that the software actually presents what it was given, is checked by nothing but the module +working — and a module that works as the default user works. + +## What would close it + +Each module passes the login it was bound (`${bound:redis-cache:as}`) to its software's username +setting, and a bed installs one of them against the catalogue's cache and reads back that its keys +sit under its login. -- 2.54.0