docs: R-182 closed, R-90 closed on measurement, R-86 unblocked, ep0 record corrected
gates / gates (push) Successful in 7s
gates / gates (push) Successful in 7s
R-182 CLOSED (controller v0.194.0 + hub v0.90.0/.1), proven live on demo-hp. The hub's notification_log for the run reads: two per-app failures RECORDED, one digest SENT naming both, and the customer channel SKIPPED with operator_only. Against the measured previous behaviour — two failures, one email naming one app, one leaving no trace anywhere. Scenario D proved itself on an event I had not planned: disk_critical alarmed on two filesystems, the second was collapsed by the cooldown, and that collapse is now visible WITH ITS KEY. Yesterday it would have left nothing at all. A gap the spec did not anticipate is recorded with its fix: the per-app event also fires from the periodic sweep, outside any run, so making it record-only would have created a NEW silence. The sweep emits a digest too, with no run_id, so it stays under the ordinary hourly cooldown. ep0: MEASURED on the box — 7757 MB (8 GB), 4 vCPU, and the 4 GiB swapfile SURVIVED the resize and is active (checked, because a resize is a stop/start). The 40 GB local disk is UNCHANGED, so no disk figure was touched anywhere. Five documents corrected — three of which the task's list did not name, found by searching. Two audit/evidence documents ANNOTATED, body untouched: they record what was true when written and that is their value. R-90 CLOSED. R-86 unblocked and re-ranked, stated honestly: 8 GB is comfortable, not unbounded — the original OOM was a 14.46 GB restore — so the restore-test cadence should still be paced, just not by fear of the endpoint. target-selection.md's "D-d did not name ep0 either way" is deliberately left standing. It is the operator's question, not CC's. STATUS.md 127 -> 83 lines, items rather than sentences.
This commit is contained in:
+27
@@ -123,6 +123,33 @@ Two rulings, one shape: something became live because someone pushed, not becaus
|
||||
that bumps a version, before publishing — and a gate that fails on the normal path is one people
|
||||
learn to ignore.
|
||||
|
||||
**S-16 — a backup run NOTIFIES ONCE and RECORDS ALWAYS, and those are different things
|
||||
(2026-08-03, R-182; controller v0.194.0 + hub v0.90.0/.1).** Measured: nine per-app capture failures
|
||||
reached the hub, two were mailed, seven were dropped by a cooldown whose key carries no app
|
||||
identifier — *before* `LogNotification`, so they left no row anywhere.
|
||||
|
||||
- **The record:** `recovery_unit_capture_failed`, per app, unconditionally, now routed
|
||||
**record-only** by the hub (`recordOnlyEvents`) — stored and logged every time, never competing
|
||||
for an e-mail slot.
|
||||
- **The notification:** `backup_run_failures`, ONE per run, listing every failed app with its leg
|
||||
and reason plus the counts and free space. **A clean run emits nothing.**
|
||||
- **A suppressed operator event now leaves a `suppressed` row** carrying the key that suppressed it —
|
||||
for every operator type. *"We chose not to e-mail you"* and *"nothing happened"* must never look
|
||||
identical; that is the whole finding, stated as a rule.
|
||||
- **The periodic sweep gets a digest too, with NO `run_id`**, so it stays under the ordinary hourly
|
||||
cooldown. Without it the sweep's failures would be recorded and never notified — a new silence
|
||||
created while closing one. A real run's digest carries a unique `run_id` precisely so the cooldown
|
||||
can never collapse a manual run into the nightly one.
|
||||
- **Why the silence is safe:** the hub's deadline check raises `expected_backup_missed` from report
|
||||
freshness, independently of any mail the box sends (`monitor/deadline.go:396,417`). **If that check
|
||||
is ever weakened, this design loses its footing.**
|
||||
- **Not taken, and why:** putting `app` in the cooldown key. It fixes the swallowing by producing one
|
||||
mail per failing app — a dozen on a full disk.
|
||||
|
||||
**ep0 was rescaled by the operator to a CX33 (2026-08-03): 4 vCPU, 8 GB RAM, measured on the box, and
|
||||
the 4 GiB swapfile survived. The 40 GB local disk is UNCHANGED** — a CPU/RAM resize only, so no disk
|
||||
figure in any runbook needed correcting. That closed **R-90** and unblocked **R-86**.
|
||||
|
||||
**S-11 — D-c's routing, and why R-158's own proposal was overruled (2026-08-02, R-167 SHIPPED).**
|
||||
Decision D-c splits two signals by AUDIENCE, and the split is the ruling: **a fill warning is the
|
||||
CUSTOMER's** (they can free space, delete files, add a drive) and **a per-app backup capture failure
|
||||
|
||||
Reference in New Issue
Block a user