Protected update recovery needs each verified metadata prefix retained before the SDK writes its cache in place. Add maintained extensions to pinned tuf-js 6.0.0: an awaited, copy-owning onVerifiedMetadata observer, an owned finite referenceTime, public operational failure types and preserved raw causes. Existing staging/enrollment callers pass neither option; upstream cryptographic checks remain in place.
verified remote metadata -> awaited observer -> SDK cache write -> next role
observer rejection -> PersistError with original cause -> abortCache-preferred refresh previously swallowed a rejected timestamp observer and retried the same in-memory version. Both an ordinary rejection and a later Symbol rejection reproduced that bypass through the public interface. The corrected guard propagates persistence failure, and wrapper messages never coerce caught values. Direct regressions require exact cause identity, timestamp-only requests and a root-only cache; throwing string conversions are checked across all four roles. Snapshot/targets wrappers retain their nested causes. MetadataVerificationError identifies the attempted verification phase/role, not proof of invalid input or permission to discard protected state. Persistence takes precedence even when an observer itself throws a verification error. Discard failed updater instances because upstream in-memory state may already have advanced.
Validation for 32330728f853f9013a1845fdb15ea8bde15c4319: 62 focused tests, zero failures and 338 assertions, including 28 SDK cases and prior staging/enrollment/diagnostics. App/runtime types, Pickier, docs and compiled portable CLI checks pass. A minified executable copied outside the checkout checks four public operational outcomes, including the Symbol rejection. A clean frozen install reproduces all 19 published SDK files with independent inodes; an extra empty Bun installer marker is accounted for separately. Both independent review axes have zero remaining actionable findings. The earlier real child-only EFBIG probe preserves the original IO cause and demonstrates cache truncation, not protected storage durability.
The original MIT notice and exact npm/source provenance are retained. Historical replay never authorizes firmware use; fresh verification at a trusted current wall time is still required. Protected prefixes/floors, clock/key lifecycle, recovery, slots and identity-bound health remain in #42/#9. Physical deployment remains disabled. Initial enrollment and diagnostic correction #43 are now published to main after all five exact-head CI jobs passed. Original browser cause #44 remains open.
Full exact-head CI 39657133947 succeeded across all five jobs. The native suite reported 1,439 passes, 39 skips, zero failures and 488,485 assertions across 178 files. Corrected commit 32330728f853f9013a1845fdb15ea8bde15c4319 is now published to origin/main by a normal fast-forward push as Chris, without coauthor trailers. GitHub reports this PR merged. The earlier head85 CI also passed but was not published independently because its later-discovered Symbol bypass required this correction. Refs #42, #9; both remain open.