R-618 ESCALATION — measured live, 2026-09-21, guest 9202, controller v0.261.0
=============================================================================

tandoor's guarded Update from 2.6.13 to 2.6.15 was pressed at 21:16:47 and entered `verifying` at
21:17:46. While it sat there, the app was asked the same question the household would ask, through
the household's own front door:

  21:18:28   curl -H 'Host: recipes.enkisfelhom.hu' https://192.168.0.114/accounts/login/
             -> HTTP 200

  21:18:28   docker ps: tandoor  ghcr.io/tandoorrecipes/recipes:2.6.15  Up 25 seconds

So the NEW version was installed and SERVING. The controller nevertheless could not see it, because
`.felhom.yml` probes `type: http, port: 8080` and the tandoor container listens on **80 only**.

The consequence is the part that matters, and it is bigger than a wrong label:

  * `verifying` cannot pass, so the full `update.health_timeout` (5 minutes) is spent.
  * `Manager.failAndHold` then runs `compose down` and the app is STOPPED.
  * The household is told the update failed and is sent to a restore they do not need.
  * Their recipe app — which was working, on the new version, with its data intact — is DOWN.

Nothing is lost: the data is in the volumes and the restore works. But a single wrong port number
in a template turns a SUCCESSFUL update into an outage plus an unnecessary restore, every time,
for every household running that app.

The same shape applies to `zipline` (probe `type: api` + `expect: status 200` on `/api/health`,
which that app answers 404) and, unmeasured, to `wger`.


A SECOND CHECK, five minutes later in the same `verifying` window
-----------------------------------------------------------------
  21:19:52  front door=200  docker=healthy
  21:20:18  front door=200  docker=healthy
  21:20:45  front door=200  docker=healthy

THE END OF IT, 2026-09-21 21:22:49 (+361.9 s)
---------------------------------------------
  phase=failed
  „A(z) tandoor frissítése 2026-09-21 21:22-kor nem sikerult, es az alkalmazas nem indult el az uj
   verzioval. Az alkalmazas biztonsagi okbol leallitva marad, hogy az adatai ne serüljenek.
   Visszaallithato a Mentesek oldalon ebbol a biztonsagi mentesbol: sajat meghajto, 2026-09-21 21:15
   — ez a masolat a beallitasokat, az adatbazist es az adatkoteteket tartalmazza."
   (quoted with ASCII fragments; the live sentence carries its accents — see apps/tandoor/)

  docker ps -a           : NO tandoor container at all
  front door             : HTTP 404  (it was 200 four times in the preceding five minutes)
  pinned_images          : ghcr.io/tandoorrecipes/recipes:2.6.15
  installed_images       : ghcr.io/tandoorrecipes/recipes:2.6.13     <- DISAGREES with the pin
  live compose image:    : ghcr.io/tandoorrecipes/recipes:2.6.15
  docker inspect         : []

The four version observables DISAGREE after a hold, and that is CORRECT — `09` §5.2: the pin is a
DECISION and `installed_images` is an OBSERVATION, and "when they disagree that is a signal, not a
bug to paper over". Here the signal reads exactly right: we decided 2.6.15, the last thing actually
observed running was 2.6.13, and nothing is running now.

TIMELINE, one line
------------------
  21:16:47  Update pressed        21:17:46  verifying begins
  21:18:28  NEW VERSION SERVING 200, docker healthcheck green
  21:19:52  200 / healthy         21:20:18  200 / healthy        21:20:45  200 / healthy
  21:22:49  health timeout -> failAndHold -> compose down -> app STOPPED, front door 404
