MetaMask / MetaMask/metamask-extension
Storage Resilience E6: Detect Silent State Loss & Improve Corruption Metrics
- Dominant language
- TypeScript
- Stars
- 13.2k
- Forks
- 5.6k
- Avg merge
- 2d 5h
- Merged PRs (30d)
- 451
Description
### What is this about?
## Goal
Distinguish a controller that legitimately defaulted from one whose persisted state was silently dropped, and tag which keys corrupt together.
## Why
Today we can't tell "initialised to defaults" from "persisted then lost". Silent rehydration masks the true corruption rate and blocks prioritisation of E1–E5. (H5 — medium)
## Success criteria
- Every persisted controller can distinguish "never persisted" from "persisted then lost".
- Sentry receives a corruption event tagged with the affected key(s) / key-group on silent loss.
- Post-corruption analysis can show *which* keys were co-located in the corrupt block (validates H1).
## Tasks
- [ ] (Core write-frequency + size instrumentation lands in **E0**; this epic builds the silent-loss detection on top.)
- [ ] Per-controller "has-been-persisted-before" marker in the manifest (`initialised: true` or equivalent).
- [ ] On startup, if a controller sees `initialised: true` but its key is missing/null, emit a `silent-state-loss` Sentry event with the logical key name.
- [ ] Track which keys/key-groups corrupt when recovery fires — add a `corrupted-keys` field to the recovery event.
- [ ] Add key-class tags across all persistence events (`legacy-manifest`, `legacy-critical-state`, `manifest-replica-copy`, `generated-state-value`, `quota-or-no-space`, `degraded-persistence-entered`, …) per [ADR §Observability](https://github.com/MetaMask/decisions/blob/codex/extension-storage-resilience/decisions/extension/0008-storage-resilience.md#observability).
- [ ] Sentry dashboard grouping by `persistence.storage_key_class` and corrupted-key-family — enables rollout analysis for E1, E3, E5, E8.
- [ ] Separate `FILE_ERROR_NO_SPACE` / quota events into their own dashboard (feeds E7).
## Dependencies
- **Depends on:** E0 (baseline instrumentation); benefits from E3 (largest caches out → cheaper stringify).
- **Unblocks validation for:** E1, E3, E5, E8; inputs to E7.
### Scenario
_No response_
### Design
_No response_
### Technical Details
_No response_
### Threat Modeling Framework
_No response_
### Acceptance Criteria
_No response_
### Stakeholder review needed before the work gets merged
- [ ] Engineering (needed in most cases)
- [ ] Design
- [ ] Product
- [ ] QA (automation tests are required to pass before merging PRs but not all changes are covered by automation tests - please review if QA is needed beyond automation tests)
- [ ] Security
- [ ] Legal
- [ ] Marketing
- [ ] Management (please specify)
- [ ] Other (please specify)
### References
_No response_
Contributor guide
Research direction
Start with the linked storage-resilience ADR's Observability section and confirm the E0 baseline instrumentation before scoping this epic. Map the persistence controllers, manifest marker, recovery events, and Sentry dashboards, then define completion against the silent-loss, corrupted-keys, key-class, and quota-event success criteria.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- observability
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100