This commit is contained in:
@@ -1,3 +1,55 @@
|
||||
## v0.95.0 — a re-issue no longer marks a healthy escrow stale (2026-08-05, R-196 / R-204 item 2)
|
||||
|
||||
`ReissueCredentials` called `MarkEscrowStale` on every re-issue that found an escrow row. The mark was
|
||||
**precautionary, not evidential**: it guessed that the box's re-apply MIGHT mint a fresh repository
|
||||
password. On the ordinary re-issue shape — a box that still holds its `<DataDir>/offbox/repo_password`
|
||||
— the password does not change, so it marked a HEALTHY escrow stale. The 2026-08-04 recovery drill
|
||||
(R-201) is what promoted this from a nit to a blocker.
|
||||
|
||||
**What the mark actually did**, because "asks for an unnecessary ceremony" understates it:
|
||||
|
||||
1. `stale_at` set → `GetEscrowStatusForCustomer` WITHHOLDS `restic_pw_sha256` from the report ACK.
|
||||
2. With no hash, the controller's SLICE-3 auto-confirm cannot flip pending→escrowed.
|
||||
3. `OffboxRunnable() = OffboxConfigured() && EscrowState=="escrowed"` → **every off-site backup
|
||||
refused, indefinitely**, on a box whose key was never in doubt.
|
||||
4. The customer is told to re-run the recovery ceremony — which mints a new recovery code and
|
||||
supersedes the sealed blob. During a recovery that is the one act that would have destroyed the key
|
||||
just recovered.
|
||||
|
||||
A precautionary flag that stops the data protection it is guarding is not conservative.
|
||||
|
||||
**Removing it leaves no gap — the case it guessed at is measured elsewhere, and better.**
|
||||
|
||||
- **Continuous, box-side:** the controller compares the ACK's sealed hash against its CURRENT local repo
|
||||
password on every report ACK (`report.EscrowAutoConfirmer.reconcileEscrowed`, the Scenario-F
|
||||
re-check). In the guest-rebuild shape — the only shape where a re-issue is followed by a fresh
|
||||
repository password — that mismatches within one report cycle and raises the stale card plus the
|
||||
„create a new recovery code" CTA. Pinned by the controller's `TestEscrowStale_MismatchWarnsOnceAndFlags`.
|
||||
**And the mark was BLINDING it:** by emptying the hash (step 1) it removed the very value that
|
||||
comparison needs, leaving the box able to report only the hash-LESS reason, which is false.
|
||||
- **Edge-triggered, hub-side:** R-197's `offsite_repo_key_changed` fires on a proven hash difference
|
||||
across a supersession and pages the operator. Pinned by `TestEscrowPut_ChangedRepoKey_RaisesSignal`;
|
||||
red-proved by removing the `maybeEmitRepoKeyChanged` call.
|
||||
|
||||
`offsite_reissued` is unchanged and still always fires — the customer must still learn that the
|
||||
credential moved. Only the stale marking and its `escrow_stale` event are gone.
|
||||
|
||||
**`MarkEscrowStale` is kept, not deleted, and now has no caller** — deliberately. The `stale_at` flag
|
||||
is still live and correct (read by the ACK, the operator card and the PBS-DR view); the right way to
|
||||
set it is a future caller that has MEASURED a key change rather than guessed at one. Its doc now says
|
||||
so, and `TestEscrowStaleMechanism_StillWithholdsAndClears` keeps the mechanism from decaying while
|
||||
nothing writes it.
|
||||
|
||||
**Disagreement recorded** (the R-96 standing rule): the task's Scenario D asked that a real key change
|
||||
also "mark the escrow stale". It must not, and nothing was changed to make it — the hub learns of a
|
||||
real change at the moment a supersession SEALS THE NEW PASSWORD, i.e. when the escrow is freshest.
|
||||
Marking it stale there would ask for a ceremony to fix the ceremony that just ran. The correct
|
||||
consequence at that instant is the operator alarm, which is what R-197 already does.
|
||||
|
||||
`TestReissue_InvalidatesEscrow` is replaced in place by `TestReissue_DoesNotMarkAHealthyEscrowStale`,
|
||||
its exact inverse, so the reversal is visible in `git log -L`. The old test was not wrong about the
|
||||
effect it measured; it was wrong about the cause, and it pinned the defect.
|
||||
|
||||
## v0.94.0 — a box can fetch its own sealed recovery package (2026-08-04, R-199 link 6)
|
||||
|
||||
**Chain link 6 had no client.** The hub has served the identity blob since slice 10D, from
|
||||
|
||||
Reference in New Issue
Block a user