Part 0 — floor raised to 0.260.0, MinAgent 0.131.0 declared. 3 boxes below, all down or blocked; both demo boxes SERVED. Part 1 (R-610) — the DANGEROUS power cut, measured three times with three apps and two cut mechanisms. All ended honest: resumed, completed, and pinned/installed/live compose/docker inspect all agreed. vikunja's 2.6.0 migration had ALREADY run 0.64 s after the cut decision and the seeded data read back intact — so the branch that is one step from old-binary-on-migrated-database is now evidence, not argument. Instrument limit stated: `starting` lasts under a second; all three landed in `verifying`, which RecoverUpdates handles in the same branch. Part 3 (R-611) — the night the previous session skipped without saying so. An app updated with nobody pressing anything; a terminally-refused app was pressed exactly once and never again over three passes. The unattended HOLD was NOT produced: the within-a-major rule correctly refused the broken edge before it was attempted, so Q4 still rests on the attended hold from slice 4. Said plainly rather than implied. Rows: closed R-608/609/610/611; opened R-612 (P1 wishlist unusable on a fresh install, and its error is a lie), R-613 (uptime-kuma healthy on its setup wizard), R-614 (stale update phase survives a redeploy). R-520's pointer corrected. Catalog: two drill pairs, both reverted; every image line byte-identical to ff9717d3. The alpine:3.20 negative control a security review flagged is cleared. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
4.7 KiB
09 — THE UNATTENDED NIGHT: an app updates with nobody pressing anything
This is the phase the previous session's brief contained and did not run, and did not say so
(R-611). It runs here. The caller is unattended-caller.py in this directory — EVIDENCE, NOT
PRODUCT: it presses exactly POST /api/stacks/<n>/update, the same button a person presses, and
nothing else. No controller code was added for it. Guest 9202, controller v0.261.0.
Scenario F — the success night: PROVEN
uptime-kuma 2.5.0 → 2.5.1 was applied by the caller with no human action, against a real
one-step catalog edge (DRILL 2, ae08a037fd68). Confirmed on the box afterwards:
uptime-kuma installed = louislam/uptime-kuma:2.5.1 catalog = louislam/uptime-kuma:2.5.1
updating = False update_phase = done hold = none
HONEST GAP, and it is the coordinator's own instrumentation error: that first run's stdout was
piped through tail, which buffers, and the run was later killed — so the caller's own log lines
for the F press were lost. The OUTCOME is solid (the box moved 2.5.0 → 2.5.1 and only the caller
pressed it), but the per-pass log for F is gone. The second run below was written straight to a file
for exactly this reason. Recorded rather than quietly omitted.
Scenario G — two results, and the first one is the more interesting
G-a. The deliberately broken edge was NEVER ATTEMPTED — the safety rule filtered it first
The C3-class negative control was vikunja: 2.6.0 → alpine:3.20. The caller skipped it, because
alpine:3.20 and vikunja/vikunja:2.6.0 are different repositories and therefore cannot be ordered,
so the edge is "across" and belongs to a human (09 §3 decision 3, §3b Q3). The box was never asked
to run it: vikunja ended the night still on 2.6.0, no update, no hold, untouched.
That is a real finding for Slice 6 and it cuts both ways. The within-a-major rule is the FIRST line of defence and it works — a catalog edge that cannot be ordered never reaches the guarded update unattended. But it also means this shape of broken edge cannot be used to measure the unattended HOLD path, because the rule that makes automatic updates safe is the same rule that refuses it.
G-b. The no-retry property, PROVEN over three passes
Reverting the catalog (f5f6a152b513) left all four apps running something NEWER than the catalog —
R-524's Ahead state. The caller then had a genuine TERMINAL refusal to react to:
pass 1/3 glance BEHIND and within a major — pressing Update
glance REFUSED reason=downgrade TERMINAL — will not press again.
„Ez a változat újabb a katalógusban lévőnél — visszalépés csak az
üzemeltető kérésére."
... the same for uptime-kuma, vikunja and wishlist ...
pass 2/3 (nothing)
pass 3/3 (nothing)
summary outcomes={} never_again=['glance','uptime-kuma','vikunja','wishlist']
Four apps, pressed exactly once each, then never again across two further passes. Nothing on the box changed: no update ran, no hold was set, no journal was written.
This is R-524 and R-609 working together end to end, unattended. Before R-609 put reason on the
wire the caller would have had only a Hungarian sentence to parse, and the only safe readings were
"give up on everything" or "press for ever". The full log is 09-unattended-night.log.
What Slice 6's design now knows that it did not
| question | answer, from measurement |
|---|---|
| how long does one app take end to end, unattended? | 51 s – 1 m 26 s for these four small apps, including the health wait — see 04/05/07 |
| does the caller need new controller code? | No. It presses the existing guarded Update and reads the existing state. |
| can it tell "wait" from "never"? | Yes, since v0.261.0 — and not before |
| does the within-a-major rule hold? | Yes, and it is the first thing that fires — G-a |
| what does a held app look like the next morning? | STILL UNKNOWN unattended — see below |
NOT MEASURED, stated plainly
The unattended HOLD path. 09 §3b Q4 asks who is told when an automatic update ends HELD. This
night never produced a hold, because the only failing edge available was one the safety rule
correctly refused (G-a). Measuring it needs an edge that passes the within-a-major test and still
fails its health check — same repository, same major version, a tag that starts and does not serve.
Real images rarely offer one, so this probably needs a purpose-built image rather than a catalog
move. Q4 therefore still rests on the ATTENDED hold measured in slice 4 (v0.238.0, Scenario F),
not on an unattended one. Recorded as the gap it is.