Merged into `main` at **683b9afa**, tagged **v0.1.30-pre.45**, the issue resolved. `staging` fast-forwarded to the same sha.
The tip I merged is the tested sha `c7591861`, and it already carried `main` at `56631063` merged and re-gated, so nothing was owed on my side: `merge-base --is-ancestor 56631063 c7591861` exits 0, `merge-tree --write-tree` was clean, and the CHANGELOG came out ten insertions and no deletions, both Added bullets verbatim with the sticker bullet first — placement, as declared.
**No step re-walked.** Your hunk-by-hunk reading of the sticker merge is the instrument and it holds: `ChatScreen`'s sticker hunks are nowhere near the `items(entries)` tail that draws the pruned-history note, `GroupListPane`'s one hunk is a lone-sticker preview branch that neither a text line nor a numeric badge can reach, and `AppPrefs` and the catalogues are additive on both sides.
**The two carries, judged.**
- **Multi-device (issue step 10)** leaves nothing behind and sets no condition. I read it off the tree rather than taking the mechanism: both `MultiDeviceService` ingestion sites (`:1342`, `:1448`) pass `emptyList()` in the message-rows position, so no sibling path stores a message row at all, and `pruned_below_cursor` appears in `cordn-store`, `cordn-sync`'s `Ingestion`, `AccountSession`, `BackupRestorer` and `Models` and in no sync-document code — the floor is local and travels nowhere. A carry that leaves no code of ours unexecuted leaves no condition.
- **"The IndexedDB record is smaller" (issue step 11)** does leave one, and it is narrower than the step. `e2e/storage.mjs`'s last check accepts `Nothing to remove|removed from|Back up first`, and a fresh browser profile has no chats, so what the browser run observed is the page, the budgets and the button — not a sweep that deleted anything. `RetentionService:92`'s `store.vacuum()` and the delete path under it have therefore executed through the Android driver only, and `VACUUM` rewrites the whole file, which is exactly the operation an IndexedDB-backed VFS does differently. The `cordn-store` retention tests run in `wasmJsBrowserTest` against `InMemoryDriver`, so they do not reach it either.
**Condition (13):** a landing touching `RetentionService`'s sweep or `AccountStore.vacuum()` has a browser prune that actually deletes something — so the delete and the `VACUUM` execute through the wasmJs driver — once the walk can seed a chat past a budget without a real coordinator. Spendable the moment `storage.mjs` can put rows in.
Four declarations in this change are unfiled and I am not filing them over the room: `SettingsSectionsTest`'s guard holding `settingsSections()` against a route table written out by hand inside the test (the one you deliberately left alone), the per-chat override, windowing the timeline read (`selectLatestByGroup` still called by nothing, `messages(gid)` still loading every row), and the other tables that only grow. Say which pr-silo files and the rest come with the next sweep.
The three defects found before the steps proper are the reason this landed as it did. The Storage row drawing nowhere is the kind of thing a browser walk catches and a phone walk would have missed only because the sidebar *is* the way in on a desktop; the nine megabytes of kept MLS state dressed up as a prunable figure would have invited somebody to set a budget against a number nothing on the page can move; and the stale-backup case is the one the warning matters most in. Finding all three before walking the steps, rather than through a failed step, is the shape of run I would ask for.