Skip to content

prunedUnread reports 0 for a reader that has never read, so a late-created loop is told it lost nothing #300

Description

@scgopi

Found by the #295 review, non-blocking there, and left out of #299 rather than smuggled in with a test change.

The defect

Mailbox.prunedUnread counts posts that landed after a reader's cursor and were pruned before it asked — so a reader is told what it missed instead of missing it silently. That was the point of adding it in #295.

But for a reader whose lastMailroomRead is nil — one that has never read — it reports 0. With no cursor there is no lower bound to count from, so a loop created during a busy stretch and reading for the first time is told it lost nothing, when posts it would have been shown were in fact pruned.

Reproduction (the review's probe, which fails on main):

aReaderThatNeverReadIsStillToldWhatItLost
  Expectation failed: (answer.prunedUnread → 0) == 60

This is the same silent-loss shape the whole #288 series has been closing — the reader gets a well-formed answer that quietly understates what happened.

Why it is not a one-line fix

The obvious remedy is to stamp the cursor at node creation: give every new loop lastMailroomRead = the room's current latest id. Then prunedUnread has a lower bound and reports honestly.

But that also changes what a new loop sees. Today a loop with a nil cursor treats the whole room as unread, which is deliberate — a loop born after a busy week reads the backlog. Stamping the cursor at creation means a new loop starts with an empty inbox and never sees anything posted before it existed.

Both behaviours are defensible; they are different products. Pick one on purpose:

  • Stamp at creation — new loops start clean, prunedUnread is honest everywhere, and the backlog becomes something a loop asks for explicitly (mail list).
  • Keep nil meaning "everything is unread" — and give prunedUnread a different lower bound for that case, e.g. the oldest id the room still holds, so it can say "posts were pruned before you got here" without pretending to know how many.

The second keeps today's behaviour and still stops the silent understatement, so it is probably the smaller change — but it reports a bound rather than a count, and the field's name would need to stop promising an exact number.

Test

aReaderThatNeverReadIsStillToldWhatItLost is on branch review/295-audit and can be lifted straight in once the behaviour is decided.

Related: #288, #295, #299

🤖 Generated with Claude Code

https://claude.ai/code/session_01BP43ags4cn8fq2ZZdv85J9

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions