## 2026-09-16T15:32:38Z Part E.1 — fresh VM 335 on demo-hp from the BUILT ISO 1.28.0
  disks go on storage nvme-scratch, which IS /mnt/hdd_1 at its root (never local-lvm)
update VM 335: -ide2 local:iso/felhom-installer-1.28.0-pve9.2-1.iso,media=cdrom -scsi0 nvme-scratch:32 -scsi1 nvme-scratch:100 -vga std
Formatting '/mnt/hdd_1/images/335/vm-335-disk-0.raw', fmt=raw size=107374182400 preallocation=off
scsi1: successfully created disk 'nvme-scratch:335/vm-335-disk-0.raw,size=100G'
Formatting '/mnt/hdd_1/images/335/vm-335-disk-1.raw', fmt=raw size=34359738368 preallocation=off
scsi0: successfully created disk 'nvme-scratch:335/vm-335-disk-1.raw,size=32G'
update VM 335: -boot order=ide2;scsi0
boot: order=ide2;scsi0
cores: 4
ide2: local:iso/felhom-installer-1.28.0-pve9.2-1.iso,media=cdrom,size=1665354K
memory: 8192
name: tester1-drill-0244
scsi0: nvme-scratch:335/vm-335-disk-1.raw,size=32G
scsi1: nvme-scratch:335/vm-335-disk-0.raw,size=100G
scsihw: virtio-scsi-single
  status: status: running
  NOTE (measured 2026-09-16): do NOT judge the install from a ping — the installer's own live
  system already answers on the box's address. Read the console instead; and when the install
  finishes, COLD stop, detach the CD, set boot order=scsi0, start — a guest reboot reuses the
  running QEMU's boot order and would re-enter the installer.
