Files
hq/04-ISSUES/226-the-stores-sweep-stops-at-the-first-reference-recorded-with-an-address/00-report.md
T
jschoubben bc64c5c187 ADR 0201 → 0202, and three issues from the night it shipped
The derived-value record is renumbered a second time: the key-value-buckets
record took 0201 while this waited to merge, as the bundles record took 0188
before it. Both times free when chosen, taken by the time it landed. cycle.py
caught it; three repositories cite this record, so the number matters.

225 — a provisioner has not been able to read its grant secrets since 01:30,
when a module's own code left its container and the files stayed root's. Four
thousand refusals, each worded as patience, and two consumers unserved. Not
from ADR 0202 or 0189, which landed hours later; dates in the report.

226 — the store's sweep stops at the first reference recorded with an address
and collects nothing. A guard that cannot tell 'I will not ask about this'
from 'it would not answer' stops the wrong amount of work.

227 — the photo app's admin client asks for the port the proxy holds. A module
pinned months behind carries everything its branch gained, the first time
anything makes it move.
2026-10-04 04:33:45 +02:00

2.8 KiB

status, opened, located-in, fixed-by, amended-design
status opened located-in fixed-by amended-design
open 2026-10-04
mesh-controller cmd/mesh-controller/collect.go
mesh-controller internal/inventory/collection.go

226 — The store's sweep stops at the first reference recorded with an address, so it collects nothing at all

What was observed

The first live run of ADR 0189's sweep, 2026-10-04, printed on every build:

the artifact store kept 127.0.0.1:5100/mesh-tools/build@sha256:0de48cd3…, so nothing more was
  asked of it: 127.0.0.1:5100/mesh-tools/build@sha256:0de48cd3… is not a reference into the
  mesh's artifact store
1681 more to collect; the next build asks again

Nothing is collected, and nothing ever will be. The store holds 1681 artifacts the mesh no longer keeps and the feature that exists to remove them is inert.

Why

Two correct decisions meeting badly.

A reference recorded before references were kept without an address is 127.0.0.1:5100/<path>@sha256:… rather than artifact-store://<path>@sha256:… (04-ISSUES/102). LetGo rightly refuses to compose a delete for a reference whose shape it does not recognise — that refusal is what keeps the sweep from reaching something that is not the mesh's.

The sweep stops at the first refusal, because "a store that refuses one refuses all of them" — deletion disabled, the store down, the network gone — and pushing through would mean a hundred identical failures in front of whoever was building something. That reasoning is right for the store refusing. It is wrong for this record being unreadable.

So one old record, early in the oldest-first order, halts the whole sweep for ever.

Why it matters beyond this instance

A guard that cannot tell "I will not ask about this" from "it would not answer" stops the wrong amount of work. The two deserve opposite responses: skip one, abandon the other. Collapsing them into "an error" is how a bounded, cautious loop becomes a loop that does nothing — and it reports the right number while doing it, which is what made it look healthy.

What a fix has to settle

  • A reference the sweep cannot address is skipped, and the sweep goes on — it is a fact about that record, not about the store.
  • Recorded() already normalises the old form to the kept one, and is what the rest of the mesh uses for exactly these references. The sweep should normalise before asking rather than refuse.
  • Only a refusal by the store ends a sweep.
  • How it is checked: a sweep over records holding one address-recorded reference and one kept one collects the second; a sweep against a store that refuses stops at the first.