R-241 FIXED: registers, capability map, STATUS, hub CHANGELOG v0.98.0
gates / gates (push) Successful in 14s

R-241 closed against controller v0.206.0 + hub v0.98.0, following the spike's
ruling rather than the obvious reading. The row records what the fix does AND
the two real bugs the tests caught rather than review - a missing t.Enabled
(caught by an EXISTING test) and a missing falling-edge sync that
reintroduced the very defect the epoch exists to fix.

R-243 UPDATED, not closed: the STATE it describes can no longer be entered
(the mint guard), and what replaces it is VISIBLE rather than silent - the box
declares awaiting_recovery_key and the customer is offered the screen. But the
ALARM GAP is untouched, for the same three reasons, so a box whose customer
never acts still stops backing up with no operator signal. The remaining work
is an operator-side signal for a box held past some age, deliberately not
bundled into R-241's fix.

R-245 NEW - WAITING-ON-OPERATOR, recorded and NOT built: should an undecided
customer be auto-abandoned after 30 days? The operator's proposal is recorded
WITH the reasoning against it, so the decision can be revisited properly: a
reinstall implies a person, so nobody is absent; a customer who cannot find
their code gets in touch, which is why the operator LEVERS were the thing
worth building; the cost is the customer's own storage allowance; and the real
harm is QUOTA, which is a condition, not a calendar. If it is ever built,
build it to trigger on the harm with a dated warning, never on a date alone.

The capability map's recovery-journey row STAYS FAIL. These are fixes, not a
walk - nothing here walked a customer end to end, and the row goes green only
when one completes with no operator intervention AND a byte-identical
sentinel. R-214, R-202 and R-240 are still open.

STATUS compressed rather than extended, per its own one-screen rule, and the
"rebuilding throws away the off-site history" line corrected: the cause is
fixed, so leaving it as a live defect would be false.

hub CHANGELOG v0.98.0 for the superseded-package purge.

Highest register ID moves R-244 -> R-245.
This commit is contained in:
2026-08-07 12:13:09 +02:00
parent ac4b2a4ba9
commit 9657334fb7
4 changed files with 69 additions and 39 deletions
+31
View File
@@ -1,3 +1,34 @@
## v0.98.0 — drop the retained recovery package when the box says its set-aside history is gone (2026-08-07, R-241)
The hub half of the controller's abandonment countdown, and the **only** reason the hub was touched
for R-241 at all.
A customer who abandons their old off-site history gets a 14-day grace on the box. At the end of it
the controller deletes the set-aside restic store and then **declares**
`offsite.abandon_purge_requested` in its report until the retained sealed package that protected that
store is gone too. **Removing only one half leaves a state that asks a question nobody can answer:** a
package that opens nothing, or ciphertext nobody can ever decrypt.
`store.PurgeSupersededEscrowForCustomer` is the one place R-198's retention is ever undone, and its
doc comment says why that is legitimate here. **It never touches `host_escrow`** — the current package
covers the key the box is using now and is what makes its live backups recoverable. Only
`host_escrow_superseded` rows go.
**It acts on a DECLARATION, never an inference**, on the same principle as `offsite.state`: the hub
cannot see that a remote store was deleted, and the box can.
**Placed immediately before the ACK is built, deliberately.** `GetEscrowStatusForCustomer` is read
after it runs, so the *same* response that carries the request's effect is what closes the box's
two-phase commit — no second round-trip, and no window in which the box believes it is still owed. The
declaration repeats on every report until that ACK stops reporting a superseded package, so a lost
request retries by itself rather than leaving the pair half-removed.
A purge failure is logged at ERROR and never swallowed; an idempotent re-declaration (already purged,
the box has not yet seen the confirming ACK) logs at DEBUG and is not an error. Audit event
`offsite_abandon_purged` is hub-internal, like the `pbsdr_*` and `offsite_selfheal_*` events.
Needs controller **v0.206.0** to declare it. No agent change.
## v0.97.1 — the held-floor REASON must match the hold's CAUSE (2026-08-05, CAMPAIGN-11 follow-on)
> **Entry added retroactively 2026-08-05 (CAMPAIGN-11 Phase 2).** The change shipped and **is** the