## 2026-09-16T15:32Z VM 335 created and started from the BUILT image (not the published one):
##   ide2 = local:iso/felhom-installer-1.28.0-pve9.2-1.iso   (sha256 a4cd9b6d… on both sides)
##   scsi0 32G + scsi1 100G, both on nvme-scratch == /mnt/hdd_1 at its root; boot order=ide2;scsi0
##   set in its OWN qm set call (the documented trap: doing it in the same call as the disks yields
##   order=net0;ide2 and the machine netboots).
## THE FLOOR IS DELIVERING, measured on the hub's own Configs page minutes after the raise:
##   demo-felhom  Version 0.244.0  Floor v0.244.0   <- it was on 0.242.0 before the floor moved
##   demo-hp      Version 0.244.0  Floor v0.243.0 (override)  <- already deployed by hand today
##   tester-1     Version 0.243.0  Floor v0.244.0  (DOWN — its box was torn down this morning)
##   drill-r50 BLOCKED and peti-felhom DOWN keep their old controllers, which is the design: the hub
##   HOLDS rather than serves when a box cannot take the release.
## THE INSTALL, step by step, each screen READ before the next keystroke (screens/e1-*.png)
##  e1-01-bootmenu.png  the built 1.28.0 menu: „Felhom telepítés" (default) / „Felhom telepítés
##                      (szöveges mód)", „Indítás 14 másodperc múlva...". Two entries, Hungarian,
##                      Felhom-branded, no Proxmox and no automated entry.
##  Chose the TEXT-MODE entry (Down, Enter) — the same deviation the 2026-09-16 drill declared: the
##  graphical entry is drivable by keyboard, but reading it blind costs a screenshot per focus move.
##  e1-02-installer.png  „Proxmox VE (9.2-1) Installer — END USER LICENSE AGREEMENT (EULA)",
##                      `<I agree>` focused (red). Enter accepts.
##  e1-03-disk.png      „Target harddisk:  /dev/sda (QEMU HARDDISK) (32.00 GiB)", `<Next>` focused,
##                      with `<Advanced options>` beside it. The box has TWO disks (32 GB system,
##                      100 GB data); the installer offers the 32 GB one and a PERSON confirms it —
##                      the image guesses nothing. That is the release gate's disk criterion (G14)
##                      seen on this build, not inferred from the previous one.
##  e1-04-country.png   „Country: Hungary · Timezone: Europe/Budapest · Keyboard layout: Hungarian",
##                      all three PREFILLED, `<Next>` focused. A Hungarian household gets its own
##                      country and clock without touching anything.
##                      DEVIATION (declared, same as the 2026-09-16 drill): the walk switches the
##                      KEYBOARD to U.S. English for TYPING ONLY, because the next screen needs an
##                      e-mail address and `@` is not reachable by a plain keycode on the Hungarian
##                      layout. It is a property of driving the console blind, not of the product.
##  e1-05-focus-check.png  FOCUS VERIFIED BEFORE ACTING: after one Up, the „Keyboard layout" row is
##                      highlighted (red, value „Hungarian"). This screendump exists because a blind
##                      value-cycle on the wrong row would have silently changed the COUNTRY or the
##                      TIMEZONE instead — the installer's rows all cycle with the same arrow keys.
##  e1-06-keyboard.png  MEASURED: with the „Keyboard layout" row focused, TWENTY `qm sendkey right`
##                      presses left the value reading „Hungarian". That is ambiguous on its own —
##                      either the arrow does not cycle this row, or the list wrapped and came back —
##                      so the next step is ONE press, which tells the two apart. Recorded rather than
##                      resolved by assumption, because the obvious reading („the key does nothing")
##                      would send me rebuilding the whole typing approach for no reason.
##  e1-07-keyboard-one-right.png  SETTLED: ONE `qm sendkey right` on the focused „Keyboard layout" row
##                      also leaves „Hungarian". So the arrow does not cycle this row at all — the
##                      twenty presses did nothing, they did not wrap. (The one-press test exists
##                      precisely because the twenty-press result could not tell those apart.)
##                      A measured fact about driving THIS installer blind, not about the product.
##  e1-08-keyboard-enter.png  THE MECHANISM, established by measurement (four screendumps):
##                      in this text-mode installer the arrow keys do NOT cycle a row's value;
##                      ENTER on the focused row opens a selection LIST, which is then driven with
##                      Up/Down + Enter. The list here runs Belgium-French … United Kingdom, with
##                      „Hungarian" highlighted as the current value and „U.S. English" 15 entries
##                      below it. Written down so the next session does not spend four screendumps
##                      re-learning it.
##  e1-09-keyboard-list.png  „U.S. English" highlighted after exactly 15 Down presses from
##                      „Hungarian" (Icelandic … Turkish in between, „United Kingdom" one past it).
##                      Captured BEFORE the confirming Enter — the rule that keeps a blind walk honest.
##  e1-10-keyboard-set.png  „Keyboard layout: U.S. English" — and Country „Hungary" + Timezone
##                      „Europe/Budapest" UNCHANGED beside it. Exactly one value moved, which is the
##                      point of verifying focus first. The layout switch is a TYPING aid for driving
##                      the console blind (the next screen needs an `@`), declared as a deviation; a
##                      volunteer at a real keyboard keeps the Hungarian layout.
##  e1-11-focus-next.png  Focus back on `<Next>` (highlighted) with the row values standing as
##                      „Hungary / Europe/Budapest / U.S. English". Verified before the Enter that
##                      leaves the screen — on this installer Enter on a VALUE row reopens its list
##                      instead of advancing, so „press Enter to continue" is only true from a button.
##  e1-12-password.png  „Root password [at least 8 characters]" (focused, empty), „Confirm root
##                      password", „Administrator email" PREFILLED with `mail@example.invalid`.
##                      The installer asks for exactly what a household must decide and nothing else.
##                      The root password used here is a THROWAWAY for a VM that gets destroyed at
##                      teardown; it is held out-of-band and appears in no committed file.
##                      The administrator e-mail is replaced with tester1@felhom.eu — the address the
##                      customer record already uses.
##  e1-13-password-filled.png  VERIFIED BEFORE ADVANCING: both password fields show 12 masked
##                      characters (the typed length), and „Administrator email" reads exactly
##                      `tester1@felhom.eu` — the `@` landed, which is the whole reason the keyboard
##                      layout was switched. Focus on `<Next>`. The placeholder was cleared with
##                      End + 26 backspaces before typing, so no remnant of `mail@example.invalid`
##                      survives (a remnant would be invisible in a masked-looking field later).
##  e1-14-network.png   „Management interface: nic0 (bc:24:11:45:0c:96, virtio_net)",
##                      „Hostname (FQDN): pve.example.invalid"  <- the only value a household must change,
##                      „IP address (CIDR): 192.168.0.101 / 24", „Gateway: 192.168.0.1",
##                      „DNS server: 192.168.0.250", „[X] Pin network interface names", focus `<Next>`.
##                      The network came from DHCP and is already correct; note the address is .101
##                      here, where the 2026-09-16 drill box got .128 — nothing may key off a
##                      remembered address.
##  e1-15-network-focus.png  ROW ORDER on the network screen, measured rather than guessed: one Up
##                      from `<Next>` lands on the „[X] Pin network interface names" CHECKBOX — not on
##                      a text field. Upward from there: DNS, Gateway, IP address, Hostname. So the
##                      hostname is five Ups from the button, and a walk that assumed „Up = previous
##                      text field" would have typed the hostname into the IP address.
##                      The checkbox stays ticked; no space is sent while it holds focus.
##  e1-16-hostname-focus.png  Focus VERIFIED in the „Hostname (FQDN)" field (the caret sits at the end
##                      of `pve.example.invalid`; the checkbox is no longer highlighted and no other
##                      field shows a cursor). Only then is anything typed.
##  e1-17-hostname-typed.png  „Hostname (FQDN): tester1.enkicsifelhom.hu" — the placeholder is fully
##                      gone (End + 26 backspaces before typing), and the IP `192.168.0.101/24`,
##                      gateway `192.168.0.1`, DNS `192.168.0.250` and the ticked „Pin network
##                      interface names" are all untouched. One field changed, deliberately.
##  e1-18-network-next.png  Focus verified on `<Next>` with „tester1.enkicsifelhom.hu" standing and
##                      the DHCP values unchanged. Five Downs from the hostname field reach the button
##                      (IP, gateway, DNS, checkbox, `<Next>`) — the same row order measured earlier,
##                      now walked in the other direction.
##  e1-19-summary.png   THE SUMMARY, verbatim — what this box is about to become:
##      Bootdisk filesystem   ext4
##      Bootdisk(s)           /dev/sda            <- the 32 GB system disk; the 100 GB data disk is NOT touched
##      Timezone              Europe/Budapest
##      Keyboard layout       U.S. English        <- the declared typing deviation
##      Administrator email   tester1@felhom.eu
##      Management interface  nic0
##      Hostname              tester1.enkicsifelhom.hu
##      Host IP (CIDR)        192.168.0.101/24 · Gateway 192.168.0.1 · DNS 192.168.0.250
##      [X] Automatically reboot after successful installation
##  THE REBOOT BOX IS LEFT TICKED ON PURPOSE. A volunteer would leave it, and the trap it causes —
##  the machine re-enters the installer because a guest reboot reuses the running QEMU process's boot
##  order — is already a measured finding from 2026-09-16. Unticking it would quietly change the path
##  being walked; the trap is handled afterwards the documented way (cold stop, detach CD, boot disk).
## 2026-09-16T15:47:53Z INSTALL STARTED (Enter on <Install>, every value verified on e1-19/e1-20)
##  e1-21-installing.png  25 s after Enter the installer is at „58 %", „extracting
##                      libjs-extjs_7.0.0-5_all.deb", with only `<Abort>` on screen — the install is
##                      really running, not a form that silently refused. Captured deliberately early:
##                      „it started" is a fact worth holding before an eight-minute wait, because a
##                      stalled form and a running install look identical from outside.
## 2026-09-16T15:57:05Z the documented recovery: cold stop, detach CD, boot from disk
update VM 335: -delete ide2
update VM 335: -boot order=scsi0
boot: order=scsi0
status: running
##  e1-22-after-install.png  THE TRAP REPRODUCED, exactly as the 2026-09-16 drill measured it:
##                      the install completed, the box rebooted itself (the „Automatically reboot"
##                      box was left ticked, as a volunteer would), and it came back INTO THE
##                      INSTALLER — the graphical entry this time, showing the EULA. Cause: a guest
##                      reboot reuses the RUNNING QEMU process's boot order (`ide2;scsi0`), so the
##                      disk-first change an installer makes does not apply to that reboot.
##                      A volunteer with the stick still in the machine sees this too.
##                      IT ALSO MEANS: a completed install and a stuck one look identical on screen.
##                      Completion was judged from the machine's behaviour (it rebooted by itself),
##                      never from the picture.
##  e1-23-first-boot.png  FIRST BOOT OF THE INSTALLED SYSTEM — the volunteer's first screen, and it is
##                      Felhom's, in Hungarian, with no admin URL anywhere:
##                        „Felhom otthoni szerver"
##                        „Ezen a gépen most nincs dolgod, és bejelentkezni sem kell."
##                        „A beállításhoz kövesd a Felhomtól kapott útmutatót."
##                        `tester1 login:`
##                        „Felhom — a doboz készen áll, és a párosításra vár."
##                        „Párosító kód:  ZB3-7HM"
##                        „Nyisd meg az e-mailben kapott linket, és add meg ezt a kódot és a
##                         Tulajdonosi jelmondatodat (az 5 szót a Felhom üzemeltetőjétől kaptad)."
##                        „Ez a képernyő magától frissül — nincs teendő a doboznál…"
##                      `8006` appears 0 times. The login prompt carries the box's own hostname.
##                      The pairing code is non-secret by design: binding also needs the owner
##                      passphrase, which is not on this screen and not in this file.
## THE HUB SIDE, same minute: the box registered ITSELF from the universal secret-free image.
##   /hosts → „(generic ISO, awaiting a bind) A box that installed from the universal secret-free ISO
##   and registered itself."
##     Appliance      1969bbb5-8502-41e2-9df0-b540bb6a85da
##     Pairing code   ZB3-7HM            <- the same code the box's own screen shows
##     MAC            bc:24:11:45:0c:96  <- the same NIC the installer named (nic0)
##     Hardware       Standard PC (i440FX + PIIX) · AMD Ryzen Embedded V1756B · 7.8 GB
##   NOTHING was pressed on the operator side to make this happen.
## AND THE CUSTOMER ALREADY HAS THE MAIL: „Kösd össze a Felhom dobozodat" arrived at 12:23:00Z today
##   (the automatic one that followed this morning's host delete), valid 7 days, naming exactly the
##   two things to enter — the pairing code from the screen and the five-word owner passphrase, which
##   it says is never sent by e-mail. So this walk needs NO operator press for the bind: O1 of the
##   previous drill is gone. The link itself is a capability URL and appears in no committed file.
## 2026-09-16T16:00:11Z BIND — the volunteer path: the customer opens the link from their own e-mail
  bind page: http=200, 3202 bytes
  form fields (values not shown): ['pairing_code', 'passphrase']
  bind POST -> http=200
  page says: Felhom — Doboz összekötése Felhom doboz összekötése Sikeres összekötés. A doboz kb. egy percen belül folytatja a telepítést. Ezt az oldalt bezárhatod — a beállítás a háttérben befejeződik, és a vezérlőpultod hamarosan elérhető lesz. Felhom.eu
