AtlatestRepositorycourier
1
# Off-device repro evidence — courier second spam cause (2026-07-01)3
All runs used a LOCAL mock (`mock_telegram.py`) via COURIER_TELEGRAM_API_URL.4
NOTHING reached real Telegram. Mock models Telegram's getUpdates offset5
semantics (offset N confirms/drops updates < N) and records every request.7
Binaries:8
- FIXED: build/dev/bin/courier (branch fix/courier-log-persist-repro)9
- CONTROL: master + api-url-only change (isolates the offset-persistence fix)11
## Deliverable 1 — --log now APPENDS across restarts (was: truncate)12
```13
2026-07-01T13:50:34Z [INFO] Courier starting mode=leader relay=none telegram=not configured14
2026-07-01T13:50:34Z [INFO] MCP server ready name=courier16
--- courier restart ---17
2026-07-01T13:50:36Z [INFO] Courier starting mode=leader relay=none telegram=not configured18
2026-07-01T13:50:36Z [INFO] MCP server ready name=courier20
--- courier restart ---21
2026-07-01T13:50:38Z [INFO] Courier starting mode=leader relay=none telegram=not configured22
2026-07-01T13:50:38Z [INFO] MCP server ready name=courier23
```24
3x 'Courier starting' + 2x restart markers => full history preserved.26
## SECOND CAUSE — BEFORE (pre-fix control): backlog delivered + re-delivered27
Cold start with a 2-update backlog. Each delivered message = one inbound the28
leader would ACK = one outbound Telegram send => storm.29
```30
control RUN 1 (cold start) stdout events:31
{"type":"hello","pid":3748}32
{"type":"heartbeat"}33
{"type":"message","text":"BACKLOG-1","sender":"daviwil","sender_id":"42","chat_id":"1001"}34
{"type":"message","text":"BACKLOG-2","sender":"daviwil","sender_id":"42","chat_id":"1001"}35
{"type":"heartbeat"}36
{"type":"heartbeat"}37
{"type":"heartbeat"}38
{"type":"heartbeat"}40
control RUN 1 stderr (no offset persistence, no drain):41
2026-07-01T13:49:48Z [INFO] Telegram poller child started pid=374843
control RUN 2 (restart, backlog still pending) -> RE-DELIVERS:44
{"type":"message","text":"BACKLOG-1","sender":"daviwil","sender_id":"42","chat_id":"1001"}45
{"type":"message","text":"BACKLOG-2","sender":"daviwil","sender_id":"42","chat_id":"1001"}46
```48
## SECOND CAUSE — AFTER (fixed): drain on cold start, deliver-once, no re-delivery49
```50
RUN 1 (cold start, 2-update backlog) stdout events:51
{"type":"hello","pid":30027}52
{"type":"heartbeat"}53
{"type":"heartbeat"}54
{"type":"heartbeat"}55
{"type":"heartbeat"}56
{"type":"heartbeat"}57
{"type":"heartbeat"}58
{"type":"heartbeat"}59
RUN 1 stderr:60
2026-07-01T13:44:45Z [INFO] Cold start: drained Telegram backlog (not delivered) count=2 offset=362
RUN 2 (restart; 1 NEW update injected) -> delivers NEW once:63
{"type":"message","text":"NEW-live-msg","sender":"daviwil","sender_id":"42","chat_id":"1001"}64
2026-07-01T13:44:51Z [INFO] Restored Telegram getUpdates offset offset=366
RUN 3 (restart, no new updates) -> NO re-delivery:67
message events: 068
2026-07-01T13:44:57Z [INFO] Restored Telegram getUpdates offset offset=469
```