4.2 KiB
topic, status, date, deciders, reconstructed, extends
| topic | status | date | deciders | reconstructed | extends |
|---|---|---|---|---|---|
| the mesh | accepted | 2026-10-02 | jochen | false | 02-DECISIONS/0136-a-step-gates-its-module-not-the-machine.md |
187. A dead tracker is not the machine's failure
Context
The home server had not applied a declaration cleanly since midday. One run-once step — the one that writes a media app's download clients and indexers through the app's own API — exited non-zero, forty-nine times over six hours, for one public tracker that had stopped answering. The step's own words: the entry was written, and the app's test of it then failed with a 400 from the indexer proxy. The machine reported not doing what it was told for the rest of the day.
What that gated matters more than the step. A converged machine retires the firewall it was found with only after a clean apply (ADR 0168), so that machine went on recording its found front end as merely retired long after the package had been uninstalled (ADR 0180). A dead public tracker was holding a firewall record hostage, which is not a connection anybody would design.
The step already knew this was not its business. It had a rule for exactly this: an entry the mesh only found and re-pointed, rather than one it was told to make, whose feed is gone, is said and left as found — failing the node's apply on every heartbeat for it reports the mesh as wrong about a tracker. The rule was there and matched one shape of the fault. An app can refuse to save such an entry, and it can save it and then fail its own test; saving validates settings, and the test runs a live search. The rule caught the first and let the second through.
Decision
1. An entry the mesh only found is never the machine's failure. Whatever shape the app's refusal takes — it would not save it, or it saved it and its own test fails — an indexer the mesh found and re-pointed is reported as a notice and left as found. What decides is whose entry it is, not which sentence the app returned.
2. What the mesh is answerable for is the plumbing. That the entry exists, points at this mesh's indexer proxy, and carries the credential the mesh delivered — which was checked against the proxy before anything was written. Whether a public tracker answers today is not the mesh's to promise, and a machine that reports itself broken because one did is lying about itself.
3. An entry the operator listed is theirs to insist on. An indexer named in the step's settings is one the mesh was told to make, and it still fails the step when it cannot be made to work. The notice says so, and says that listing the indexer is how to turn it back into a failure.
Consequences
- The home server applies cleanly again, and everything a clean apply gates — its found firewall's record among it — follows.
- A tracker that dies is a line in a report rather than a machine that reads as broken. An operator who wants it gone removes the entry or repairs the feed; the mesh says which, every time it runs.
- The four Servarr modules carry one byte-identical copy of this step each (ADR 0069), so the change lands in four places and a test refuses any drift between them.
- It does not widen to a download client: one the mesh was told to write and cannot is still a failure, because the mesh chose it and nothing else will fix it.
How this is checked
| Rule | Checked by |
|---|---|
| A found feed whose tracker answers an error after the entry was written is a notice | the step's tests, with the home server's own message and the app's two validations modelled apart |
| An indexer the settings list is still a failure | the same test |
| The four copies of the step do not drift | the step's own sameness test |
| Live | the home server applies cleanly, and its found firewall reads removed |