## SECRET HANDLING, corrected from this project's one real slip (2026-09-16 morning):
##   the owner passphrase was extracted from the hub page's `data-secret` ATTRIBUTE straight into a
##   0600 file and never printed — the earlier leak happened because the masking covered element TEXT
##   only, and the attribute went to the transcript. The page carries exactly one such attribute
##   („Credentials Retrieval Password"), length 35; only the length is recorded here.
## 2026-09-16T16:00:11Z BIND — SUCCEEDED, and this time with ZERO operator presses.
##   The bind page asked for exactly the two things the e-mail named: `pairing_code` and `passphrase`
##   (field names read from the form, not guessed — guessing them cost an extra attempt on the claim
##   page in the previous drill).
##   The page answered: „Sikeres összekötés. A doboz kb. egy percen belül folytatja a telepítést.
##   Ezt az oldalt bezárhatod — a beállítás a háttérben befejeződik, és a vezérlőpultod hamarosan
##   elérhető lesz."
##   THE DIFFERENCE FROM THE 2026-09-16 MORNING DRILL: that walk needed O1, an operator pressing
##   „Send self-bind link", because no automatic mail existed for a customer who was already waiting.
##   This walk used the mail the hub sent ITSELF after the host delete (R-509, proven at 12:23:00Z),
##   so the pre-declared operator press is gone.
## 2026-09-16T16:00Z THE BOX ENROLLED ITSELF, minutes after the bind:
##   Host ID        tester-1-33b6a9      (the morning's host record was deleted; this is a new box)
##   Status         ONLINE, „Enrolled just now", „Last Report just now"
##   Agent          0.131.0 — the vouched agent, no hand upgrade
##   PBS wrapper    „matches vouched 104db0a4401f…"
##   Capabilities   „pve:store-grant:felhom-pbs  critical  ok — backup tier felhom-pbs readable by
##                  the agent", „pve:store-grant:local ok", „pve:pool-read ok"
##   Guests         0/0 at this moment — the customer guest is still being created.
## AND THE CLAIM MAIL CAME BY ITSELF at 16:00:58Z: „[Felhom] Új beállító kód — újratelepült a
##   szervered … A kód 72 óráig érvényes". The setup code itself is a SECRET: it is held out-of-band
##   in a 0600 file for the claim step and appears in no committed file.
## 2026-09-16T16:17:25Z CLAIM — the household sets its own dashboard password
Traceback (most recent call last):
  File "<stdin>", line 8, in <module>
  File "/usr/lib/python3.13/urllib/request.py", line 495, in open
    response = meth(req, response)
  File "/usr/lib/python3.13/urllib/request.py", line 604, in http_response
    response = self.parent.error(
        'http', request, response, code, msg, hdrs)
  File "/usr/lib/python3.13/urllib/request.py", line 533, in error
    return self._call_chain(*args)
           ~~~~~~~~~~~~~~~~^^^^^^^
  File "/usr/lib/python3.13/urllib/request.py", line 466, in _call_chain
    result = func(*args)
  File "/usr/lib/python3.13/urllib/request.py", line 613, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 403: Forbidden
