# M10-06 Status status: done task: Simulation cache cancellation, playback gate, LRU, restart and corruption isolation updated: 2026-08-16 America/New_York ## Scope Simulation cache playback is now a lifecycle-gated operation. A cache may be read by frame only after the current Storage Worker has completed a full manifest, payload and per-frame hash verification. This closes cache lifecycle safety; it does not implement Simulation Zone evaluation, browser bake generation, or GN modifier seek semantics. ## Protocol and Client - `SIMULATION_CACHE_NOT_READY`, `SIMULATION_CACHE_CANCELLED` and `SIMULATION_CACHE_BUDGET_EXCEEDED` are stable error codes. - `verifySimulationCacheCancellable` checks cancellation between total and per-frame SHA-256 work. `StorageClient` accepts `AbortSignal`, removes an aborted request from `pending`, and sends a `cancelRequest` to the Worker so late responses cannot publish. - `planSimulationCacheLRU` sorts removable entries by `lastAccessAt`, `createdAt`, and `cacheKey`; active playback keys are protected. If protected entries alone exceed the requested budget, the result reports `budgetSatisfied: false` instead of evicting them. ## Storage Contract - IndexedDB schema 7 adds `simulation_quarantine`; the M10-06 Chromium test creates a temporary schema 6 database and verifies the real v6 to v7 migration and store. - `prepareSimulationCachePlayback` performs full verification in the current Worker and activates the key. `readSimulationCacheFrame` rejects unprepared keys, while `release` removes readiness and LRU protection. A successful full read also establishes verified readiness for compatibility with existing callers. - `pruneSimulationCaches` removes deterministic LRU manifests and deletes their unreferenced simulation assets. Active playback is automatically protected. - Invalid manifests and missing, truncated, or hash-mismatched payloads are moved from `simulation_manifest` to `simulation_quarantine`. Quarantine preserves the bad row for diagnostics while valid cache listing and playback continue. ## Evidence - `WEB_TEST_PORT=5464 npm --prefix web run test:simulation-cache-lifecycle`: unit 5/5 and real Chromium 1/1. It covers v6 to v7 migration, post-restart `NOT_READY`, full verification, StorageClient cancellation, BrowserTransform playback cancellation with zero published frames and zero pending requests, active-cache LRU protection, release, cancelled write cleanup, OPFS byte tamper, and quarantine listing. - `WEB_TEST_PORT=5460 npm --prefix web run test:simulation-cache-identity`: unit 5/5 and Chromium 1/1. Existing graph/source/revision stale filtering remains green. - `WEB_TEST_PORT=5461 npm --prefix web run test:simulation-cache`: identity and existing Worker-restart smoke 2/2. - `WEB_TEST_PORT=5462 npm --prefix web run test:simulation-cache-performance`: 600/600 frames, OPFS backend, 6,639 ms total, 0 pending requests after terminate, and restart recovery passed the 30,000 ms gate. - Targeted schema/snapshot smoke 2/2 and recent-project recovery 4/4 passed after the schema version update. Full unit suite passed 138/138; typecheck, lint, production build (73 modules), local-dependency check, and `git diff --check` passed. The first lifecycle run was not accepted as evidence because the test helper returned the numeric legacy `DOMException.code` value `20` instead of the `AbortError` name. The helper was corrected and the complete command was rerun on port 5459, then rerun again on port 5464 after adding playback cancellation and migration assertions. ## Implementation Hashes - Simulation protocol: `3025db84bd4e0151b8894a457c51da630d628afb1760e2f0caeec003f0efce3f`. - Storage protocol: `2711dbab0c52a566679b83d5e4d793ec0ffd3f991e744dce765b6bdc54d25c13`. - Error registry: `7ebff554dd6346b539215a6545c67806bca2ead33953700b79c0910fd0cfb408`. - Storage Worker: `e31d7dcf93c5dcefb7e6c4cfd7874c748f972849ee7d93adb6294f82aafcf236`. - Storage client: `aaa3a03e3b91452e90a661566407c261c7a16b1671ed55ec948de7626d49bfa4`. - Storage migration: `8de1fcbbda9d7a4e7496995306c4e9fc83224211a516cf7241496b6a145953b5`. - OPFS helper: `2e8ef9d72194bf803a7e823fb2b7de30b9f10ae6dd4b031b81b97ff82eee9cc6`. - Unit test: `4ece0f5051667b04fab78c81a847def7a0c77d9267bd9e4fa2bbe4b9308125bf`. - Lifecycle Chromium spec: `861d370f72896987cef65d2e4d78ab3edcc1d4828d4a0fa0b5301b72a4a2932a`. - Identity regression: `aa305871e8651018342b123112beab10a43dab3313e2c9765e450dc91c08b6e1`. - Performance regression: `d7083c24789fc5877a7841bf611aee0ff471cc191621de1b30720d637635b44c`. - Smoke/recovery version updates: `2d15e5bf54a1dcdec1686ee937a510a7521ad44b152c895289a152ea711fadf4` / `a4d6279f05b6215f2e34cd5f1d76ebb6d5ed2cc765859c2ae0af975623f93b2c`. - Package: `fe90c0bd741a7840f6184726737a1a93c606841b8408dd7fd6dec823a8352cf6`. ## Rollback Remove the schema 7 migration and `simulation_quarantine` store, restore frame reads to the schema 6 identity-only contract, remove cancellation/LRU/playback commands and the M10-06 tests/status entry, then restore the M10 count to 5/15. Do not retain schema 7 databases with a schema 6 reader.