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..85fc440 --- /dev/null +++ b/04-ISSUES/079-every-machine-is-named-twice-over/01-diagnosis.md @@ -0,0 +1,31 @@ +# 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. + +*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. + +*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. + +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/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..5951201 --- /dev/null +++ b/04-ISSUES/080-a-cache-grant-lets-the-consumer-flush-the-server/01-diagnosis.md @@ -0,0 +1,14 @@ +# 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. + +*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.