## 2026-09-16T16:17:03Z THE BOX IS UP AND REACHABLE FROM OUTSIDE (R-510 holds on this box too):
##   hub: „Guests 1/1 running · VMID 9201 · tester-1 · running · Last Seen just now"
##   from DooPlex, over the customer's own domain through the tunnel:
##     https://felhom.enkicsifelhom.hu/       -> 200
##     https://felhom.enkicsifelhom.hu/claim  -> 200
##   (the host row still shows „Cloudflared inactive" on the HOST plane — the tunnel that matters for
##   the customer runs in the GUEST, and it is evidently serving.)
## 2026-09-16T16:17:50Z CLAIM, retried with curl (a python urllib client got 403 from the edge on the
##   same page curl reads as 200 — a transport difference, not the box refusing)
  GET /claim http=200 bytes=2525
  csrf field present: yes; cookies: felhom_claim_csrf 
  claim POST http=302
  page says: 
  login page token: MISSING
  login with the NEW password -> http=302   (302 = the claim really took)
  dashboard -> http=200
  dashboard says: Indítópult — Felhom.eu Indítópult Vezérlőpult Alkalmazások Tárhely Meghajtók Hálózati tárhely Biztonsági mentés Áttekintés Távoli mentés Alkalmazások Visszaállítás Megosztás Hálózati megosztás Rendszermonitor Debug Beállítások Rendszer Értesítések Biztonság és
  controller version on the page: 0.244.0
