Repository source: docs/concepts/caught_up_mark.md
Caught-up mark
Purpose: Let a member see what is new since they last caught up, on every device, without visiting a page ever counting as reading it.
Scenario: With FORUM_INBOX_ENABLED on, a member opens Inbox. Unread conversations come first, then Replies (posts whose parent any key of their username wrote), then New posts. Each of Replies and New posts lists its oldest 50 unread posts. Caught up acknowledges exactly the listed posts and moves that section's mark to the newest of them; the next 50 appear. The Inbox link outlines when unread conversations plus unread replies are above zero; new posts never light it.
Boundary: One mark per username and section, shared by every key and device of that username, in private state/private/inbox.sqlite3. A mark starts at the moment it is first read, so earlier posts are history. Marks only move forward and only on Caught up; opening Inbox or reading the count changes nothing. A mark also keeps the IDs it acknowledged in its last 10 minutes, because signed posts may arrive up to 10 minutes after their own timestamp; a late post inside that window stays unread unless it was shown. Marks hold post IDs and times, so a read-model rebuild leaves them valid. Instance imports can add older posts below a mark; those count as history. Deleting the file resets marks to the next visit and loses no content. Messages keep their own per-conversation read state.
Sources: marks (source unavailable), sections (source unavailable), page and count (source unavailable), page (source unavailable), count script (source unavailable), tests (source unavailable), page tests (source unavailable), count check (source unavailable).
Related: recent conversation, navigation slots, viewer session, private message history.