Skip to content

Let the channel "caught up" mark replace ordinary message read marks - #590

Merged
wesbillman merged 5 commits into
mainfrom
larry/timeline-covers-message-marks
Oct 6, 2026
Merged

wesbillman merged 5 commits into
mainfrom
larry/timeline-covers-message-marks

Conversation

@loganj

@loganj loganj commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

🤖

Summary

  • When you scroll to the bottom of a channel and stay there, the app already saves one "caught up to here" mark for that channel. Until now it also kept a separate read mark for each ordinary message under it. Those extra marks used storage space in your synced read state for no gain in this app.
  • Now the "caught up" mark replaces the per-message marks of ordinary top-level messages. The app drops existing ones when it saves, and it does not write new ones for messages the mark already covers.
  • Unread counts in this app do not change.

Compatibility

  • The old desktop app and the mobile app do not understand the "caught up" mark. For messages you read in this app, they can now show ordinary top-level messages as unread. This was accepted. It never works the other way: a read in desktop or mobile stays read here.

What keeps its own mark

  • Mentions, broadcasts, thread replies and DM messages. The "caught up" mark does not prove you saw them, so it does not replace their marks.
  • A message in a channel that the app has not listed yet, because the app cannot yet tell if it is a DM.

Details

  • The rule lives in the existing coverage check that already drops message marks under a full channel read mark (unread.ts). It uses the same "ordinary top-level message" test that unread uses, so the two cannot disagree.
  • No new relay reads. This replaces the approach in Fold read message marks into channel marks with a background sweep #577, which needed an extra background read.

@wesbillman wesbillman left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One change needed: retain DM message-read marks while channel metadata is unknown (inline).

Star Lord’s automated source review via Wes’s account. Reviewed head 8c6062a90bf879345d8246fcc14a47d296930e10 against base 4d5e757265dc80ac1ccaa18f7a252fbeb872bbe4; source-only, with no local tests or app execution. The hosted CI snapshot showed the required check passing; Windows native validation was skipped.

Comment thread src/features/relay/unread.ts Resolved

@wesbillman wesbillman left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No further changes requested: the known-type guard addresses the prior DM-metadata finding in both pruning and skip-write paths, with a delayed-metadata regression covering both.

Star Lord’s automated source follow-up via Wes’s account; head 4417702754371f5ec99c8f0cdc295763ca3a5577, base 4d5e757265dc80ac1ccaa18f7a252fbeb872bbe4. Source-only: no tests/app execution or runtime/focus validation. Hosted CI snapshot remains unresolved: Rust and tool integration failed, 12 browser jobs running, Windows native validation skipped.

loganj added a commit to block/buzz that referenced this pull request Oct 5, 2026
🤖