## THE CLAIM, and a transport fact worth recording:
##   GET /claim  -> 200 (2525 bytes), one pre-auth cookie `felhom_claim_csrf`, one `_csrf` field.
##   POST /claim -> 302 — the success shape. Proof that it TOOK is the login below, not this redirect.
##   A python urllib client got 403 Forbidden from the edge on the SAME page curl reads as 200,
##   seconds apart. That is the edge judging the client (no browser-ish headers), not the box
##   refusing — recorded so a future session does not read a 403 there as a product fault.
##   The setup code came from the mail the hub sent by itself; the new dashboard password is the
##   household's own and is held out-of-band. Neither appears in any committed file.
## THE CLAIM TOOK, and the delivery is PROVEN on the fact rather than the redirect:
##   login with the NEW password -> 302, dashboard -> 200, and the page footer reads
##   CONTROLLER 0.244.0 — the golden this task baked, published and vouched today.
##   So a box installed from the built ISO lands on the vouched set with no hand upgrade:
##     agent 0.131.0 (vouched) · controller 0.244.0 (this task's golden) · PBS wrapper matching.
## 2026-09-16T16:18:49Z registering the data drive (the app's files need it)
  csrf: MISSING
  target: /dev/sdb  (mount name ASCII-only — an accented name is refused, measured 2026-09-16)
  POST /api/storage/init -> http=403
{"ok":false,"error":"CSRF token missing or invalid"}
## THE DRIVE, as the box reports it before anything is done to it:
##   initialize: /dev/sdb · 107 374 182 400 B · „QEMU HARDDISK" · data_bearing=false · mountable=false
##   attach:     /dev/mapper/pve-vm--9201--disk--1 · ext4 · already mounted at /mnt/sys_drive
##   i.e. exactly one disk is offered for initialisation — the 100 GB data disk — and the system
##   drive is already in place. Nextcloud's files go on the former, which is why it is registered
##   before any app is deployed.
## 2026-09-16T16:19:13Z drive init, retried with a token taken from a real authenticated page
  csrf from the dashboard: present (64 chars)
  POST /api/storage/init -> http=200
{"data":{"phase":"formatting","started":true},"ok":true}

  drives as the box reports them now:
    initialize: ['/dev/sdb']
    attach:     [('/dev/sdb', '/dev/sdb'), ('/dev/mapper/pve-vm--9201--disk--1', '/mnt/sys_drive')]
