=== Scenario A — a real upgrade 2.3.2 -> 2.4.0 with a fresh proven copy — 2026-09-13T10:07:31Z ===
--- BEFORE ---
{
 "state": "running",
 "updating": false,
 "update_phase": null,
 "update_phase_label": null,
 "update_error": null,
 "hold_reason": null,
 "pinned_images": {
  "uptime-kuma": "louislam/uptime-kuma:2.3.2"
 },
 "installed_images": {
  "uptime-kuma": {
   "ref": "louislam/uptime-kuma:2.3.2",
   "digest": "sha256:9aeb4e51d038047f414309c77a1af553281ca535723cb88907d907269d0a908e",
   "at": "2026-09-13T10:00:45Z"
  }
 },
 "catalog_images": {
  "uptime-kuma": "louislam/uptime-kuma:2.4.0"
 }
}
louislam/uptime-kuma:2.3.2 Up 6 minutes (healthy)
--- POST /api/stacks/uptime-kuma/update at 2026-09-13T10:07:32Z ---
HTTP 202
{"ok":true,"data":{"accepted":true,"completed":false},"message":"Frissítés elindult – az állapot a kártyán követhető"}

10:07:32 U safety-dump
10:07:34 U pulling
10:08:01 U starting
10:08:16 U verifying
10:08:20 - done
--- AFTER 2026-09-13T10:08:20Z ---
{
 "state": "running",
 "updating": false,
 "update_phase": "done",
 "update_phase_label": "Frissítve",
 "update_error": null,
 "hold_reason": null,
 "pinned_images": {
  "uptime-kuma": "louislam/uptime-kuma:2.4.0"
 },
 "installed_images": {
  "uptime-kuma": {
   "ref": "louislam/uptime-kuma:2.4.0",
   "digest": "sha256:91e963bfda569ba115206e843febb446f473ab525add4e08b2b9e3beffa16985",
   "at": "2026-09-13T10:08:19Z"
  }
 },
 "catalog_images": {
  "uptime-kuma": "louislam/uptime-kuma:2.4.0"
 }
}
louislam/uptime-kuma:2.4.0 Up 7 seconds (healthy)
--- the controller, verbatim (update + backup lines since 2026-09-13T10:07:32Z) ---
2026/09/13 10:07:32 router.go:567: [INFO] [api] update requested for stack: uptime-kuma
2026/09/13 10:07:32 update.go:278: [INFO] [stacks] update uptime-kuma: accepted — guarded update started
2026/09/13 10:07:32 update.go:701: [INFO] [stacks] update uptime-kuma: phase checking
2026/09/13 10:07:32 update.go:409: [INFO] [stacks] update uptime-kuma: precondition met — proven copy from 2026-09-13T10:03:07Z (4m0s old, limit 24h0m0s)
2026/09/13 10:07:32 update.go:701: [INFO] [stacks] update uptime-kuma: phase safety-dump
2026/09/13 10:07:32 update_guard.go:239: [INFO] [backup] update safety dump for uptime-kuma: the app has no database — nothing to copy (no-op)
2026/09/13 10:07:32 update.go:423: [INFO] [stacks] update uptime-kuma: safety dump done (0 file(s)) []
2026/09/13 10:07:32 update.go:701: [INFO] [stacks] update uptime-kuma: phase pinning
2026/09/13 10:07:32 pin.go:362: [INFO] [stacks] update uptime-kuma: pin advanced to the catalog's current definition (uptime-kuma=louislam/uptime-kuma:2.4.0)
2026/09/13 10:07:32 update.go:701: [INFO] [stacks] update uptime-kuma: phase pulling
2026/09/13 10:08:01 update.go:701: [INFO] [stacks] update uptime-kuma: phase starting
2026/09/13 10:08:14 update.go:701: [INFO] [stacks] update uptime-kuma: phase verifying
2026/09/13 10:08:19 update.go:499: [INFO] [stacks] update uptime-kuma: healthy after 5s (the app's health check passed)
2026/09/13 10:08:19 update.go:505: [INFO] [stacks] update uptime-kuma: DONE in 47s
--- the stacks page card (badge / hold / phase fragments) ---
      1 Frissítés
      1 Naprakész
      1 stackAction(event, 'uptime-kuma', 'restart')
      1 stackAction(event, 'uptime-kuma', 'stop')
      1 stackAction(event, 'uptime-kuma', 'update')
=== Scenario A — a real upgrade 2.3.2 -> 2.4.0 with a fresh proven copy done ===
