Observed in production on 2026-09-22 (utcDay 20717):
~/.local/share/devin/cli/sessions.db legitimately deleted ~22,661 message_nodes rows attributed to utcDay 20717 within ~7 hours (APFS snapshot at ~13:00 PDT showed 30,642 rows; live read at ~17:45 PDT showed 7,981). Freelist stayed at 42 pages — WAL-resident deletion.
- The account had already committed devin-cli stats for day 20717. Every subsequent
preserve-history upload covering that day is correctly refused with replacement_required — the stored rows exceed what the source now yields.
- The refused flight is retained; the next autosubmit cycle's
resume re-sends the identical bytes and refuses again, so the wedge blocks all configured clients until a manual stats-sync --abandon fences and clears it.
Resolution used here: --abandon the refused flight, republish non-regressed days individually (20714–20716, 20718 committed at r29/r31), and narrow the devin-cli publish window via the new per-client days override (#367) so the shrunken stored day leaves the range on the next cycle. Stored day 20717 remains as committed history — the usage was real even though the source rows are gone.
Design gap worth tracking: the protocol deliberately has no override for a shrunken stored day, which is right for hiding data loss but forces operational workarounds for volatile sources. Options if this recurs: (a) per-client publish windows that cover only closed days (commit each day once, never re-cover), (b) an attested source-reduction reconcile mode, or (c) keeping the narrow-window convention permanently for volatile clients.
Evidence: snapshot vs live counts at ~/.aicharts-livequal2/devin-snap/ (sessions.db + WAL clones); refused flight retained in stats-sync-v2.current (sequence 25, expectedRevision 27).
Observed in production on 2026-09-22 (utcDay 20717):
~/.local/share/devin/cli/sessions.dblegitimately deleted ~22,661message_nodesrows attributed to utcDay 20717 within ~7 hours (APFS snapshot at ~13:00 PDT showed 30,642 rows; live read at ~17:45 PDT showed 7,981). Freelist stayed at 42 pages — WAL-resident deletion.preserve-historyupload covering that day is correctly refused withreplacement_required— the stored rows exceed what the source now yields.resumere-sends the identical bytes and refuses again, so the wedge blocks all configured clients until a manualstats-sync --abandonfences and clears it.Resolution used here:
--abandonthe refused flight, republish non-regressed days individually (20714–20716, 20718 committed at r29/r31), and narrow the devin-cli publish window via the new per-clientdaysoverride (#367) so the shrunken stored day leaves the range on the next cycle. Stored day 20717 remains as committed history — the usage was real even though the source rows are gone.Design gap worth tracking: the protocol deliberately has no override for a shrunken stored day, which is right for hiding data loss but forces operational workarounds for volatile sources. Options if this recurs: (a) per-client publish windows that cover only closed days (commit each day once, never re-cover), (b) an attested source-reduction reconcile mode, or (c) keeping the narrow-window convention permanently for volatile clients.
Evidence: snapshot vs live counts at
~/.aicharts-livequal2/devin-snap/(sessions.db + WAL clones); refused flight retained instats-sync-v2.current(sequence 25, expectedRevision 27).