Skip to content

feat(inbox): filter conversations by unresponded activity - #660

Open
johnmatthewtennant wants to merge 22 commits into
mainfrom
codex/inbox-unresponded-landing
Open

johnmatthewtennant wants to merge 22 commits into
mainfrom
codex/inbox-unresponded-landing

Conversation

@johnmatthewtennant

@johnmatthewtennant johnmatthewtennant commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Why

Reading a message does not mean it has been answered. Combining Mentions, Agents, and Unresponded gives users a queue of agent conversations awaiting their reply, independently of read state.

What

Replace Unread only with a Filters dropdown: All, Unread only, or Unresponded only. Unresponded follows the selected Activity type: incoming DMs, replies in participating threads, or explicit mentions. It clears earlier activity only after a verified reply from the current viewer in that conversation. Reading and other participants' replies do not clear it; fresh matching activity returns it.

Activity, Sender, and Filters selections are remembered locally for each account and community, including after leaving Inbox or reloading.

The Mentions filter also fixes a preview/unread bug: matching mention evidence supplies the row's preview, sender, ordering, and unread state. Ordinary follow-up progress remains in All activity and Threads. DM recipient tags count as direct activity, not mentions.

This also fixes cold-start false positives: an older mention could appear unanswered until opening its thread loaded a later reply. Before admitting Unresponded rows, the existing Inbox feed checks later conversation history and relevant edits/deletions. Unchecked rows stay hidden with a loading or retry state. Candidates sharing a root use one history check, and Activity/Sender exclusions do not demand response reads. UUID threads use the existing signed canonical thread window, including nested replies that tag only an intermediate parent. Cold ancestry is resolved through bounded exact reads; fetched parent messages stay withheld until their edits and deletions settle. The check uses the shared verified evidence owner, without polling or a separate message store. Both overlay stages batch at most 500 exact IDs per request while preserving aggregate event/byte limits and pagination. Newly discovered history messages are marked incomplete before admission, so switching to All or Unread cannot expose an unchecked original body. Held or failed overlays retain the preview/detail placeholder until both stages settle.

Verified conversations appear newest first as their history and overlays finish. Older checks continue in the same background operation, and a later failure keeps earlier verified rows usable. Aggregate overlay event/byte limits still span the whole operation.

Reviewer-reproducible examples

From this checkout, run the isolated production-UI journeys:

bin/pnpm install --frozen-lockfile
bin/pnpm exec playwright install chromium
bin/pnpm test:browser tests/browser/inbox-unresponded.spec.mjs --project chromium --no-deps --workers 1

The fixtures create an unanswered thread and DM, so no live account or relay data is required. Reading leaves them in Unresponded; submitting through the real DM/thread composers removes answered activity, and a fresh incoming message restores it. After answering a mention, ordinary thread progress appears under Threads and All activity while Mentions stays empty. A DM's recipient tag never creates a Mentions row.

The cold-start fixture has 15 mentions in one thread and a later viewer reply tagging only an intermediate parent, displaced from the initial sample by 500 newer unrelated messages. While reply history is held, Unresponded shows loading and no candidate rows. After release, the answered mentions disappear without opening detail. One signed canonical window supplies the nested reply and certifies exhaustion for this fixture.

The incremental fixture holds an older conversation after a newer one finishes verification. The newer row appears and its detail opens while Checking recent activity remains visible. Before this change, no row appeared until the older read completed. Re-selecting Unresponded after completion reuses checked history without new conversation reads.

For the agent-attention queue, select Mentions, Agents, and Unresponded only. Reading a matching mention leaves it in the queue; replying in that conversation clears the earlier mention, and a new mention brings it back. Leave Inbox and reopen it, then reload: the three filter choices remain selected.

Coverage

Five browser cases added, none removed. They cover production app composition and real composers, signed publication/echo, cold history through the broker, incremental row usability across a held older read, and navigation/reload persistence. No browser assertions were moved or deleted. The 12 Activity/Sender combinations remain in mounted Inbox tests; chronology, same-second ancestry, deleted replies, failure/retry, budgets, and cancellation stay with their existing evidence owners.

The matching-Mentions regression fails on main because ordinary unread progress replaces the matching mention projection. Cold-response regressions fail before the fix because the later own reply is missing, including a nested reply with only a parent tag.

Risks and remaining work

