Stale channel state keeps left channels in the feed #12

Closed
opened 2026-07-15 17:36:35 +00:00 by foresle · 0 comments
Owner

Channels the account left long ago still deliver new posts into the feed every day, dated the current day, so the problem is ongoing rather than a one-time backlog of old posts.

Scope:

  • Posts from channels the account is not currently subscribed to must not be ingested or appear in the feed.
  • Stale per-channel state entries accumulated in the Telegram session must stop producing updates for left channels.
  • Posts from left channels already stored in the database must be left untouched, no cleanup of stored data is part of this issue.

Notes:

  • The authoritative subscription list is the account's own set of Telegram dialogs, which ingestion already enumerates through iter_dialogs. The project keeps no channel list of its own and must not gain one, the current set of joined channels is read from Telegram at runtime.
  • Root cause is in how grammers tracks update state. On startup ingestion drains every dialog and streams updates with catch_up enabled, which seeds a per-channel state entry into session.sqlite for every channel seen in dialogs or incoming updates. grammers then periodically polls the channel difference for each stored entry and emits any new posts it finds.
  • A stored entry is dropped only when the difference request answers with a CHANNEL_PRIVATE error. A public channel never returns it, because Telegram serves public channel content to non-members, so the entry of a left public channel lives in the session forever and keeps yielding new posts.
  • grammers exposes no method that reconciles stored entries against the current dialog set on its own, so leaving a channel does not remove its entry.
  • The reconciliation must draw the allowed set from the current dialogs at runtime, dropping session entries and rejecting incoming posts whose channel is no longer among the account's dialogs. A one-time cleanup of the affected entries in session.sqlite removes the current inflow, and the runtime check against the dialog set keeps left channels from being picked up again.
Channels the account left long ago still deliver new posts into the feed every day, dated the current day, so the problem is ongoing rather than a one-time backlog of old posts. Scope: - Posts from channels the account is not currently subscribed to must not be ingested or appear in the feed. - Stale per-channel state entries accumulated in the Telegram session must stop producing updates for left channels. - Posts from left channels already stored in the database must be left untouched, no cleanup of stored data is part of this issue. Notes: - The authoritative subscription list is the account's own set of Telegram dialogs, which ingestion already enumerates through `iter_dialogs`. The project keeps no channel list of its own and must not gain one, the current set of joined channels is read from Telegram at runtime. - Root cause is in how `grammers` tracks update state. On startup ingestion drains every dialog and streams updates with `catch_up` enabled, which seeds a per-channel state entry into `session.sqlite` for every channel seen in dialogs or incoming updates. `grammers` then periodically polls the channel difference for each stored entry and emits any new posts it finds. - A stored entry is dropped only when the difference request answers with a `CHANNEL_PRIVATE` error. A public channel never returns it, because Telegram serves public channel content to non-members, so the entry of a left public channel lives in the session forever and keeps yielding new posts. - `grammers` exposes no method that reconciles stored entries against the current dialog set on its own, so leaving a channel does not remove its entry. - The reconciliation must draw the allowed set from the current dialogs at runtime, dropping session entries and rejecting incoming posts whose channel is no longer among the account's dialogs. A one-time cleanup of the affected entries in `session.sqlite` removes the current inflow, and the runtime check against the dialog set keeps left channels from being picked up again.
foresle added this to the 0.1.0 milestone 2026-07-15 17:36:35 +00:00
foresle self-assigned this 2026-07-15 17:36:35 +00:00
foresle added this to the Developing project 2026-07-15 17:36:35 +00:00
foresle canceled time tracking 2026-07-16 05:15:45 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
foresle/notgram#12
No description provided.