## THE DRIVE INIT — and what its answer does and does not say:
##   POST /api/storage/init -> 200 {"data":{"phase":"formatting","started":true}}
##   That is an ATTEMPT, not a result: „started":true means the detached format job was accepted.
##   The result is the drive coming back MOUNTED under /mnt/felhom-drives with its label, which is
##   what the wait below watches for. (Presence is not success — this project's standing rule, and
##   the reason nothing is deployed onto the drive until the mount is observed.)
##   The mount name is ASCII („adatlemez"); the human label „Adatlemez" carries the accent. An
##   accented MOUNT name is refused by the API — measured on 2026-09-16, reused here rather than
##   rediscovered.
##   First attempt was refused 403 „CSRF token missing or invalid": I had read the token from a page
##   path that does not exist and the fallback did not follow its redirect. My error, not the box's.
## CORRECTION (17:0xZ) — MY EARLIER READING WAS WRONG, and the product was fine all along.
##   I wrote that the drive was „formatted but not mounted, 42 minutes on" from
##   `/api/disks/candidates`, which lists /dev/sdb under BOTH „initialize" and „attach".
##   The storage page — the surface the household actually opens — says the opposite and is right:
##     „Adatlemez · /mnt/felhom-drives/adatlemez · Alapértelmezett · Aktív · 0.0 GB / 97.9 GB
##      · ext4 · /dev/sdb[/felhom-data] · QEMU HARDDISK · Nincs alkalmazás ezen a tárolón"
##   So the init COMPLETED: formatted, mounted, registered, set as default.
##   WHY I GOT IT WRONG: `/api/disks/candidates` reports what the AGENT sees on the bus (raw disks),
##   not what the CONTROLLER has registered. Reading a registration question off a disk-enumeration
##   endpoint is the same class this project keeps re-learning — the instrument decided the verdict.
##   No product finding about the format. One possible small row about that endpoint still offering a
##   registered, in-use drive for initialisation is checked separately below.
## THE OFF-SITE DEFAULT, WORKING END TO END ON A FRESH BOX (this is what hub v0.116.0 shipped for):
##   „Biztonsági mentés — Távoli mentés … Aktív — nincs kijelölt alkalmazás"
##   „Távoli mentés (3. mentés) — titkosított, offsite: az alkalmazás-mentések titkosított másolata
##    egy távoli tárolóra"
##   So tier 3 is LIVE on a box installed an hour after the default was shipped — the customer did
##   nothing, the operator pressed nothing. It has no app pointed at it yet, which is the next step.
##   The drive itself: „Adatlemez · /mnt/felhom-drives/adatlemez · Alapértelmezett · Aktív ·
##   0.0 GB / 97.9 GB · ext4 · /dev/sdb · Nincs alkalmazás ezen a tárolón".
## 2026-09-16T17:04:52Z deploying Nextcloud onto the registered drive
  POST /api/stacks/nextcloud/deploy -> http=400  {"ok":false,"error":"a(z) \"Admin jelszó\" mező kitöltése kötelező — használja a Generálás gombot vagy írjon be egy jelszót"}
