Summary
src/lib/enbox/agent-store.ts has grown to ~1,800 lines, and useAgentStore.reset() plus the four crash-resilience sentinels it manages now occupy roughly a third of the file. The four sentinels — VAULT_RESET_PENDING_KEY, LEVELDB_CLEANUP_PENDING_KEY, AUTH_RESET_PENDING_KEY, SESSION_RESET_PENDING_KEY — follow an identical pattern but are wired up imperatively, with one bespoke `runPendingXCleanup()` helper per sentinel.
This issue tracks extracting the reset machinery into a self-contained module with a single sentinel-registry abstraction.
Current Pain Points
agent-store.ts mixes agent lifecycle, biometric event handling, identity creation, recovery-phrase staging, and reset/cleanup orchestration in one file.
- Each sentinel has its own:
XYZ_RESET_PENDING_KEY constant declaration (with extensive prose).
runPendingXyzCleanup() helper.
- Per-step write-before-wipe, fail-CLOSED-on-write, clear-after-success branches inside
reset().
- The four helpers duplicate
await storage.get(key); if (pending !== 'true') return; await wipe(); await storage.remove(key); with cosmetic variations.
- Adding a fifth sentinel would mean another ~80 lines of boilerplate in
agent-store.ts plus another bespoke runner.
Proposed Direction
- Move all reset / sentinel code into
src/lib/enbox/reset/ (or a sibling module).
- Define a
ResetSentinel abstraction with: storage key, wipe function, and (optionally) a vault-intact predicate for false-alarm suppression.
- Replace the four bespoke runners with one driver:
await runPendingResetCleanups([sentinels]).
- Keep `reset()` itself focused on orchestration (write all sentinels → wipe in order → clear sentinels), delegating per-sentinel mechanics to the registry.
- Preserve the existing crash-resilience and fail-CLOSED guarantees:
- All sentinels persisted before any wipe begins.
- Aggregated rollback failures surfaced (not swallowed).
- Vault-intact defensive guard (introduced for the cold-launch retry path) reused per sentinel rather than hard-coded to one.
Acceptance Criteria
src/lib/enbox/agent-store.ts is under ~1,000 lines.
- A single
ResetSentinel definition declares each retry sentinel; no per-sentinel runPendingXyzCleanup() helpers remain.
- All existing reset-blockers test cases (
src/lib/enbox/__tests__/agent-store.reset-blockers.test.ts) pass without semantic changes.
- New tests cover the registry's contract directly (one test surface per behaviour, not per sentinel).
- Public API of
useAgentStore is unchanged.
Out of Scope
- Changing the on-disk SecureStorage key names (would break existing installs).
- Introducing new sentinels.
Summary
src/lib/enbox/agent-store.tshas grown to ~1,800 lines, anduseAgentStore.reset()plus the four crash-resilience sentinels it manages now occupy roughly a third of the file. The four sentinels —VAULT_RESET_PENDING_KEY,LEVELDB_CLEANUP_PENDING_KEY,AUTH_RESET_PENDING_KEY,SESSION_RESET_PENDING_KEY— follow an identical pattern but are wired up imperatively, with one bespoke `runPendingXCleanup()` helper per sentinel.This issue tracks extracting the reset machinery into a self-contained module with a single sentinel-registry abstraction.
Current Pain Points
agent-store.tsmixes agent lifecycle, biometric event handling, identity creation, recovery-phrase staging, and reset/cleanup orchestration in one file.XYZ_RESET_PENDING_KEYconstant declaration (with extensive prose).runPendingXyzCleanup()helper.reset().await storage.get(key); if (pending !== 'true') return; await wipe(); await storage.remove(key);with cosmetic variations.agent-store.tsplus another bespoke runner.Proposed Direction
src/lib/enbox/reset/(or a sibling module).ResetSentinelabstraction with: storage key, wipe function, and (optionally) a vault-intact predicate for false-alarm suppression.await runPendingResetCleanups([sentinels]).Acceptance Criteria
src/lib/enbox/agent-store.tsis under ~1,000 lines.ResetSentineldefinition declares each retry sentinel; no per-sentinelrunPendingXyzCleanup()helpers remain.src/lib/enbox/__tests__/agent-store.reset-blockers.test.ts) pass without semantic changes.useAgentStoreis unchanged.Out of Scope