c85262111c
gates / gates (push) Successful in 23s
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
76 lines
4.7 KiB
Markdown
76 lines
4.7 KiB
Markdown
# 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.
|