docker updates: an unscoped sweep over an empty listing still empties and persists the verdict map #55

Open
opened 2026-08-21 23:21:37 +02:00 by julian · 0 comments
Owner

Residual from the approving review on #44 — pre-existing, explicitly out of that PR's scope, filed as the follow-up it asked for (alongside #39).

seededFromStorage gates the prune, not the rebuild. An unscoped refreshUpdates replaces state.updates with checked, built from whatever state.stacks holds — so a sweep tick over an empty full listing empties the map and persists it, haveFullListing notwithstanding:

register() seeded with nginx:1.26 + postgres:16, engine answers []
await ticks.get("updates")!()   // full poll (empty) + unscoped sweep

PROBE3 memory: []  disk: []

Pre-existing at the merge base (pruneUpdates(project ? merged : checked, state.stacks) + unconditional storage.set wiped there too); #44 strictly narrowed the class. The fix is a policy call, not a mechanical guard: a host that genuinely emptied must eventually drop its verdicts, so "skip when the listing is empty" is really "how long may a phantom outlive its stack". Same reachability caveat as the other findings — bare-process deployments only; containerised OpsDeck always lists itself.

Source: #44 (comment) (residual section).

Residual from the approving review on #44 — pre-existing, explicitly out of that PR's scope, filed as the follow-up it asked for (alongside #39). `seededFromStorage` gates the *prune*, not the *rebuild*. An unscoped `refreshUpdates` replaces `state.updates` with `checked`, built from whatever `state.stacks` holds — so a sweep tick over an empty full listing empties the map and persists it, `haveFullListing` notwithstanding: ``` register() seeded with nginx:1.26 + postgres:16, engine answers [] await ticks.get("updates")!() // full poll (empty) + unscoped sweep PROBE3 memory: [] disk: [] ``` Pre-existing at the merge base (`pruneUpdates(project ? merged : checked, state.stacks)` + unconditional `storage.set` wiped there too); #44 strictly narrowed the class. The fix is a policy call, not a mechanical guard: a host that genuinely emptied must eventually drop its verdicts, so "skip when the listing is empty" is really "how long may a phantom outlive its stack". Same reachability caveat as the other findings — bare-process deployments only; containerised OpsDeck always lists itself. Source: https://git.imhof.cloud/OpsDeck/core/pulls/44#issuecomment-1035 (residual section).
Sign in to join this conversation.
No labels
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
OpsDeck/core#55
No description provided.