Campaign 10 closeout Part 1: Q1 lowers R-158's rank; Q2 clears ValidateDump and kills C2's gate
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.
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
# 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 `accounts` table 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:
|
||||
|
||||
1. 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;
|
||||
2. **then** the warn→gate promotion;
|
||||
3. **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.
|
||||
Reference in New Issue
Block a user