Count unread replies only in conversations you are part of - #471
Conversation
79a6e31 to
3c652a0
Compare
A reply is unread only when it answers the viewer's message, or the viewer also replied to the same parent. Nested threads under someone else's reply stay quiet until the viewer posts there. Mentions, DMs and broadcasts still count. When retained evidence cannot decide membership, look it up once per parent from the relay instead of guessing. Signed-off-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
The unread fixture now makes the viewer author the first thread root. The links journey holds the viewer's profile until its linked message is focused, so a viewer-authored root started that hold at startup and could outlive the profile read deadline on slow runners. Keep that journey's roots peer-authored. Signed-off-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
Address the PR review of the out-of-window conversation lookup: - keep fetched parents and roots in a separate bounded store that never counts, never fills the window and survives its overflow reset; - split a full aggregate page, and page one busy parent back in time; - decide thread attention from the direct parent and fetch the root for grouping and navigation; - hold live notifications while the lookup is pending; - scope membership to the reply's channel, honor deletions, never ask a parent twice at once, and retry failures with backoff. Signed-off-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
Address the re-review of the out-of-window conversation lookup: - a lookup in flight during a cache clear or access change discards its answer and re-asks only the parents the reset kept; an aborted read from the reset is not counted as a relay failure; - report `pending` only while a lookup is queued or running, so a read reply cannot hold a notification candidate that nothing will settle; - key lookups by channel and parent, so a reply in another channel that tags the same parent cannot block or share the answer; - record which of the viewer's messages made a lookup positive, and end the membership when the viewer deletes all of them after the lookup. Signed-off-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
3c652a0 to
d999933
Compare
wesbillman
left a comment
There was a problem hiding this comment.
One change requested: lookup-backed membership can survive deletion of the viewer’s old reply on another client, leaving unrelated replies marked unread and notification-eligible (inline).
Star Lord automated source review via Wes’s account. Head d999933e9d665a8a4960a6137e06ed5d83c4c005, base e5a70460a9a3423464e7ee97dede8ccecfd69f10. Source-only: no tests, builds or app execution. Hosted CI required passed in one snapshot; Windows validation was skipped, and native/UI retry-focus behavior remains unverified.
A positive lookup kept only the IDs of the viewer's messages that made it positive. When the window did not hold such a message, a deletion from another client could not resolve its target through the session's visibility check, so it never reached unread and the membership survived. Keep those verified messages in a bounded store (4,096, not counted evidence, dropped on access loss) and expose them to the existing deletion-visibility lookup. Evicting one forgets the lookups it backs, so they are asked again instead of outliving an unobservable deletion. The regression test no longer loads the old reply before deleting it. Signed-off-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
wesbillman
left a comment
There was a problem hiding this comment.
One change requested: witness eviction can miss in-progress lookup results and leave completed memberships without deletion evidence (inline). The ordinary cross-client deletion path from the previous review is addressed.
Star Lord automated source review via Wes’s account. Head 019849036068ef14a9612b4d479c66258c101c69, base e5a70460a9a3423464e7ee97dede8ccecfd69f10. Source-only follow-up: no tests, builds or app execution; CI was still running in one snapshot, Windows validation was skipped, and native/UI retry-focus behavior remains unverified.
…e bound A lookup batch witnessed every reply of the viewer before it installed the batch's results. Eviction only scanned installed lookups, so a batch that returned more than 4,096 of the viewer's replies could evict the witnesses of its own pending decisions. Those memberships were then installed without deletion-visible evidence, and a deletion from another client could not end them. Each lookup now keeps one witness, the viewer's newest message for that parent, and records whether the viewer has others. The lookup is remembered before it is witnessed, so eviction always sees it. Deleting the witness ends the membership, or asks the relay again when the viewer has other messages there. Witnesses can no longer exceed the lookup bound. Signed-off-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
wesbillman
left a comment
There was a problem hiding this comment.
One change requested: choosing a newer reply as the sole witness can hide deletion of a cached viewer-authored parent, which is then reused to restore membership (inline). The previous in-progress eviction finding is addressed.
Star Lord automated source review via Wes’s account. Head 6943099676790a7fcd20480ed4af6f9f517a4381, base e5a70460a9a3423464e7ee97dede8ccecfd69f10. Source-only follow-up: no tests, builds or app execution; CI was still running in one snapshot, Windows validation was skipped, and native/UI retry-focus behavior remains unverified.
… visible When the viewer wrote both a parent and a newer reply to it, the lookup witnessed only the reply. The parent stayed in the structural cache but was not deletion-visible, so another client's deletion of it was dropped. After the reply was deleted too, the follow-up lookup reused the cached parent and restored the membership. Prefer the viewer's own parent as the witness, keep the first witness instead of replacing it with a later message, and drop a deleted message from the lookup cache so a follow-up lookup fetches it again. Signed-off-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
…ures The session-level regression signed more than 5,000 events. That took about 8 seconds locally and pushed the JavaScript CI lane past its 10-minute timeout. It also queued parents one per poll, so it did not build the single multi-parent batch it described. Move it to a direct unread fixture. Events are marked verified rather than signed, as the transport does after verification, and all ten parents are asked in one turn. One ID fetch proves the shared batch. The test fails on 0198490, where the membership survives, and runs in about 100 ms. Signed-off-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
wesbillman
left a comment
There was a problem hiding this comment.
No changes requested in this test-only follow-up: the replacement queues all ten parents together, exercises the real deletion-visibility gate, and preserves signed session-level deletion coverage.
Star Lord automated source review via Wes’s account; head 9cd80cde90a74907c4f2d76fe9a3144dc4430386, base e5a70460a9a3423464e7ee97dede8ccecfd69f10.
Source-only: no tests, builds or app execution; prior CI confirms the 10-minute timeout and 18.4-second removed case, but current CI was still running at the snapshot and the replacement’s runtime/full-suite improvement remain unverified.
Two session-level lookup tests each signed 4,096 flood events to overflow the evidence window. They took about 14 seconds each on CI and made unread-startup.test.ts the slowest file in the JavaScript lane, which is now timing out at its 10-minute limit. Move them next to the witness-bound test in a shared direct-unread fixture (unread-lookups.test.ts). The fixture marks events verified, as the transport does after verification. The assertions are unchanged. Disabling the live-reply witness still fails the moved test. Signed-off-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
wesbillman
left a comment
There was a problem hiding this comment.
No changes requested in this test-only follow-up: the moved cases retain the overflow/refresh and no-repeat-lookup assertions, exercise the real unread owner, and leave signed-session deletion, access and failure/retry coverage in place.
Star Lord automated source review via Wes’s account; head 3f90ee873a41c9cbeb55187c35a18afe967bfd0c, base e5a70460a9a3423464e7ee97dede8ccecfd69f10.
Source-only: no tests, builds or app execution; prior hosted logs confirm the two cases took 14.35 s and 13.95 s and that JavaScript exceeded its 10-minute limit, but current CI was still running at the snapshot, so the new runtime/full-suite improvement remains unverified.
…page-icon * origin/main: Count unread replies only in conversations you are part of (block#471) Animate the terminal welcome with a compact hex wordmark (block#508) Use top tabs in the new-tab picker (block#505) Polish media controls, panel headers, and menus (block#496) harden pinned browser CI setup and native fixture provenance (block#494) perf(relay): confirm membership hints with exact channel reads (block#486) test(browser): wait for menu and wheel completion (block#492) fix(links): render one hash on completed channel links (block#506) ci: publish Windows and Linux alongside macOS previews (block#491) fix(channels): keep conversations open through archive and restore (block#452) feat(channels): align create and edit forms with draft protection (block#482) Test provider connections before model selection (block#500) Signed-off-by: Matthew Boston <mboston@squareup.com>
…delegate * origin/main: Fix Pi and Goose environment overrides (#517) feat(ui): Switch shared icons to Tabler (#523) Improve message media contrast and thumbnail fill (#521) Document unified inventory and verify focused import and compact-row acceptance (#293) fix(ux): clarify Pi installation and setup errors (#511) Count unread replies only in conversations you are part of (#471) Animate the terminal welcome with a compact hex wordmark (#508) Use top tabs in the new-tab picker (#505) Signed-off-by: bb-expert <51cde9442e46eac81c83ec71552708c3b0cb96a88ff8e1581d8fb4de281afbf3@buzz.block.builderlab.xyz> # Conflicts: # src/features/relay/unread.test.ts
* origin/main: (21 commits) Add remote agent owner attestation fn to host service (#532) fix(build): pin Rust 1.98.1 to unblock macOS 27 agent builds (#529) main fix: Pi model test ETXTBSY flake (#513) fix(composer): remove phantom text-field focus outlines (#519) fix(relay): use writer reads for channel confirmations (#501) feat(channels): unify header actions and inline details editing (#487) Show app-managed agents working in the sidebar (#539) Add recoverable hosted community deletion (#403) Add verified Inbox evidence and exact edit closure (#495) Animate Buzz startup through initial content readiness (#534) Polish profile avatar picker and custom colors (#533) Add Send to channel for authored thread replies (#531) Allow plugins to send managed-agent registration events (kind 30177) (#535) Fix Pi and Goose environment overrides (#517) feat(ui): Switch shared icons to Tabler (#523) Improve message media contrast and thumbnail fill (#521) Document unified inventory and verify focused import and compact-row acceptance (#293) fix(ux): clarify Pi installation and setup errors (#511) Count unread replies only in conversations you are part of (#471) Animate the terminal welcome with a compact hex wordmark (#508) ... Signed-off-by: Sol <49aa1f65411fd096d2e2ec144f1e7aa36fdc76d1b907cfdf7be000c66f9d3b8e@buzz.block.builderlab.xyz>
🤖
Summary
Example
You post a message. An agent replies to you: unread. Someone starts a nested thread under the agent's reply: quiet. You reply in that nested thread: new replies there are now unread.
Details
threadnotification category. The per-thread-root "participants" set is replaced by two sets built in the same indexing pass: messages you wrote, and messages you replied to. Checking a reply is two lookups by ID; there is no tree walk.docs/unread.mdanddocs/notifications.mddescribe the new rule.