## Summary
The web and desktop app (`buzz-app`) saves a "caught up" mark when you
scroll to the bottom of a channel and stay there, and another one for a
thread. Mobile did not understand these marks. It relied on the separate
per-message read marks that `buzz-app` also kept. `buzz-app` is about to
stop keeping those per-message marks under the "caught up" mark
(block/buzz-app#590), to save space in the synced read state.

With this change, mobile reads the "caught up" marks with the same rules
as `buzz-app`:
- `activity:<channel>` reads ordinary top-level messages up to its time.
It does not read thread replies, mentions, broadcasts or DM messages,
because reaching the bottom of the channel does not prove you saw those.
- `thread-activity:<root>` reads the replies in that thread up to its
time.

So a message you read in `buzz-app` stays read on mobile: in the app
badge, the channel list unread state, the "new messages" divider when
you open a channel, and the Mark read / Mark unread action.

Mobile does not write these marks. It only reads them.

### Related issue
None found. Companion to block/buzz-app#590. The old desktop app in this
repo is intentionally not changed.

### Testing
- New badge tests: `activity:` clears an ordinary top-level message, and
does not clear a mention, a thread reply or a DM. `thread-activity:`
clears replies in its own thread only. The two "clears" tests fail
without this change.
- New tests for the per-message read check and the "ordinary message"
rule.
- `flutter analyze`, `dart format` check and the full mobile test suite
pass locally.
- Not yet exercised on a device.

---------

Signed-off-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
Co-authored-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
Larry added 4 commits October 6, 2026 17:15
The activity:<channel> mark already reads every ordinary top-level
message up to its time. Message marks under it only served older
desktop and mobile clients, which ignore activity:. Drop them in the
existing coverage prune, and skip writing them when catch-up already
covers the message. Mentions, broadcasts, replies and DM messages keep
their marks.

Signed-off-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
Signed-off-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
A roster can list a channel before its metadata says it is a DM. While
the type is unknown, a DM message looked ordinary, so pruning dropped its
mark and reading skipped writing one; when the DM metadata arrived, the
message became unread. Catch-up now covers a message only once the
channel's type is known and not DM.

Signed-off-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
Main now reads a whole DM on catch-up (#616), so a DM never gets an
activity: mark. Update the DM case and the coverage note to match.

Signed-off-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
@loganj
loganj force-pushed the larry/timeline-covers-message-marks branch from 4417702 to 2c4cb00 Compare October 6, 2026 21:17

@wesbillman wesbillman left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No further changes requested. The updated DM regression matches the rebased whole-DM read contract, and the prior unknown-type guard remains intact in both pruning and skip-write paths.

Star Lord’s automated source follow-up via Wes’s account — head 2c4cb00676d8acb2882b751aec1af7ea4c55bb0c, base f4bfee4705fa57a892942684075d73fe8c538645.

Source-only: no tests or app workflows run; the hosted snapshot still had JavaScript, Rust/tool integration and all 12 browser journey shards running, with Windows native validation skipped, so CI completion and native/live-relay/error-retry focus behavior remain unverified.

A dwell at the live bottom now writes a catch-up mark that covers the
visible top-level messages, so no message mark was left for pressure to
move into the reserve. Read one visible row through a reading lease
instead, the same way the test reads the pressure channel.

Signed-off-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>

@wesbillman wesbillman left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No further changes requested. The reserve regression now creates an uncovered message receipt without bottom catch-up removing its precondition; pressure, wire-omission and reload assertions remain intact, as does the prior DM-metadata fix.

Star Lord’s automated source follow-up via Wes’s account — head 3b289407bd30d43b63167f672212f23d48105c8c, base f4bfee4705fa57a892942684075d73fe8c538645.

Source-only: no tests or app workflows run; the hosted snapshot had six browser journey shards still running and Windows native validation skipped, so completed CI and native/live-relay behavior remain unverified.

@wesbillman
wesbillman merged commit c75d054 into main Oct 6, 2026
22 checks passed
@wesbillman
wesbillman deleted the larry/timeline-covers-message-marks branch October 6, 2026 23:05
abipalli pushed a commit to abipalli/buzz that referenced this pull request Oct 7, 2026
🤖

## Summary
The web and desktop app (`buzz-app`) saves a "caught up" mark when you
scroll to the bottom of a channel and stay there, and another one for a
thread. Mobile did not understand these marks. It relied on the separate
per-message read marks that `buzz-app` also kept. `buzz-app` is about to
stop keeping those per-message marks under the "caught up" mark
(block/buzz-app#590), to save space in the synced read state.

With this change, mobile reads the "caught up" marks with the same rules
as `buzz-app`:
- `activity:<channel>` reads ordinary top-level messages up to its time.
It does not read thread replies, mentions, broadcasts or DM messages,
because reaching the bottom of the channel does not prove you saw those.
- `thread-activity:<root>` reads the replies in that thread up to its
time.

So a message you read in `buzz-app` stays read on mobile: in the app
badge, the channel list unread state, the "new messages" divider when
you open a channel, and the Mark read / Mark unread action.

Mobile does not write these marks. It only reads them.

### Related issue
None found. Companion to block/buzz-app#590. The old desktop app in this
repo is intentionally not changed.

### Testing
- New badge tests: `activity:` clears an ordinary top-level message, and
does not clear a mention, a thread reply or a DM. `thread-activity:`
clears replies in its own thread only. The two "clears" tests fail
without this change.
- New tests for the per-message read check and the "ordinary message"
rule.
- `flutter analyze`, `dart format` check and the full mobile test suite
pass locally.
- Not yet exercised on a device.

---------

Signed-off-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
Co-authored-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
johnmatthewtennant pushed a commit that referenced this pull request Oct 7, 2026
…iles

* origin/main:
  Install the bundled Buzz CLI skill on desktop startup (#667)
  refactor: share status, DM and sidebar intent policy across hosts (#683)
  fix(sessions): show enabled page in navigation (#648)
  fix(composer): replace exact emoji shortcodes on closing colon (#584)
  refactor(mentions): let the Mentions plugin own what the chooser offers (#669)
  Refresh agent cards and move saved teams to Agents (#656)
  Let the channel "caught up" mark replace ordinary message read marks (#590)
  test(rust): create test executables without an open write descriptor (#665)
  feat: add mobile pairing Settings plugin (#595)
  Cache the floating action bar's MediaQueryList (#652)
  feat(messages): copy and paste mentions, channel refs and links (#579)
  Remember desktop window size and position across launches (#655)
  fix(messages): show verified workflow ownership separately from signer (#663)
  fix(activity): collapse duplicate channel-wide agent indicators (#664)
  docs: make native development the acceptance path (#666)
  Sign plugin releases with NIP-PS (#465)
  test(browser): explain WebKit fetch refusals during a page reload (#650)
  Add Claude Code harness setup in Settings (#654)
  fix: restore workflow controls, run feedback and workflow message authors (#661)

Signed-off-by: Luna <0828be588d5c9c4d092c5b1cf01761d5aef63d6b104807fd8e8284d517dd1a99@buzz.block.builderlab.xyz>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants