811a0ef7a7
Claude-Session: https://claude.ai/code/session_01GzammAMzsJTgpQHqxwM2bC
6.2 KiB
6.2 KiB
REPORT — v0.124.0: backups IA restructure (four sub-pages, Felhom-offsite status card, .fab browser download)
Date: 2026-07-13 · Version: controller v0.124.0 (from v0.123.0) · MinAgent: 0.81.0 (UNCHANGED) · Floor: untouched (rides the next train) · Controller-only.
What shipped (commits 0ece2ba, aa967fb, 753cd83)
- IA split —
/backups(Áttekintés),/backups/remote(Távoli mentés),/backups/apps(Alkalmazások),/backups/restore(Visszaállítás), sidebar children (Tárhely pattern). Sections MOVED verbatim from the v0.123.0 page — the committed one-shotscripts/backups_split_move_check.pyverifies all 15 blocks against baselinedf7ad37(whitespace-normalized; the two allowed divergences — tier-3 anchor retarget + the restore-to-verify relocation — are encoded explicitly). Shared handler builders extracted (backupsCommonData/backupsOffboxData); flash redirects, tier-3 anchors and the tier2-config back-link retargeted per page. - Felhom-offsite status card — three honest states from local data, display-only by construction (no form/button inside the card; unit-enforced). Decision 2 honored: the card never changes anything.
- .fab browser download — existing export pipeline + staging dest + guarded streaming exit with estimate-first UX, post-stream cleanup and a 1h TTL sweep; per-app sequential batch; portability framing everywhere (decision 3). Import stays drive-scan.
Tests + red-proofs (run → FAIL → restored)
- Move check red-proof: one moved block reworded → exit 1 ("1 block(s) rewritten"); restored → 0.
- Traversal guard red-proof: guard loosened to raw prefix-matching →
../decoy.fabcame back 200 serving the decoy — the test caught it (got 200, want 400). Restored → green. - Round-trip + corruption (data-mutation red-proof): real
executeExport→ bundle → realexecuteImport→ byte-identical restored content; a mid-file-corrupted copy is REFUSED (job fails, app not started, nothing restored). Integrity = gzip CRC + manifest segment validation — there is NO per-file checksum (documented; the spec's "manifest checksum" wording adapted to reality). - Nav/state tests (marker per section, present on exactly one page;
.Pageids), status-card state tests, TTL sweep test (fake mtimes/now). Full green gate + all five template gates green per commit.
§13 live validation
- Deployed: 0.124.0 on the drill guest (qm300) AND demo 9201, both healthy.
- Four-page walk (drill, screenshots in session record): every moved control clicked once —
tier-2 Beállítás (+ retargeted back-link), tier-3 toggle (off→on), restore-to-verify from its
NEW home (
/backups/restoreflash), manual-target form open/close. Old/backupsbookmark → Áttekintés on both boxes; sidebar active states correct. - Status card: state 3 (no card) and state 2 ("Aktív — nincs kijelölt alkalmazás") both live-rendered on the drill box; state 1 by unit render test (demo has a managed target — spec says do NOT unconfigure).
- .fab download: drill ActualBudget — estimate 3.6 KB shown first, bundle 2102 B streamed,
staging bundle removed (server log). Demo ActualBudget — downloaded to the operator machine,
sha256-identical after placement on
felhom-usb/exports(e2a1233f…both ends). - Supervised import (Viktor GO): ON DEMO (see finding 2 for why not drill): scan found the bundle, manifest read (exported-by 0.124.0), "Importálás kész! Az alkalmazás sikeresen visszaállítva.", ActualBudget Up (healthy). The round-trip surfaced finding 1.
FINDINGS (both pre-existing, surfaced by this task's first real containerized round-trip)
- (HIGH — data-loss trap) Containerized .fab export ships EMPTY volume data.
exportVolumeDatarunsdocker run -v <volDir>:/out alpine tar …where<volDir>is the controller-CONTAINER'sos.MkdirTemppath — the guest's docker daemon resolves it against the HOST filesystem, so the tar lands stranded on the guest host (/tmp/felhom-export-*/…, found with ActualBudget's 66 KB tar in it) and the bundle'sdata/volumesis empty while the manifest claims volume data and the export reports SUCCESS. Import then wipes the app's volumes and brings it up EMPTY. Affects every golden/bootstrap (containerized) box for volume-backed apps; HDD-data apps are unaffected (direct FS copy). Demo's ActualBudget was repaired from the stranded tar; both temp dir and staged bundle cleaned. Fix direction: stage the docker-run output under a host-visible bind (e.g. the controller data volume) or usedocker cp/stdout streaming; plus a post-export assertion that manifest-claimed volume tars exist in the bundle (fail LOUD). - (MEDIUM — agent-side, out of this controller-only task) Drive wizard offers zero candidates
on a legacy-boot PVE. With LVM root and no ESP mount, every system mount resolves to
device-mapper,
storage.SystemDisksfinds no raw disk →sysKnown=false→isSystemBackedfail-safes EVERYTHING to system →ListCandidateDisksis always empty (drill box; a hot-added blank 5G disk stayed invisible). The fail-safe is right to exist but overreaches here — needs an agent ruling (e.g. resolve device-mapper parents to their PVs' disks).
Observations
- .fab browser-UPLOAD remains the noted follow-up (import is drive-scan only — downloaded bundles return via a drive/share, exactly as exercised here).
- Combined mega-zip stays parked (decision; per-app sequential batch shipped instead).
- appexport packages LIVE state (fresh config copy + DB dump + live data), NOT the tier-1 recovery unit — §8's "stale unit" concern is moot; no "futtass előbb mentést" needed.
- The import page's drive-label mojibake ("TÃ˘rhely (felhom-usb)") is the KNOWN open fix-5 item.
NoUserDataBackupWarningis referenced by the per-app section but never set by any handler (dead conditional, pre-existing);DBDumpTotalByteswas computed but never rendered — dropped in the split.- Drill box left as found: hot-added disk detached + LV removed; ActualBudget re-toggled; demo exports dir + stray export temp cleaned.