mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-23 18:51:11 +00:00
* fix(imessage): adopt durable ingress drain with cursor advanced after append The chat.db watcher advanced its ROWID cursor after yielding rows to an in-memory pipeline; a crash between read and dispatch skipped those messages forever. Raw rows now journal durably (event_id = message GUID, lane per chat) at the monitor chokepoint, and the cursor advances only after the durable append — mirroring Telegram's offset-after-spool contract. Dispatch runs through the core drain with deferred claims, merged fan-out adoption, and gated settlement; legacy catchup enters the same raw path. The transitional GUID replay guard is deleted per the layering contract with 4h/10k tombstone parity; the permanent age fence and recovery caps are untouched. Twin verdict: tapbacks are distinct rows with their own ROWID/GUID; fresh-GUID stale backlog remains age-fence territory (upstream imsg source cited in PR). Autoreview blocked by codex sandbox network in the build stage; full manual review performed. Part of the #109657 fleet adoption program (wave 2). * fix(imessage): exempt operator-requested catchup rows from the live age fence Landing review caught real message loss: legacy catchup accepts rows up to its configured maxAge (120min default), but the unified durable path ran them through the 15-minute live Push-flush fence — suppressing AND tombstoning any catchup row older than 15 minutes, permanently losing history the operator explicitly asked to replay. Catchup rows now carry provenance through the journal payload and skip the live fence; the catchup query's own maxAge window is their age gate. Regression test proves provenance survives the durable round trip. * test(imessage): resolve ingress rebase mocks * docs(imessage): document the fence-suppression vs catchup overlap tradeoff * fix(imessage): satisfy durable ingress lint gates