Response detection is deterministic within bounded verified history, not semantic answer detection. Distinct conversations are checked serially; newest verified results appear while older checks continue, but a large cold inbox can still take longer to settle. Canonical threads are read to signed exhaustion within the existing cap of 2,000 events and 4 MiB; resolving a missing root is limited to 32 exact ancestor reads. Exhausting that budget or failing a read shows Retry inbox rather than treating missing evidence as unanswered. Production relay latency and large multi-conversation performance have not been measured.

Human testing of incremental result loading remains deferred.

Screenshots

Filters dropdown:

Filters dropdown

Unresponded across All activity:

Unresponded across All activity

Checking later reply history before admitting rows:

Unresponded loading while reply history is checked

Answered mentions excluded without opening detail:

Answered mentions excluded after the history check

Newest verified conversation available while older history loads:

Newest verified Unresponded row while older history loads

Signed-off-by: John Tennant <jtennant@block.xyz>
Signed-off-by: John Tennant <jtennant@block.xyz>
@johnmatthewtennant
johnmatthewtennant marked this pull request as ready for review October 6, 2026 18:43
Luna added 2 commits October 6, 2026 15:14
Signed-off-by: Luna <0828be588d5c9c4d092c5b1cf01761d5aef63d6b104807fd8e8284d517dd1a99@buzz.block.builderlab.xyz>
Signed-off-by: Luna <0828be588d5c9c4d092c5b1cf01761d5aef63d6b104807fd8e8284d517dd1a99@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 changes requested. The response filter, mention-specific projection, and per-account/community persistence are consistent with the stated bounded-history contract in the reviewed source.

Star Lord automated source review via Wes’s account — head ee43214bb0860a2fa340c734be845b885f5f9963, base 97155e7cbd1f97ecedfab5ec8f36310f6caf2e89. Tests and app workflows were not run; the single CI snapshot still had browser shards running, so this is not runtime, native, or merge acceptance.

@johnmatthewtennant
johnmatthewtennant marked this pull request as draft October 7, 2026 02:51
Signed-off-by: John Tennant <jtennant@block.xyz>
Signed-off-by: John Tennant <jtennant@block.xyz>
Signed-off-by: John Tennant <jtennant@block.xyz>
Signed-off-by: John Tennant <jtennant@block.xyz>
Signed-off-by: John Tennant <jtennant@block.xyz>
Signed-off-by: John Tennant <jtennant@block.xyz>
Signed-off-by: John Tennant <jtennant@block.xyz>
Signed-off-by: John Tennant <jtennant@block.xyz>
@johnmatthewtennant
johnmatthewtennant marked this pull request as ready for review October 7, 2026 10:59

@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.

Two changes recommended in the new cold-history path; details inline.

Star Lord automated source review via Wes’s account — head 606d8a00c9d0221474f5a90e9af2bfdb9d6c4c2e, base 97155e7cbd1f97ecedfab5ec8f36310f6caf2e89. Source-only: no tests or app workflows executed. The hosted snapshot shows CI required and DCO passing; runtime/native and human acceptance remain unverified.

Comment thread src/features/relay/inbox-feed.ts Outdated
Comment thread src/features/relay/inbox-feed.ts Outdated
@johnmatthewtennant
johnmatthewtennant marked this pull request as draft October 7, 2026 11:19
Signed-off-by: John Tennant <jtennant@block.xyz>
Signed-off-by: John Tennant <jtennant@block.xyz>
Signed-off-by: John Tennant <jtennant@block.xyz>
Signed-off-by: John Tennant <jtennant@block.xyz>
Signed-off-by: John Tennant <jtennant@block.xyz>
Signed-off-by: John Tennant <jtennant@block.xyz>
@johnmatthewtennant
johnmatthewtennant marked this pull request as ready for review October 7, 2026 12:14
Signed-off-by: John Tennant <jtennant@block.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. Both previous findings are addressed: overlay targets are batched below the shared reader’s request limit, and cold history/ancestry is marked incomplete before admission and withheld until both overlay stages settle.

Star Lord automated source review via Wes’s account — head a31864f109b6f0a7993e92e2300d00aab71cc005, base 97155e7cbd1f97ecedfab5ec8f36310f6caf2e89. Source-only: tests/app workflows were not run; the hosted snapshot shows CI required and DCO passing, but native and human acceptance remain unverified.

Signed-off-by: John Tennant <jtennant@block.xyz>
Signed-off-by: John Tennant <jtennant@block.xyz>
Signed-off-by: John Tennant <jtennant@block.xyz>
@johnmatthewtennant
johnmatthewtennant marked this pull request as draft October 7, 2026 12:38
@johnmatthewtennant
johnmatthewtennant marked this pull request as ready for review October 7, 2026 15:05
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