722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 1 | # macltok review, 2026-10-25 |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 2 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 3 | Read-only review of everything that landed on 2026-10-25. In macltok that is |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 4 | event context pagination, the encrypted mentions inbox, bounded history repair, |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 5 | segmented history and the pack fixes, as published on `vapour` 8fd8dcf6. In the |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 6 | sdk fork it is the sliding sync commit fence, reseeding, room-owned history |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 7 | views, replacement snapshots, segmented history and cinny reaction shortcodes, |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 8 | up to 9b2c17fb1. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 9 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 10 | Nothing was built or run. Every finding was read against the code, and the |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 11 | ones marked verified were reread by hand after the reviewer reported them. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 12 | Ids carry a status that starts as OPEN. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 13 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 14 | ## S. sdk fork correctness |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 15 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 16 | ### S1. A limited sync can lose its gap. verified, OPEN |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 17 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 18 | `handle_sync` takes `older_boundary` from the in-memory linked chunk only |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 19 | (`event_cache/caches/room/state.rs:949`). After auto-shrink, or a restart with |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 20 | lazy loading, a room whose last chunk is the trailing gap from a recent load |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 21 | holds no events in memory. A limited sync for that room then records an |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 22 | ordinary gap and no `HistoryGap`. On reopen the retained events and the new |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 23 | ones render as continuous, which is the lost interval malice reported. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 24 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 25 | Fix direction. Take the boundary from the store's newest event when memory has |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 26 | none. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 27 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 28 | ### S2. An empty fill page panics when the next chunk is a gap. verified, OPEN |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 29 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 30 | `apply_page` always passes a gap to `push_backwards_pagination_events` |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 31 | (`room/history.rs:549`). With no events, `replace_gap_at` removes the gap and |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 32 | returns the next chunk's first position. If that chunk is itself a gap, |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 33 | `insert_gap_at` returns `ChunkIsAGap` and the `.expect` at |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 34 | `event_linked_chunk.rs:403` fires. On native the room's history coordinator |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 35 | dies and every later history call for the room returns `ClientDropped`. On wasm |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 36 | it likely takes the worker with it. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 37 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 38 | ### S3. A limited sync during a recent fetch leaves two adjacent gaps. OPEN |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 39 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 40 | The recent fetch captures its anchor before the network request |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 41 | (`room/history.rs:221`). A limited sync that lands meanwhile installs its own |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 42 | gap, and the fetch then inserts its events and gap after it. The stale sync gap |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 43 | shows as a gap row over continuous history, and filling it walks into S2. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 44 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 45 | ### S4. Every room open persists a gap chunk. OPEN |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 46 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 47 | The recent load persists a gap whenever an anchor exists, `Joined` included |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 48 | (`room/history.rs:284-319`). macltok runs it on every open, so joined gaps pile |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 49 | up in storage, in `history_gaps()` and in every gap publication. The trailing |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 50 | gap left behind is also what produces the empty in-memory chunk S1 needs. The |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 51 | `RecentHistoryOutcome.gap` doc says the field is absent when nothing needs |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 52 | joining, and it is not. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 53 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 54 | ### S5. `history_candidate` decrypts the whole room twice per operation. OPEN |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 55 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 56 | It walks every stored chunk under the state write lock, which also blocks the |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 57 | room's sync (`room/state.rs:805-825`). A recent load and each fill page do it |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 58 | twice, and the commit then holds the whole history in memory until shrink. The |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 59 | insertion loop at `history.rs:301-312` is also O(n·m). |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 60 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 61 | ### S6. sqlite event cache reads moved onto the write connection. OPEN |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 62 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 63 | 72db3bb7d moved `load_all_chunks`, `load_all_chunks_metadata`, |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 64 | `load_last_chunk`, `load_previous_chunk`, `filter_duplicated_events` and |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 65 | `find_event_relations` into `with_immediate_transaction` so that |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 66 | `register_linked_chunk_owner` can do a one-time `INSERT OR IGNORE`. Reads now |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 67 | serialise behind every write. Plausibly part of the slow sqlite login. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 68 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 69 | ### S7. Pinned and event-focused views die after a clear. OPEN |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 70 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 71 | `clear_loaded_views` drops the pinned cache and drains event-focused caches, |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 72 | while threads are cleared and kept (`room/state.rs:866-877`). An open pinned |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 73 | timeline gets a Clear and then a closed stream. An event-focused timeline gets |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 74 | a Clear, then `MissingCache` on paginate. An interrupted event-focused |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 75 | pagination reports `hit_end_of_timeline`. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 76 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 77 | ### S8. A room `Update::Clear` on error paths wipes view chunks under live caches. plausible, OPEN |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 78 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 79 | Room Clear now deletes thread and pinned chunks and standalone events on all |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 80 | three backends. The pagination and shrink error paths send it without calling |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 81 | `clear_loaded_views`, so loaded thread and pinned caches keep writing against |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 82 | chunk ids that no longer exist. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 83 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 84 | ### S9. Reset on the live timeline drops receipts and identities. OPEN |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 85 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 86 | The Reset arm of the timeline state transaction clears `read_receipts` and |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 87 | `fully_read_event` and never repopulates them |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 88 | (`timeline/controller/state_transaction.rs:216-231`). It also discards |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 89 | `recycled_timeline_ids`, so every surviving row gets a new id. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 90 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 91 | ### S10. A commit hook that never resolves stalls sync for good. OPEN |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 92 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 93 | The hook runs inside `handle_response` holding the position lock |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 94 | (`sliding_sync/mod.rs:338`). Nothing can cancel it, and every later |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 95 | `sync_once` and `expire_session` waits on that lock. macltok's hook always |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 96 | resolves today, so this is a hazard in the api, not a live bug. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 97 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 98 | ### S11. Smaller sdk findings. OPEN |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 99 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 100 | - `visited_cursors` grows by one cursor per page, forever, and is re-encrypted on every gap rewrite. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 101 | - `RoomEventCache::clear` and `reseed` `.expect` their join handles, so a task panic or runtime shutdown panics the caller. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 102 | - sqlite writes plain gaps as a bare string and history gaps as an object behind an untagged reader. Always writing the object would leave one reader shim. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 103 | - A downgrade fails to read history gaps and clears the room. Fine pre-1.0, noted. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 104 | - IndexedDB room Clear decrypts every chunk in the database to find one room's. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 105 | - The cinny `"shortcode"` field is a bare literal in three places, and `reaction_shortcode`'s doc says it only reads MSC4027. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 106 | - The pinned Lagged path subscribes to the new cache and keeps reading the old receiver. Upstream bug, now hit after every clear. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 107 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 108 | ## M. macltok correctness |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 109 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 110 | ### M1. The mentions inbox rewrites itself on every sync response. OPEN |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 111 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 112 | `batch` writes a new checkpoint for every response, typing and receipts |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 113 | included, and `save` serialises, encrypts and durably commits the whole inbox |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 114 | inside the sync hook (`mentions/service.rs`). With the 64 MiB default budget |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 115 | that is up to 64 MiB written per typing notification before `pos` may advance, |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 116 | at roughly four times that in peak memory. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 117 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 118 | Related costs on the same path. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 119 | - Every background completion also does a full save. Permanently undecryptable candidates are never dropped and retry forever with backoff capped at 256s, and any decryption report resets every candidate's retry. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 120 | - `filter_ignored` reads the ignore list from the state store once per entry per batch. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 121 | - Budget eviction drops one window and re-encrypts the whole inbox before checking again. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 122 | - Candidate eviction removes the smallest key, which means lexicographic room id, not the oldest. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 123 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 124 | ### M2. A mentions failure stops sync. OPEN |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 125 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 126 | A failed save fails the hook and the hook stops room list sync. An IndexedDB |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 127 | quota error means no messages at all. A corrupt mentions store fails |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 128 | `Account::build`, and the only way out is `StoreConfig::delete`, which also |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 129 | drops the crypto store. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 130 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 131 | ### M3. A crash between hook ack and `pos` write raises a false global gap. verified, OPEN |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 132 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 133 | The hook records `next_pos` P2 durably, then the process dies before the sdk |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 134 | writes `pos`. On restart the sdk replays with `previous_pos` P1, the checkpoint |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 135 | says P2, and `batch` treats it as a discontinuity, marking every observed room |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 136 | unresolved (`mentions/service.rs:404`). Keeping the previous checkpoint and |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 137 | accepting a replay from it would fix it. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 138 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 139 | ### M4. Event context lost what the timeline gave it. OPEN |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 140 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 141 | ywsvysot moved `EventContext` from an event-focused sdk timeline to raw |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 142 | `/messages` through `normalise_observed`. That fixed real bugs in the focused |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 143 | path, but items now have no display names or avatars, edits arrive as separate |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 144 | messages, reactions and redactions arrive as `Other`, replies stay |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 145 | `ReplyDetails::Pending` forever and UTDs never retry. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 146 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 147 | Also in context. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 148 | - Truncating a page to `limit` while returning the server's `end` token skips whatever was cut, and `limit: 0` is accepted for pages. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 149 | - Fetch awaits `before` and `after` one after the other. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 150 | - Context media go into the shared 2048-entry registry and are never released, so heavy context paging can evict media for rows still on screen. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 151 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 152 | ### M5. Cancel is reported as failure. OPEN |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 153 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 154 | A user Cancel and the cancel that runs on room close both publish |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 155 | `RecentHistoryState::Failed("…interrupted")` and a report with a failure and no |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 156 | stop (`engine/repair.rs:284`, `:347`). `HistoryRepairStop::Cancelled` exists |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 157 | and is never sent. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 158 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 159 | ### M6. Network failures report as store errors. OPEN |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 160 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 161 | `cache_error` maps every `EventCacheError` to `ErrorKind::Store` |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 162 | (`engine/repair.rs:444`), `PaginationError` included. The `Failed => Network` |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 163 | arm cannot be reached because the sdk returns the error after committing |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 164 | `Failed`. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 165 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 166 | ### M7. Every history completion sends a full reset. OPEN |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 167 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 168 | `publish_history` flushes and then always resyncs (`engine/timeline.rs:134-145`), |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 169 | so every completion, failures and close included, sends a `TimelineReset`, and |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 170 | every room open produces two. The segmented history doc promises incremental |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 171 | insertions. `tests/engine.rs` ignores resets during recent loading, which hides |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 172 | it. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 173 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 174 | ### M8. Smaller macltok findings. OPEN |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 175 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 176 | - The mirror never removes `recent_history` or `repairs` entries when a room closes, and `RecentHistoryState::Idle` is never emitted. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 177 | - `initial_history_limit` no longer applies to room timelines, and a failed recent load leaves a room with no initial history at all. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 178 | - An `Updated` result for an already joined gap still counts a page. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 179 | - The `Joined` gap arm in timeline normalisation cannot be reached, because the sdk drops joined gaps. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 180 | - A finished recent load publishes both `RecentHistoryChanged(Loaded)` and a `HistoryRepairReport` for the same edge. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 181 | - `evict_one` sets an entry's revision to the current one, not the next one, so revision-keyed consumers miss the change. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 182 | - Mentions in a room left within the same response are dropped by the joined check. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 183 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 184 | ## D. dead api and design |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 185 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 186 | ### D1. Most of the history repair api does nothing. OPEN |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 187 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 188 | `Start.budget` is validated and ignored. The policy is echoed and stored in the |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 189 | mentions inbox and never read. `Continue` always errors. `StartRecent` |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 190 | duplicates the open-time load. `GetPolicy` and `SetPolicy` in the actor are |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 191 | unreachable because the engine handles them first. Never emitted are |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 192 | `HistoryRepairStrategy::Overlap`, `HistoryRepairStop::Cancelled` and `NoAnchor`, |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 193 | `HistoryRepairPhase::FetchingRecent`, `coverage_duration_ms` and |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 194 | `threshold_evaluated`. Pre-1.0, so delete rather than keep them for serde. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 195 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 196 | ### D2. `HistoryGapLifecycle::Fetching` is never emitted. OPEN |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 197 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 198 | A consumer has to match a `Bridging` report's `gap_id` to know a gap is |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 199 | filling, then infer the end from a later report. Either emit it on the gap row |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 200 | while a fill runs or delete it. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 201 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 202 | ### D3. Mentions shapes. OPEN |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 203 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 204 | - `MentionGap.reason` is a string. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 205 | - `MentionCoverage.incomplete_history` is always true. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 206 | - Every newly seen room adds a gap and the list caps at 128, so `truncated` is true after the first sync on any account with more than 128 rooms. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 207 | - The store is a generic multi-record store with HMAC'd keys that only ever holds `"inbox"`. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 208 | - `MentionsCommand` is consumer-built and missing `#[non_exhaustive]`, and so are `HistoryRepairCommand`, `HistoryRepairPolicy` and `HistoryRepairBudget`. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 209 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 210 | ### D4. Pack shims. OPEN |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 211 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 212 | `clone_pack_image_with_usage`, `clone_sticker_with_usage` and |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 213 | `clone_pack_with_usage` sit beside wrappers under the old names. `known_usage` |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 214 | drops usage values it does not know, so clone stops being faithful for msc2545 |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 215 | extensions, and it duplicates the default-usage rule in |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 216 | `normalise::image_pack::usage`. `Some(vec![])` silently means inherit. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 217 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 218 | ### D5. `reseed` has no caller. OPEN |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 219 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 220 | `RoomEventCache::reseed`, its state method, `reseed.md` and its tests are about |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 221 | 500 lines of fork surface. macltok uses `fill_history_gap_once` and the |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 222 | segmented history doc says it does not reseed. The generation fencing stays, |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 223 | `clear` and `commit_history_candidate` need it. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 224 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 225 | ### D6. Event context shape. OPEN |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 226 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 227 | `EventContext.event` is optional but always present on success. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 228 | `EventContextPage.end_reached` repeats `next_token.is_none()`. The transport |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 229 | takes `u32` and clamps to 50 while the engine rejects anything over 50. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 230 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 231 | ## H. housekeeping |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 232 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 233 | - H1. sdk 9b2c17fb1 is only on the fork's `segmented-history` branch. The `macltok` branch is at 9b9b16982. Fast-forward it before tidying branches or cargo cannot fetch the pin. OPEN |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 234 | - H2. lyvnurlv d1313f47 is an empty change merged into vapour, and the segmented history doc cites it. At xnzknouu the pins are split three ways. OPEN |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 235 | - H3. `repair.rs` landed without rustfmt. OPEN |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 236 | - H4. `docs/segmented-history.md` says the lost interval drops are an earlier path, and both `prev_batch` drops are still at `state.rs:943`. It says concurrent history operations return `RoomBusy`, and only a fill does. Much of it is handoff status that will rot. OPEN |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 237 | - H5. `docs/mentions-discovery.md` says replies need a notifying highlight while the code accepts `direct` alone, and says context capture runs after the commit while the watch publication runs before the ack. OPEN |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 238 | - H6. American spellings in sqlite.rs and the mentions doc. OPEN |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 239 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 240 | ## Checked and sound |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 241 | |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 242 | - Gap metadata and the mentions inbox are encrypted at rest on sqlite and IndexedDB. The inbox head compare-and-swap holds. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 243 | - The sliding sync `pos` advances only after the hook acks, on both stores. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 244 | - Coordinator cancellation, shared recent fetches and atomic event, gap and cursor commits. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 245 | - The old timeline watcher stops before the reset goes out, and the mirror ack precedes the command reply. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 246 | - Both merges keep both sides. All nine sdk pins and both lockfiles agree on 9b2c17fb1. |
722b4c3d0a09 | atagen | 2026-10-25 08:14 UTC | 247 | - The spare sdk worktrees hold nothing that is not already committed. |