## WHAT A HOUSEHOLD IS ASKED FOR, and what the box mints itself (GET …/deploy-fields):
##   asked:     DOMAIN (prefilled from the customer record: enkicsifelhom.hu), SUBDOMAIN (default
##              „cloud"), HDD_PATH (the data drive) — all three required.
##   generated: DB_PASSWORD (password:24), MYSQL_ROOT_PASSWORD (password:24),
##              NEXTCLOUD_ADMIN_PASSWORD (password:16); NEXTCLOUD_ADMIN_USER defaults to „admin".
##   So no customer ever types an app password, and none is defaulted to something guessable —
##   the same shape R-513 closed for the file manager.
  final state: not_deployed
## 2026-09-16T17:15:33Z deploy retried WITH the secrets supplied (the box refused an empty admin password)
  POST deploy -> http=202  Telepítés elindítva – az állapot a kártyán követhető
  (the three app secrets are held out-of-band in a 0600 file; none appears in any committed file)
## A CONTRADICTION WORTH RECORDING (measured 2026-09-16 on the fresh box, controller 0.244.0):
##   `GET /api/stacks/nextcloud/deploy-fields` describes NEXTCLOUD_ADMIN_PASSWORD as
##     type=password, required=FALSE, generate=password:16
##   but `POST /api/stacks/nextcloud/deploy` with that value absent is REFUSED 400:
##     „a(z) „Admin jelszó" mező kitöltése kötelező — használja a Generálás gombot vagy írjon be
##      egy jelszót"
##   The browser fills it with the „Generálás" button before submitting, so a household never meets
##   this; an API caller that believes the metadata does. The refusal itself is good behaviour —
##   fail-closed, in Hungarian, naming the button — but `required:false` for a field the server
##   requires is the label disagreeing with the code.
## 2026-09-16T17:16:09Z R-536 live on a fresh box: the hub right after the 202, before the app is up
   2026/09/16 19:15:34 [INFO] Event from tester-1: app_deploy_started (info) — Alkalmazás telepítése elindult: Nextcloud
   deploy_started seen: 1
   app_deployed seen (must be 0 while it is still installing): 0
##   WHAT THAT PROVES: the acceptance now says „telepítése elindult" and NOTHING claims the app is
##   installed while it is still installing. Measured at 19:15:34 CEST, seconds after the 202, with
##   the stack still pulling images. On 2026-09-16 morning the same moment produced
##   „Alkalmazás telepítve: Mealie" — an install that was then killed 5 s later and never happened.
##   The other half of the pair (app_deployed at COMPLETION) is checked when the stack reaches running.
## 2026-09-16T17:17:31Z the completion half of R-536:
   2026/09/16 19:15:34 [INFO] Event from tester-1: app_deploy_started (info) — Alkalmazás telepítése elindult: Nextcloud
   2026/09/16 19:16:23 [INFO] Event from tester-1: app_deployed (info) — Alkalmazás telepítve: Nextcloud
##   THE PAIR, COMPLETE (R-536 proven live on a fresh box, both halves):
##     19:15:34 CEST  app_deploy_started (info) — „Alkalmazás telepítése elindult: Nextcloud"   <- the 202
##     19:16:23 CEST  app_deployed       (info) — „Alkalmazás telepítve: Nextcloud"             <- 49 s later,
##                                                                                                when the stack was up
##   Forty-nine seconds separate the acceptance from the installation. Before today those were the
##   same instant, and an install that never finished kept the „telepítve" record for ever.
