Correct what the coverage document said about actions

I wrote that a module cannot declare an action. It could — the parser
accepted one, and the refusal only came on the machine. The claim was
wrong in the direction that matters: it read as "the design prevents
this", when what prevented it was a check at the far end that nobody
would connect back to the manifest.

Health checks are still the gap most worth closing, but the shape of the
answer is different from what I wrote. An action is not available to a
module at all, so a health check needs a way to say ask this and expect
that without saying run this — closer to a listens entry than to an
action.

Also records the finding itself, because it is a recurring shape here
and not a one-off: a rule enforced only at the far end is enforced and
unusable.
This commit is contained in:
2026-09-01 02:56:05 +02:00
parent 9073d3f2df
commit dea46c3c6c
+12 -3
View File
@@ -82,9 +82,12 @@ head. The module knows its own format because it wrote the rest of the file.
### Health checks — 7 modules ### Health checks — 7 modules
`{type: port|url, expect: …}`. The mesh knows whether a container is running, which is not the `{type: port|url, expect: …}`. The mesh knows whether a container is running, which is not the
same as whether it answers — a distinction this project has paid for twice already. An `action` same as whether it answers — a distinction this project has paid for twice already.
with a `verify` is exactly this shape, but actions may not arrive over the link, so a module
cannot declare one. An `action` carries a `verify` and is exactly this shape. **It is not available to a module**: the
link may not carry a command to run ([ADR 0005](../../02-DECISIONS/0005-the-node-host.md)), and a
module's resources reach a machine over the link. So a health check needs a way to say *ask this
and expect that* without saying *run this* — closer to a `listens` entry than to an action.
**This is the gap most worth closing**, because *running* and *answering* being conflated is a **This is the gap most worth closing**, because *running* and *answering* being conflated is a
class of fault, not an inconvenience. class of fault, not an inconvenience.
@@ -140,3 +143,9 @@ same module. There is one derivation here, and there should stay one.
**A live listing returned credentials in plaintext.** Not a coverage question, but the reason **A live listing returned credentials in plaintext.** Not a coverage question, but the reason
sealing is worth its inconvenience. sealing is worth its inconvenience.
**A rule was enforced only at the far end.** A module may not declare an action, and the host
refused one correctly — but the control plane accepted it into the catalogue, resolved it and
pushed it, so the refusal arrived on a machine with nothing tying it back to the manifest. The
rule held; it was just unusable, which is the same shape as the network shape that cost five
failing tests before anyone read the host's log. It is now refused where it is written.