hub v0.103.0 — a host can read the packages we kept for it (R-311)
ListSupersededEscrow had zero production callers for nineteen days. It is the only reader of a retained identity_blob, so the retention shipped in v0.93.0 was material the product could not reach - proven on the fixture 2026-08-12, where a code that opens a retained package was answered as a code that opened nothing. New GET /api/v1/hosts/<id>/escrow/retained: self-scoped exactly as the current-row GET, same recovery-mode gate, same audit event written BEFORE the bytes leave, capped at 16. Rows with a NULL identity_blob are WITHHELD and returned as unopenable_count. They retain the PBS key, not the repository password, so they can never open what the caller is asking about; serving them would have the agent try packages that cannot succeed and would let the screen claim an earlier package is openable on exactly the boxes the original defect hurt. The count is returned because their existence is load-bearing and underivable. The trade, stated rather than waved through: the hub still cannot read any of it - sealed bytes in, sealed bytes out, no decrypt path, no recovery code ever held. What widens is volume, bounded by self-scope, the recovery-mode gate and the cap. The response is a NAMED TYPE, not a map, so the wire-contract gate can resolve it; the wire is declared as a fourth ROOT and the gate now checks 182 tags rather than 174. A positive control shows that check is name-presence, not decodability - filed as R-315 rather than reported as coverage. Six tests through the real endpoint; four red-proofs asserted applied.
This commit is contained in:
@@ -81,6 +81,12 @@ ROOTS = [
|
||||
"controller", "internal/report", "Report", "hub"),
|
||||
("hub -> controller (report ACK, `escrow` object)",
|
||||
"hub", "internal/store", "EscrowStatus", "controller"),
|
||||
# R-311. Declared the moment the wire was created, because the gate covers only what is DECLARED
|
||||
# and a silent pass is indistinguishable from coverage. The hub response is a named type rather
|
||||
# than a map[string]any precisely so this root can resolve — an untyped map is a cross-repo
|
||||
# contract nothing can check.
|
||||
("hub -> agent (GET /hosts/<id>/escrow/retained)",
|
||||
"hub", "internal/api", "RetainedEscrowResponse", "agent"),
|
||||
]
|
||||
|
||||
# Tag names whose literal string carries no information in a repo-wide search. NOT CHECKED.
|
||||
|
||||
Reference in New Issue
Block a user