Q1 - what the customer sees when a backup refuses for lack of space. The failure
IS customer-visible: /backups renders "Adatmentés sikertelen" with a cross mark.
It is absent from the dashboard, the launcher, the app detail page, and - the one
worth fixing - from /backups/apps, the per-app page where you would naturally ask
whether a given app is backed up.
Point 5 measured across three runs: it retries, stays failed while constrained
(marker persists, unit mtime unchanged at 07:30:50), and clears on recovery with a
fresh unit at 07:37:38. /backups/apps reading "Utolsó: 3 perce" tracks the unit's
REAL mtime, not the failed run, so it is honest about the age of the last good
unit rather than claiming a fresh one. Explicitly NOT the R-156 family.
So R-158 is a NOTIFICATION GAP, not a silent-failure defect, and ranks BELOW
R-157 - whose mechanism B leaves a deployed app not running while deadapp reports
"0 currently down", silent on every channel.
Q2 - ValidateDump was right and no bad dumps are shipping. The live DB genuinely
had zero accounts (only _prisma_migrations 129, cc_proof 82, instance_settings 1).
An empty table proves nothing, so an account was SEEDED as the task required: the
warning then stopped entirely and the dump provably contained the rows (c10acct 1,
c10user 2; 102766 -> 103029 bytes).
But that kills C2's proposed ordering. A fresh appliance legitimately has zero
accounts, so gating on "accounts has rows" would block the backups of every new
customer until someone registers. The validator's fact is right; its inference
("may predate the customer's data") is wrong - there was no data to predate. The
chain is therefore longer: a sound predicate first (compare the dump against the
LIVE db, per-table counts, not an absolute expectation), then warn->gate, then the
tar-drop. Until then the DB volume tar stays load-bearing - not because dumps are
bad, but because nothing can yet prove one is good.
No new R-n; register grepped. Nothing fixed. Part 2 (teardown) follows.
6.2 KiB
Campaign 10 — closeout: two last measurements, then teardown (2026-08-02)
Companion doc (my call, per the task) to CAMPAIGN-10-two-storage-soak-2026-07-31.md and
SPIKE-recovery-unit-space-2026-08-02.md, rather than appending — those two are already long and this
session answers two specific questions and then dismantles the rig.
Part 1 headline: Q1 lowers R-158's rank — the failure is customer-visible, on one page, and it
persists and clears correctly. Q2 clears ValidateDump of shipping bad dumps, and simultaneously
kills C2's proposed gate on its current predicate.
Q1 — when a backup refuses for lack of space, what does the customer see?
Method: ballast /mnt/sys_drive to 699 MB free (homebox's unit needs 2.3 GB), run the real backup
through POST /api/backup/run, and read every customer-facing surface through the real UI endpoints.
The five points
| # | Surface | Result |
|---|---|---|
| 1 | /backups overview |
SHOWS IT — ✗ Adatmentés sikertelen |
| 2 | /backups/apps (per-app) |
shows nothing — Homebox tier-1 reads Utolsó: 3 perce |
| 3 | /stacks/homebox (app detail) |
shows nothing |
| 4 | / dashboard · /launcher |
show nothing — no banner |
| 5 | GET /api/backup/status |
db_dump.success: **false** |
| — | hub event / email | none (R-158) |
Exact copy, as rendered on /backups:
✗ Adatmentés sikertelen
The point-5 question — retry, stay failed, or quietly go green?
It retries, stays failed, and does not lie. Measured across three runs:
| run | condition | status.success |
/backups shows failure |
unit mtime |
|---|---|---|---|---|
| 1 | constrained | false | true | 07:30:50 |
| 2 | still constrained | false | true (persists) | 07:30:50 (unchanged) |
| 3 | space freed | true | false (cleared) | 07:37:38 (fresh) |
/backups/apps is honest, not deceptive. Its Utolsó: 3 perce tracks the unit's real mtime
(07:30:50), not the failed run's timestamp — so it correctly reports the age of the last good unit. It
simply never says the latest attempt failed. This is NOT the R-156 family: no surface claims a
fresh backup over a stale unit.
R-158's rank — LOWERED, with the reason
R-158 is a notification gap, not a silent-failure defect. It ranks BELOW R-157.
Because the customer can find out by looking, and the indicator behaves correctly — it persists while failing and clears on recovery. What is missing is that nothing pushes it: no hub event, no email, no dashboard banner. And the discovery path is poor in a specific way worth fixing: the per-app backup page — the natural place to ask "is homebox backed up?" — shows no failure at all, while the answer lives one page away on the overview.
R-157 outranks it because R-157's mechanism B leaves a deployed: true app not running, with the
deadapp check reporting 0 currently down — silent on every channel, including the one the customer
would look at.
Q2 — was ValidateDump's warning correct?
The warning, seen twice:
[WARN] [backup] ValidateDump: …/rallly-postgres.sql is structurally valid (32 tables) but its
accounts table has NO rows — the dump may predate the customer's data
It was factually correct, and the dump was NOT deficient
The live database genuinely had no accounts. Every non-empty table, from pg_stat_user_tables:
_prisma_migrations | 129
cc_proof | 82 <-- the campaign's own canary
instance_settings | 1
accounts | 0
An empty table proves nothing either way, so — as the task required — an account was seeded and the backup re-run:
INSERT users (id='c10user', …) -> 1 row
INSERT accounts (id='c10acct', …) -> 1 row
Result:
[INFO] [backup] DB dump: rallly-postgres → rallly-postgres.sql (100.6 KB, 396ms, 32 tables)
(no ValidateDump line at all — the warning STOPPED)
grep -c c10acct <dump> = 1 grep -c c10user <dump> = 2
dump size 102 766 B -> 103 029 B
Verdict: the validator is sound and no bad dumps are shipping. It correctly detected an empty
accounts table, and the moment real data existed the dump captured it and the warning cleared.
(Seeded data disclosed: one users row and one accounts row, both c10*-prefixed, on a scratch
customer that this session then deletes.)
What it does to C2's ordering — the proposed gate is DEAD on this predicate
C2 proposed dropping the DB volume tar (halving DB-app units, and closing the D5/R-127(b) initdb-skip
password trap) once ValidateDump is promoted from a warning to a gate. That ordering does not
survive Q2:
A fresh appliance legitimately has zero accounts. Gating on "the
accountstable has rows" would block the backups of every new customer until someone registers a user — refusing good backups for the entire period a box is most fragile.
The validator's fact is right and its inference ("may predate the customer's data") is wrong: there was no data to predate. So the dependency chain is longer than C2 assumed:
- a sound gate predicate first — a comparison against the live DB (per-table row counts in the
dump vs
pg_stat_user_tables) rather than an absolute expectation about one table; - then the warn→gate promotion;
- only then the tar-drop.
Until (1) exists, the DB volume tar stays load-bearing — not because dumps are bad, but because nothing can yet prove a given dump is good.
Findings
No new R-n. Register grepped (documentation/backlog/*.md) for ValidateDump, accounts table,
Adatmentés sikertelen, and the per-app backup page: no existing rows, and neither Q1 nor Q2 produced
a defect that is not already covered.
- Q1 does not mint an R — it re-ranks R-158 (filed in the spike) and adds the specific
improvement worth making: surface the per-app failure on
/backups/apps, where a customer looks for a specific app. - Q2 does not mint an R — it removes a proposed change (the gate) and lengthens C2's dependency chain. Recording that a design is wrong is the spike rule working.
Nothing fixed, per the fences.