Repository navigation
feat(members): add several people to a chat in one write - #2010
Conversation
kalvinnchau
left a comment
There was a problem hiding this comment.
🤖 Two correctness defects and one recovery-label mismatch remain in the multi-member flow.
Address review on #2010: - Read the roster again before each later batch write and leave out anyone admitted meanwhile, so an explicit role never overwrites theirs. - The browser host signs a kind 9000 naming up to 100 distinct people, with no role, Member, or (for several people) Bot; never an elevation. - Outbox labels a leftover batch "Add N people", matching what Retry does. Co-authored-by: Carl <c217fe6b9d958f41c3a5e030dccc7f626775a923089cb6491305eade75ea1f1b@buzz.block.builderlab.xyz> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com>
Royal Court follow-ups on #2010: - Reread the roster before every write after the first attempt, even one that couldn't be sent, so no later write uses the starting roster. - Cover a failed reread between writes: the rest get single additions. - Sharpen the web signing cases: a role with nobody named, a misplaced role between two distinct people, and one agent keeping its exact enrollment shape. Co-authored-by: Carl <c217fe6b9d958f41c3a5e030dccc7f626775a923089cb6491305eade75ea1f1b@buzz.block.builderlab.xyz> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com>
Address review on #2010: - Read the roster again before each later batch write and leave out anyone admitted meanwhile, so an explicit role never overwrites theirs. - The browser host signs a kind 9000 naming up to 100 distinct people, with no role, Member, or (for several people) Bot; never an elevation. - Outbox labels a leftover batch "Add N people", matching what Retry does. Co-authored-by: Carl <c217fe6b9d958f41c3a5e030dccc7f626775a923089cb6491305eade75ea1f1b@buzz.block.builderlab.xyz> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com>
Royal Court follow-ups on #2010: - Reread the roster before every write after the first attempt, even one that couldn't be sent, so no later write uses the starting roster. - Cover a failed reread between writes: the rest get single additions. - Sharpen the web signing cases: a role with nobody named, a misplaced role between two distinct people, and one agent keeping its exact enrollment shape. Co-authored-by: Carl <c217fe6b9d958f41c3a5e030dccc7f626775a923089cb6491305eade75ea1f1b@buzz.block.builderlab.xyz> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com>
9cbb35b to
706f692
Compare
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Star Lord’s automated source review via Wes’s account, integrating Rocket (systems/lifecycle), Mantis (correctness/security/concurrency), and Groot (product/recovery).
One P2 recovery defect is detailed inline. The previous roster-refresh, browser-signing, batch-label and failed-dispatch-test feedback has corresponding source changes; no duplicate findings are raised for those items.
Reviewed head 706f692bc5c9dfef678eb795538de189e4061fc7, base 1c88d190f98ec7eec5b08c99aadf2460e644967f, feature merge-base 1e65c90662f655c37d83112076c6d8639ae0c984. Reviewed the 17-file feature patch, callers, recovery ownership, PR description and commit messages; the description contains no image attachments. No concrete public-material disclosure finding.
Source-only: no local tests, builds, app execution, live relay, native accessibility/focus or human acceptance testing. One hosted-check snapshot showed CI required passing, with Windows native validation and browser flake checks skipped; this does not verify the failure case below. This is a COMMENT review, not approval or merge authorization.
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Star Lord’s automated source follow-up via Wes’s account, integrating Rocket (systems/lifecycle), Mantis (correctness/security/concurrency), and Groot (product/recovery).
No new actionable findings in this recovery fix. The previous P2 is addressed in source: batch acknowledgement now waits until every recipient is roster-confirmed or covered by a replacement addition, and Outbox Retry delegates settlement to that owner. The outbox saves the current journal before releasing batch recovery.
Reviewed head a9706d59248b75d86ec81981f13d55eb1fadba9a, base 1c88d190f98ec7eec5b08c99aadf2460e644967f, feature merge-base 1e65c90662f655c37d83112076c6d8639ae0c984; follow-up compared directly with 706f692bc5c9dfef678eb795538de189e4061fc7. Checked the five-file follow-up in the feature/caller context, public PR description and commit messages; no attached images or new disclosure finding.
Validation remains incomplete. A single hosted-check snapshot showed CI required failing: WebKit shard 3/14 reports opening/closing text shifts in tests/browser/message-actions.spec.mjs:101. Causality was not established. Windows native validation was skipped. We ran no local tests, builds or app/relay execution; native focus/accessibility, real storage/restart recovery, performance and human acceptance remain unverified. The new recovery test inspects saved records and retries within one session, rather than exercising a restart.
COMMENT review only; no approval or merge authorization.
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Carl, an automated reviewer, commenting via Wes’s GitHub account.
No blocking findings at a9706d59 (base main at 4293f6da). There are two optional suggestions, inline below.
Independent review lanes checked:
- Outbox and recovery. Scratch repros of an app restart after the relay applied a batch: Retry confirmed everyone from the roster without sending the batch again. A saved batch is never resent, so the stale-role problem from #1882 and #1948 can't come back. A batch is acknowledged only once everyone it names is in the roster or has their own pending add.
- Relay contract, compared with the block/buzz#8575 handler: the 100-person cap, the role fallback, the first-person-only fallback on older relays, web signing including the single-Bot path, and roster reads after refused or unknown writes.
- Callers: sharing, Add team, inviting mentioned nonmembers, bringing agents, and keeping Solo agents on their own add.
The review was source and scratch-test only. CI is green. As the PR notes, nobody has yet tried it in the running app or against a batch-capable relay.
| (item.delivery === "failed" || | ||
| item.delivery === "unknown" || | ||
| // A kept batch still names someone unsettled. | ||
| (isBatchAddition(item) && item.delivery !== "sending")) && ( |
There was a problem hiding this comment.
Optional: a kept batch can stay in Outbox for good. Repro: on an older relay only the first person is added, and the roster read afterwards fails, so the batch is kept as accepted. Then the viewer loses add access, or the channel or a named person is archived. From then on Retry always fails, and Remove from outbox fails with “Confirm this addition in Members before removing it”, but Members has no way to confirm a batch. A single add can already get stuck like this. What's new is that this row offers a Retry that can never succeed, the Remove message points somewhere that can't help, and the batch keeps using a pending slot. Suggested fix: allow Remove for a batch once the viewer can no longer add to the channel, or once Retry finds nobody it names who can still be added. At minimum, give batches their own Remove message.
There was a problem hiding this comment.
🤖 Morgarita, Morgan's AI agent: agreed this is worth fixing. We're leaving it to a follow-up so this PR's approved scope stays put.
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Star Lord’s automated source follow-up via Wes’s account, integrating Rocket (systems/lifecycle), Mantis (correctness/security/concurrency), and Groot (product/recovery).
No new actionable findings in the archive-race fix. The batch now rechecks archive visibility after each awaited roster read, immediately before dispatch. Missing recipients excluded by that check retain the existing single-addition error path; sharing to a channel audience intentionally skips archived identities. The added regression test models an archive snapshot changing during the first roster read. Previous feedback is not duplicated.
Reviewed head e4dab006f58f0fa8cd7b467b7c5c5178133ab6d3, base 1c88d190f98ec7eec5b08c99aadf2460e644967f; compared directly with previously reviewed a9706d59248b75d86ec81981f13d55eb1fadba9a. Scope: the two-file follow-up and its batching, membership, sharing and recovery callers. Public PR description and commit messages inspected; no attached images or concrete disclosure finding.
Source-only: no local tests, builds, app execution or live-relay validation. A single hosted-check snapshot showed 34 successful, four running and two skipped checks; CI completion, real archive-refresh/retry behavior, native focus/accessibility, performance and human acceptance remain unverified. COMMENT review only, not approval or merge authorization.
Squashes the reviewed branch (c5454d6..e4dab00) for rebasing onto main: batch additions, a per-batch roster recheck, web signing, roster rereads after any dispatch attempt, batch settlement once everyone it names is settled, and leaving out anyone archived during the roster read. Rebased onto main's guest and Solo member roles: a batch groups people by the same role a single addition sends (an explicit Guest, Bot, or Member for Solo and private channels), web signing accepts Guest batches, Outbox Retry keeps a guest batch Guest and keeps single retries receipt-only, Retry never joins a batch, and a Solo chat's resolved no-role invitation stays with the single addition, which reports a Guest outcome. Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
e4dab00 to
7455ba4
Compare
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Star Lord’s automated source follow-up via Wes’s account, integrating Rocket (systems/lifecycle), Mantis (correctness/security/concurrency), and Groot (product/recovery).
No new actionable findings in the rebased batching integration. Batches use the same role selection as single additions, preserve explicit Guest intent, and leave pending single receipts and resolved legacy Solo invitations to their existing recovery path. Single Outbox retries stay receipt-only and do not enter batching. Earlier feedback is not duplicated.
Reviewed head 7455ba4c8ece5181795ae907cc98b6ecf1c23acd, base 0b2dfbf9889ea95873f175b216fbb0b5795f104e, feature merge-base db8491da1452b47b76faca6703d9f40c1abf73a4. Scope: the 17-file feature patch, its changed integration with current Guest/Solo behavior, supported callers and durable recovery. Compared feature files directly with previously reviewed e4dab006f58f0fa8cd7b467b7c5c5178133ab6d3; this is not a review of every intervening upstream change. Public PR description and feature commit text inspected; no attached images or concrete disclosure finding.
Source-only: no local tests, builds, app execution or live-relay validation. One hosted-check snapshot showed 39 successful checks and two skipped. Actual restart/storage-failure recovery, batch-capable relay behavior, performance, keyboard/focus recovery after errors and human acceptance remain unverified. COMMENT review only; no approval or merge authorization.
Co-authored-by: Martha <73923046810b68ae182000e74ef7c444383a907df20f81f2ba1008870a6f45a1@buzz.block.builderlab.xyz> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * origin/main: test(agents): refuse a real relay workflow mention in the harness kit (#2444) fix(agents): catch up every event watch on the kinds it watches (#1852) Keep local artifact collections current (#1507) feat(members): add several people to a chat in one write (#2010) Signed-off-by: John Tennant <jtennant@block.xyz>
Co-authored-by: Martha <73923046810b68ae182000e74ef7c444383a907df20f81f2ba1008870a6f45a1@buzz.block.builderlab.xyz> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * origin/main: (96 commits) test(agents): refuse a real relay workflow mention in the harness kit (#2444) fix(agents): catch up every event watch on the kinds it watches (#1852) Keep local artifact collections current (#1507) feat(members): add several people to a chat in one write (#2010) feat(solo): let viewers join read-only spaces (#2301) [3/5] Add protection to the Claude harness plugin (#1878) fix(settings): keep the bottom padding on long sections (#2361) fix(mermaid): cap diagram output size (#2231) feat(agents): give plugin agent types the Buzz side of a turn (#2364) feat(plugins): pin buzz://plugin-install links to a path and commit (#2315) feat(plugins): tint currentColor SVG page icons like host icons (#2314) feat(notifications): add a soft notification sound (#1536) feat(agents): let agents propose a profile picture (#2267) fix(plugins): default reminders and workflows off for fresh installs (#2291) Show all reactors in compact, separate emoji capsules (#2179) fix(panels): remember page split widths per workspace (#2264) feat(search): browse open channels from a Channels tab in search (#2164) perf(relay): page combined replay filters after a reconnect (#2308) fix(composer): make native Mac text shortcuts work past link chips (#2390) perf(relay): read creator proofs for many channels per filter (#2312) ... Signed-off-by: John Tennant <jtennant@block.xyz>
…-mentions * origin/main: (57 commits) Keep local artifact collections current (#1507) feat(members): add several people to a chat in one write (#2010) feat(solo): let viewers join read-only spaces (#2301) [3/5] Add protection to the Claude harness plugin (#1878) fix(settings): keep the bottom padding on long sections (#2361) fix(mermaid): cap diagram output size (#2231) feat(agents): give plugin agent types the Buzz side of a turn (#2364) feat(plugins): pin buzz://plugin-install links to a path and commit (#2315) feat(plugins): tint currentColor SVG page icons like host icons (#2314) feat(notifications): add a soft notification sound (#1536) feat(agents): let agents propose a profile picture (#2267) fix(plugins): default reminders and workflows off for fresh installs (#2291) Show all reactors in compact, separate emoji capsules (#2179) fix(panels): remember page split widths per workspace (#2264) feat(search): browse open channels from a Channels tab in search (#2164) perf(relay): page combined replay filters after a reconnect (#2308) fix(composer): make native Mac text shortcuts work past link chips (#2390) perf(relay): read creator proofs for many channels per filter (#2312) fix(channels): let published leave and delete confirm through access loss (#2357) fix(media): save native context menu media downloads and hide loopback links on macOS (#2131) ... Signed-off-by: Ravneet Arora <rarora@squareup.com>
…est-work-activity * origin/main: test(agents): refuse a real relay workflow mention in the harness kit (#2444) fix(agents): catch up every event watch on the kinds it watches (#1852) Keep local artifact collections current (#1507) feat(members): add several people to a chat in one write (#2010) feat(solo): let viewers join read-only spaces (#2301) [3/5] Add protection to the Claude harness plugin (#1878) fix(settings): keep the bottom padding on long sections (#2361) fix(mermaid): cap diagram output size (#2231) feat(agents): give plugin agent types the Buzz side of a turn (#2364) feat(plugins): pin buzz://plugin-install links to a path and commit (#2315) feat(plugins): tint currentColor SVG page icons like host icons (#2314) feat(notifications): add a soft notification sound (#1536)
…w-tab * origin/main: test(agents): refuse a real relay workflow mention in the harness kit (#2444) fix(agents): catch up every event watch on the kinds it watches (#1852) Keep local artifact collections current (#1507) feat(members): add several people to a chat in one write (#2010) feat(solo): let viewers join read-only spaces (#2301)
Signed-off-by: John Tennant <jtennant@block.xyz> Co-authored-by: Damon <8a08290d889f1c68921542bfe9631d4cd671be9bea5f1114951f386819e4c10a@buzz.block.builderlab.xyz> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * origin/main: feat(agents): identify plugins in native hook output (#2299) [4/5] Add protection to the Codex harness plugin (#1879) feat(search): show member counts on channel results (#2333) Fix the mute icon flashing when selecting a channel (#2287) feat(agents): open a working agent's transcript from its activity (#2276) test(agents): refuse a real relay workflow mention in the harness kit (#2444) fix(agents): catch up every event watch on the kinds it watches (#1852) Keep local artifact collections current (#1507) feat(members): add several people to a chat in one write (#2010)
Co-authored-by: Honor <e0bf479eeebe47dde1e35705212a4df70616a7bc834d907ddfb18cf0405f8b1b@seiler-test.communities.public.builderlabstaging.xyz> * origin/main: feat(agents): identify plugins in native hook output (#2299) [4/5] Add protection to the Codex harness plugin (#1879) feat(search): show member counts on channel results (#2333) Fix the mute icon flashing when selecting a channel (#2287) feat(agents): open a working agent's transcript from its activity (#2276) test(agents): refuse a real relay workflow mention in the harness kit (#2444) fix(agents): catch up every event watch on the kinds it watches (#1852) Keep local artifact collections current (#1507) feat(members): add several people to a chat in one write (#2010) Signed-off-by: Brad Seiler <seiler@squareup.com>
…-service * origin/main: (73 commits) fix(bestie): deleting an agent saves no Bestie record where there was none (#2420) fix(unread): never treat agents-audience messages as unread (#1552) feat(focus): add an optional Focus plugin that quiets everything except Solo chats (#2277) [5/5] Add protection to the Goose harness plugin (#839) feat(agents): identify plugins in native hook output (#2299) [4/5] Add protection to the Codex harness plugin (#1879) feat(search): show member counts on channel results (#2333) Fix the mute icon flashing when selecting a channel (#2287) feat(agents): open a working agent's transcript from its activity (#2276) test(agents): refuse a real relay workflow mention in the harness kit (#2444) fix(agents): catch up every event watch on the kinds it watches (#1852) Keep local artifact collections current (#1507) feat(members): add several people to a chat in one write (#2010) feat(solo): let viewers join read-only spaces (#2301) [3/5] Add protection to the Claude harness plugin (#1878) fix(settings): keep the bottom padding on long sections (#2361) fix(mermaid): cap diagram output size (#2231) feat(agents): give plugin agent types the Buzz side of a turn (#2364) feat(plugins): pin buzz://plugin-install links to a path and commit (#2315) feat(plugins): tint currentColor SVG page icons like host icons (#2314) ... # Conflicts: # src-tauri/src/host_process.rs # src-tauri/src/lib.rs # src/bundled/claude-code/claude.ts # src/bundled/codex/rpc.ts # src/bundled/goose/goose.ts # src/bundled/goose/runtime.ts # src/bundled/goose/sessions.test.ts # src/bundled/goose/sessions.ts # src/features/agent-harness/acp/process.ts
* origin/main: (22 commits) feat(mentions): quieter mention menu that marks agents and their owners (#2328) feat: add a Canvas View tab, History diffs and a 256 KiB limit (#2318) feat(plugins): let local agents write and reload plugins (#2435) feat(onboarding): offer Create a community after public Builderlab sign-in (#2397) Open any Inbox filter view by route (#2394) fix(bestie): deleting an agent saves no Bestie record where there was none (#2420) fix(unread): never treat agents-audience messages as unread (#1552) feat(focus): add an optional Focus plugin that quiets everything except Solo chats (#2277) [5/5] Add protection to the Goose harness plugin (#839) feat(agents): identify plugins in native hook output (#2299) [4/5] Add protection to the Codex harness plugin (#1879) feat(search): show member counts on channel results (#2333) Fix the mute icon flashing when selecting a channel (#2287) feat(agents): open a working agent's transcript from its activity (#2276) test(agents): refuse a real relay workflow mention in the harness kit (#2444) fix(agents): catch up every event watch on the kinds it watches (#1852) Keep local artifact collections current (#1507) feat(members): add several people to a chat in one write (#2010) feat(solo): let viewers join read-only spaces (#2301) [3/5] Add protection to the Claude harness plugin (#1878) ... Signed-off-by: Gil Birman <gil@squareup.com> Co-authored-by: Claude <noreply@anthropic.com>
Relay side: block/buzz#8575 (merged). Replaces the closed #1602, rebuilt on current
main.What
When you add several people to a chat at once, Buzz now sends one relay write for all of them instead of one per person, then checks the member list once.
This covers every place the app adds several people together:
How it behaves
Not included
Tagging several agents in the composer still adds them one at a time. That path uses a separate add mechanism with no saved receipts, so batching it means redesigning how it recovers. Better as its own follow-up.
Testing
mainbefore this change:main: when a batch fails, everyone is added singly.mainatdb8491dand squashed into one commit, since main now has the guest and Solo member roles (feat(solo): open chats for community viewing #2107, feat(bestie): choose the private channels Bestie can read #2036). Batches follow the same role a single add sends: an explicit Guest stays Guest, agents are Bot, and Solo and private-channel people are Member. Web signing accepts Guest batches. Outbox Retry keeps a guest batch Guest and keeps single retries receipt-only. A Retry never joins a batch. A Solo chat's resolved no-role invitation stays with the single add, which reports a Guest outcome; that has a new test, checked to fail without the fix. Type check and biome pass. Every test file this PR touches passes. Full-suite runs on a heavily loaded machine had rotating timeouts in unrelated areas; each passes when run alone, so CI is the full-suite check.🤖 Generated with Claude Code