c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 1 | # Segmented history implementation |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 2 | |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 3 | The durable implementation is in the macltok `segmented-history` feature |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 4 | worktree. The combined SDK revision |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 5 | `9b2c17fb10703d90b177b02588912a34cecfa11f` is published on its |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 6 | `segmented-history` bookmark. It includes the reaction compatibility fix from |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 7 | `c0a` and segmented history from `49a9`. The macltok history branch includes |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 8 | pack fixes from `e4bb841a` and the `macltok-pack-fixes` worktree through |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 9 | `d1313f47`. All nine SDK pins and both lockfiles use the combined SDK revision. |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 10 | The unified macltok bookmark is named `segmented-history`. |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 11 | |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 12 | ## Current behavior |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 13 | |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 14 | Opening a room loads retained history and its gap rows, then fetches a bounded |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 15 | recent window from a fresh server position. The recent fetch is capped at four |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 16 | pages of 50 raw events. It preserves retained sections and their older cursors. |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 17 | If it cannot establish continuity, it installs a durable gap between the |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 18 | sections. It stops when continuity is established or accessible history ends. |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 19 | |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 20 | `HistoryRepairCommand::FillGap` takes a room ID and stable gap transaction ID. |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 21 | It fetches up to four backward pages of 50 events and advances only that gap's |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 22 | saved cursor. Fill progress and events commit atomically. Concurrent history |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 23 | operations for the room return `RoomBusy`. An empty page with an advancing |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 24 | cursor keeps the gap. A repeated cursor pauses it. Accessible history ending |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 25 | before the retained boundary marks the interval unavailable. Only reaching the |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 26 | retained boundary joins sections. Already joined gaps are harmless to stale |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 27 | callers. |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 28 | |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 29 | The cache stores gap identity, boundary evidence, cursor, and status alongside |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 30 | the encrypted linked event chunks. SQLite supports legacy token data and the |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 31 | new metadata. IndexedDB stores the optional encrypted metadata field. Room |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 32 | close and restart retain sections and fill cursors. Timeline snapshots and |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 33 | incremental updates project gaps as `TimelineItem::HistoryGap`. Gap rows retain |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 34 | their identity while status changes. Joined markers disappear and unavailable |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 35 | intervals remain visible. |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 36 | |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 37 | The recent fetch can complete while live sync continues. Cache installation |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 38 | uses a candidate state and commits events, gap metadata, and cursor together. |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 39 | Sync publication is serialized with gap installation. Existing loaded timelines |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 40 | receive incremental insertions that preserve retained item identities and |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 41 | pending sends. Loading history outside the current timeline window still needs |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 42 | a reset. |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 43 | |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 44 | Each SDK room cache owns a coordinator task. Recent callers share an in-flight |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 45 | request. Cancelling one caller preserves the operation for other subscribers, |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 46 | and cancelling all callers stops fetching before installation. Started commits |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 47 | finish before the coordinator accepts conflicting work. No mutex guard crosses |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 48 | the network request. The idle task holds only a weak cache reference, so it does |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 49 | not keep a room cache alive. The SDK UI calls `wait_for_history` as a fence, |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 50 | then takes an atomic event and gap snapshot while replacing its cache |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 51 | subscription. The macltok watcher is stopped before its timeline reset is sent, |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 52 | so old diffs cannot arrive after the reset. A mirror publication acknowledgement |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 53 | completes before the command response is released. The room actor starts recent |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 54 | loading in the background when the room opens, so opening does not wait for the |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 55 | network request. |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 56 | |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 57 | Limited sync results persist explicit gap markers in the event cache. Later sync |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 58 | updates preserve those markers until the pagination chain reaches the retained |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 59 | boundary. The integration uses the room's live timeline flush and watcher reset |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 60 | path. It does not reseed the cache. Thread and pinned timelines remain open |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 61 | through this update path. |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 62 | |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 63 | ## Public and wire shapes |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 64 | |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 65 | `ClientHandle::fill_history_gap(room_id, gap_id)` is the convenience method for |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 66 | the targeted fill. It returns `Result<(), Error>`. The underlying command is |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 67 | `HistoryRepairCommand::FillGap { room_id, gap_id }`, sent as |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 68 | `Command::HistoryRepair`. The older policy and staged repair command variants |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 69 | remain available for serde compatibility, but room opening no longer consults |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 70 | the saved policy. `Continue` is invalid because continuation must identify its |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 71 | gap. `GetPolicy` and `SetPolicy` remain compatibility operations and do not |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 72 | control opening. |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 73 | |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 74 | The inline gap lifecycle value `Fetching` is reserved and is not currently |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 75 | emitted by timeline projection. During a targeted fill, loading is signaled by |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 76 | a `HistoryRepairReport` with `gap_id` set and `phase` set to `Bridging`. Recent |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 77 | loading has its own room keyed `RecentHistoryState` with |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 78 | `Idle`, `Loading`, `Loaded`, or `Failed` values. The mirror exposes that state in |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 79 | `recent_history`, separately from gap continuity and repair progress. |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 80 | |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 81 | `TimelineItem::HistoryGap` carries a `HistoryGap` with `id`, |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 82 | `older_boundary`, `newer_boundary`, `lifecycle`, `continuity`, and `failure`. |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 83 | Lifecycle values are `Idle`, `Fetching`, `Paused`, `Failed`, and `Unavailable`. |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 84 | Continuity values are `Unresolved`, `Verified`, and `AccessibleStart`. The gap |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 85 | ID is an owned transaction ID. Boundary values are optional owned event IDs. |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 86 | Failure is an optional displayable string. `TimelineState.items` contains these |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 87 | items in order with event rows. Mirror snapshots serialize the same item shape, |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 88 | and incremental timeline changes carry it through the normal reset or changed |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 89 | diff. |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 90 | |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 91 | Serde enums use externally tagged variants. A command payload is shaped as |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 92 | follows, with the outer `Command` adding its `HistoryRepair` tag. |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 93 | |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 94 | ```json |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 95 | { |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 96 | "HistoryRepair": { |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 97 | "FillGap": { |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 98 | "room_id": "!room:example.org", |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 99 | "gap_id": "opaque-gap-transaction-id" |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 100 | } |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 101 | } |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 102 | } |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 103 | ``` |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 104 | |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 105 | A gap row in `TimelineState.items` has the following shape. |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 106 | |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 107 | ```json |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 108 | { |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 109 | "HistoryGap": { |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 110 | "id": "opaque-gap-transaction-id", |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 111 | "older_boundary": "$older:example.org", |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 112 | "newer_boundary": "$newer:example.org", |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 113 | "lifecycle": "Idle", |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 114 | "continuity": "Unresolved", |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 115 | "failure": null |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 116 | } |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 117 | } |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 118 | ``` |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 119 | |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 120 | The mirror snapshot stores recent loading separately by room ID. This fragment |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 121 | shows the serialized `State.recent_history` field. |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 122 | |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 123 | ```json |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 124 | { |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 125 | "recent_history": { |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 126 | "!room:example.org": "Loading" |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 127 | } |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 128 | } |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 129 | ``` |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 130 | |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 131 | The final history repair publication acknowledgement is internal, skipped by |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 132 | serde, and not part of application wire data. The mirror applies the report |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 133 | before acknowledging it, so command completion follows publication. |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 134 | |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 135 | ## Malice integration |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 136 | |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 137 | Pin the published macltok `segmented-history` revision in Malice's native and |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 138 | worker manifests and regenerate their lockfiles. The SDK dependency is already |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 139 | pinned by macltok. |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 140 | |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 141 | Malice should remove the saved policy and threshold controls from room opening. |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 142 | Render each inline gap between its neighboring event sections. A fill should |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 143 | preserve the visible event anchor, composer draft, reply or edit state, pending |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 144 | sends, and encryption identity. Keep event-context windows independent from |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 145 | live room history. |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 146 | |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 147 | ## Lost interval investigation |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 148 | |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 149 | The reported failure showed retained events followed by newly sent messages, |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 150 | with an omitted interval of roughly eight to ten hours presented as continuous. |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 151 | Older pagination continued before the retained buffer, and a page refresh did |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 152 | not recover the missing range. A refresh can reconnect to the existing |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 153 | SharedWorker, so it does not prove that the engine restarted. |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 154 | |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 155 | The earlier SDK cache path could discard a limited-sync boundary token when a |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 156 | timeline was reported unlimited despite cached events. It could also discard a |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 157 | token when all incoming events were duplicates. Both cases can hide a real |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 158 | discontinuity from older pagination. Initial pagination could also finish |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 159 | against retained history before fresh sync arrived. These are concrete failure |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 160 | paths, but none has been confirmed as the production cause. The durable gaps |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 161 | preserve discontinuities when observed. Startup, subscription, and sync |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 162 | diagnostics are still needed to identify where this particular interval was |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 163 | lost. |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 164 | |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 165 | ## Validation commands |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 166 | |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 167 | Run native checks from `../macltok-history-repair` with the repository's Nix |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 168 | toolchain. |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 169 | |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 170 | ```sh |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 171 | nix develop --command cargo test --all-targets |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 172 | nix develop --command cargo test --all-targets --features sqlite |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 173 | nix develop --command cargo clippy --all-targets -- -D warnings |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 174 | nix develop --command cargo clippy --all-targets --features sqlite -- -D warnings |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 175 | ``` |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 176 | |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 177 | For the browser worker runtime, use the web devshell. The harness starts a local |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 178 | homeserver and runs both worker targets in Firefox. |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 179 | |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 180 | ```sh |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 181 | nix develop .#web -c nu harness/web/run.nu |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 182 | ``` |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 183 | |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 184 | The flake checks include native and WebAssembly compilation with IndexedDB and |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 185 | the web worker runtime. The default native gate passed all 86 tests. The |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 186 | aggregate `nix flake check` run stopped during the SQLite and mirror build. |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 187 | The remaining aggregate gates were waived for this handoff and have not passed. |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 188 | The focused native history repair and engine suites passed all 11 tests with |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 189 | SQLite, mirror, and serde enabled against the published combined SDK revision. |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 190 | |
c9f0fd0ee1cc | atagen | 2026-10-25 06:16 UTC | 191 | Seven focused SDK recent-history tests and seven segmented-history tests pass. |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 192 | The SDK WebAssembly compile passes with IndexedDB enabled. SDK UI timeline |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 193 | checks pass with 123 unit tests. Separate SDK room checks pass with seven unit |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 194 | tests and 14 timed integration tests. Two headless Firefox tests pass for the |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 195 | IndexedDB shared gap storage contract with plaintext and encrypted stores. The |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 196 | full SQLite and mirror gate, aggregate WebAssembly gate, and browser worker |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 197 | runtime gate remain unverified. Complete worker restart and encrypted room |
9eabb6b7587d | atagen | 2026-10-25 07:08 UTC | 198 | recovery remain integration acceptance checks. |