a2e914f683
gates / gates (push) Successful in 7s
A hub the agent could not reach was reported to the customer as a bad recovery code. Measured live 2026-08-05 (CAMPAIGN-11 F3): hub firewalled off, a CORRECT current code, and the customer told it did not open their package — in 0.0556s against ~1.0s for a real unseal. No unseal was attempted. The discriminator existed here and this boundary threw it away: recover.go fails at four distinguishable points and the local-api handler had cases for two, with a default answering 'the recovery code did not open the sealed bundle, OR the bundle could not be fetched'. escrow.ErrBundleFetch now joins the fetch leg and the handler routes it to 502 with its own words — the code was NOT used. 502 not 4xx: the request was not bad, an upstream dependency failed. Four situations, four statuses: 502 fetch / 400 fetched-and-refused / 404 no bundle / 409 predates the field. The controller classifies on the STATUS and never parses the sentence. A GREEN TEST NAMED THIS DEFECT AND DID NOT PREVENT IT. TestRecoverOffsiteRepoPassword_FetchErrorIsDistinct has said since v0.125.0 that the operator must not be sent to re-read their code because the hub was unreachable — and passed throughout, because it asserted this package's error STRING one layer below the merge, and a string is not something a caller can branch on. Re-pointed at the sentinel, with a consequence-level twin asserting the status. Red-proofs: removing the %w join fails the sentinel test; deleting the handler case makes fetch and wrong-code both answer 400 with the wrong-code sentence. 29 packages ok, vet clean, agent gates OK.