Effort
| Delivery boundary |
P50 |
P90 |
Substantive files |
| Group multi-ingress, per-target retry idempotency, Linked Inbox cascade, and recovery |
3,100 review lines |
5,500 review lines |
22–35 |
Delivery contract
Dependency and single goal
Strictly stack on PR 8. Add GroupMention and MemberInbox source adapters to the same UserDirectedWork dispatcher and deliver multi-target ingress, per-target retry idempotency, communication-link authority, and bounded recovery. PR 10 still owns safe default rollout of the Group projection.
State after merge
With the rollout gate enabled in internal/test environments, one Group message may mention one or more Members. Every target receives an independent user message, Turn, FIFO sequence, runtime, and outcome; network retry cannot duplicate delivery. During UserDirectedWork, a Member may use PR 2 links to send another Member one bounded side quest, and the Coordinator is always reachable. Working/Idle/Paused all accept this work. A busy target only queues in its own FIFO: no hard interruption, no clearing direct intervention, and no automatic Resume. The backend control plane is complete, but the default product gate remains closed until PR 10 removes the old N-channel Group feed.
Primary files
src-tauri/crates/agent-core/src/state/commands/session/org_tasks/group_chat.rs
src-tauri/crates/agent-core/src/core/coordination/agent_inbox/*
src-tauri/crates/agent-core/src/core/tools/impls/orchestration/agent_org/send_message*
src-tauri/crates/agent-core/src/core/tools/impls/orchestration/inbox_wake.rs
src/engines/ChatPanel/hooks/useAgentOrgGroupChatController.ts
src/api/tauri/agent/orgTasks.ts
Group ingress implementation
- The composer reads targets from structured
member://<canonical_member_id> pills, deduplicates by ID, and canonicalizes the body after removing pills. Display names never resolve authority.
- Zero Member targets or Coordinator-only mentions use the existing Root send. This version typed-rejects a mixed
@Coordinator + @Member message to avoid silently introducing another atomic protocol that creates Root plus N Member Turns in one click. deliveries contains non-Coordinator Members only.
- The frontend generates one stable and distinct
turnIntentId per target and retains immutable deliveries:[{targetMemberId,turnIntentId}]. When transport outcome is unknown, Retry reuses the exact composer snapshot. Changed body or targets generate new IDs.
- One bounded backend transaction fully preflights Team, targets, target cap, queue cap, IDs, and digest before writing. Only three outcomes exist: all-new writes all; all-existing with exact matches returns existing receipts; mixed existing/new or any binding conflict returns
idempotency_conflict with zero new rows.
- Each target separately receives source message/Inbox, PR 3 context,
source=GroupMention, dispatch Member, FIFO sequence, root authority/budget, and independent receipt. Kick each target only after commit; pending recovery handles kick failure.
- Siblings do not reference each other. There is no
group_message_id, batch row, shared progress, group-wide Stop/Retry, or hidden collaboration relationship.
Linked Inbox and scheduler implementation
org_send_message resolves real sender, Turn kind, root authority, parent, and depth from persisted CallContext/context. The model cannot supply is_user_directed, delivery class, link override, or budget.
- The UserDirectedWork branch permits one plain side-quest target. Member-to-Member send checks the frozen undirected link. The Coordinator is always reachable. Self, unknown, and removed targets are rejected.
Working/Idle/Paused all permit the write.
- PR 7
call_id receipt, root delivery/depth budget, child Inbox/context, and recipient FIFO allocation commit in one transaction. Kick is event-driven after commit.
- The formal branch remains Working-only and Task-bound.
TaskAssigned can be generated only from a committed Task/assignment outbox; it does not read peer links and cannot carry a Member-defined side quest.
- Split generic drain into exact typed claims: formal drain claims only
TaskAssigned/formal coordination; UserDirectedWork claims only the context's exact source_inbox_id. Remove group_chat.rs auto-Resume/intervention-clear and blanket drain.
- Startup-owned pending UserDirectedWork recovery uses keyset pagination, single-flight, and at most 100 rows or 50 ms per batch before yielding. Recover only an exact delivery that has never started. After start, a crash writes failed/abandoned/unknown and never automatically replays file or external side effects. Normal Idle/Paused adds no periodic scan.
Scope boundaries
A single org_send_message does not fan out. Do not allow self-send, unbounded cascades, automatic side-quest Task registration, Group-as-direct interruption, automatic Idle/Paused Resume, or model-forged authority. Multi-target submit atomicity covers initial acceptance only; after commit, targets are fully independent.
Failure scenarios that must be rejected or remain no-ops
- Duplicate, unknown, removed, ambiguous, or N+1 targets, or mixed Coordinator plus Member.
- Two targets reuse the same Turn ID.
- Exact retry after response loss creates new Inbox, sequence, or Wake.
- Mixed existing/new or same ID with different target/body is “filled in.”
- Group/peer work clears direct intervention, auto-Resumes, or hard-interrupts a busy Member.
- Blanket drain consumes
TaskAssigned.
- The model forges link, delivery class, root/parent, or budget.
- Claim after Archive, or unbounded cascade/Provider amplification.
- Pending delivery is lost on restart, or a started side quest is replayed automatically.
Acceptance and handoff
Verify concurrent duplicate/all-new/all-existing/mixed matrices; crash after commit before kick; pending-versus-started recovery; link on/off/bidirectional/Coordinator-reachable; TaskAssigned independent of links; call_id Inbox replay; N+1, queue, delivery, depth, and Provider backpressure; a 10-target burst with per-Member runtime ≤ 1; Working/Idle/Paused matrix; and ordinary SDE with zero additional context/Inbox/Wake/listener. PR 9 must freeze per-target independent context sequence, exact source_inbox_id, exact assistant reply_to, Member/source/outcome, and unified run-changed invalidation. PR 10 reads only these facts and cannot infer causality.
Suggested review commits — still one PR
A. Inbox authority and schema. B. Transactional Group ingress. C. Linked Inbox and recovery. D. Composer/RPC and focused tests. These aid review and are not four features that may merge out of order.
Plain-language contract
Dependency
PR 8.
How it works
The composer generates one stable, distinct turnIntentId for each canonical Member target. After one complete preflight, the backend accepts only three outcomes: write all-new together, return prior results for all-existing, or reject mixed state with zero new rows. After commit, kick targets independently. org_send_message derives sender/root/depth from real CallContext and writes peer Inbox according to communication links and budgets. Formal and user-directed Inbox use different exact claims. Recover only pending deliveries that never started.
State after merge
One message can mention multiple Members, and each receives its own message, Turn, FIFO, and result. Network retry does not duplicate work. In Working/Idle/Paused, a Member can use a link to ask another Member to do a side quest. A busy target queues only: no interruption, no clearing intervention, and no automatic Resume. The backend is complete, but the default Group feed still waits for PR 10.
Boundaries
Zero Member or Coordinator-only goes to Root. Mixed @Coordinator + @Member must be split into two sends. Do not create group_message_id, shared progress, or group-wide Stop/Retry. Do not self-send, cascade without bound, register a side quest as a formal Task automatically, or replay already-started side effects.
How to test
Test unknown/over-limit/mixed-target zero-write, all-new/all-existing/mixed idempotency, crash after commit before kick, pending versus started recovery, bidirectional links and Coordinator always reachable, TaskAssigned unaffected by links, call_id Inbox deduplication, N+1/backpressure, all three Team states, and zero extra ordinary-SDE branches.
Effort
Delivery contract
Dependency and single goal
Strictly stack on PR 8. Add
GroupMentionandMemberInboxsource adapters to the same UserDirectedWork dispatcher and deliver multi-target ingress, per-target retry idempotency, communication-link authority, and bounded recovery. PR 10 still owns safe default rollout of the Group projection.State after merge
With the rollout gate enabled in internal/test environments, one Group message may mention one or more Members. Every target receives an independent user message, Turn, FIFO sequence, runtime, and outcome; network retry cannot duplicate delivery. During UserDirectedWork, a Member may use PR 2 links to send another Member one bounded side quest, and the Coordinator is always reachable.
Working/Idle/Pausedall accept this work. A busy target only queues in its own FIFO: no hard interruption, no clearing direct intervention, and no automatic Resume. The backend control plane is complete, but the default product gate remains closed until PR 10 removes the old N-channel Group feed.Primary files
Group ingress implementation
member://<canonical_member_id>pills, deduplicates by ID, and canonicalizes the body after removing pills. Display names never resolve authority.@Coordinator + @Membermessage to avoid silently introducing another atomic protocol that creates Root plus N Member Turns in one click.deliveriescontains non-Coordinator Members only.turnIntentIdper target and retains immutabledeliveries:[{targetMemberId,turnIntentId}]. When transport outcome is unknown, Retry reuses the exact composer snapshot. Changed body or targets generate new IDs.idempotency_conflictwith zero new rows.source=GroupMention, dispatch Member, FIFO sequence, root authority/budget, and independent receipt. Kick each target only after commit; pending recovery handles kick failure.group_message_id, batch row, shared progress, group-wide Stop/Retry, or hidden collaboration relationship.Linked Inbox and scheduler implementation
org_send_messageresolves real sender, Turn kind, root authority, parent, and depth from persisted CallContext/context. The model cannot supplyis_user_directed, delivery class, link override, or budget.Working/Idle/Pausedall permit the write.call_idreceipt, root delivery/depth budget, child Inbox/context, and recipient FIFO allocation commit in one transaction. Kick is event-driven after commit.TaskAssignedcan be generated only from a committed Task/assignment outbox; it does not read peer links and cannot carry a Member-defined side quest.TaskAssigned/formal coordination; UserDirectedWork claims only the context's exactsource_inbox_id. Removegroup_chat.rsauto-Resume/intervention-clear and blanket drain.Scope boundaries
A single
org_send_messagedoes not fan out. Do not allow self-send, unbounded cascades, automatic side-quest Task registration, Group-as-direct interruption, automatic Idle/Paused Resume, or model-forged authority. Multi-target submit atomicity covers initial acceptance only; after commit, targets are fully independent.Failure scenarios that must be rejected or remain no-ops
TaskAssigned.Acceptance and handoff
Verify concurrent duplicate/all-new/all-existing/mixed matrices; crash after commit before kick; pending-versus-started recovery; link on/off/bidirectional/Coordinator-reachable;
TaskAssignedindependent of links;call_idInbox replay; N+1, queue, delivery, depth, and Provider backpressure; a 10-target burst with per-Member runtime ≤ 1; Working/Idle/Paused matrix; and ordinary SDE with zero additional context/Inbox/Wake/listener. PR 9 must freeze per-target independent context sequence, exactsource_inbox_id, exact assistantreply_to, Member/source/outcome, and unified run-changed invalidation. PR 10 reads only these facts and cannot infer causality.Suggested review commits — still one PR
A. Inbox authority and schema. B. Transactional Group ingress. C. Linked Inbox and recovery. D. Composer/RPC and focused tests. These aid review and are not four features that may merge out of order.
Plain-language contract
Dependency
PR 8.
How it works
The composer generates one stable, distinct
turnIntentIdfor each canonical Member target. After one complete preflight, the backend accepts only three outcomes: write all-new together, return prior results for all-existing, or reject mixed state with zero new rows. After commit, kick targets independently.org_send_messagederives sender/root/depth from real CallContext and writes peer Inbox according to communication links and budgets. Formal and user-directed Inbox use different exact claims. Recover only pending deliveries that never started.State after merge
One message can mention multiple Members, and each receives its own message, Turn, FIFO, and result. Network retry does not duplicate work. In
Working/Idle/Paused, a Member can use a link to ask another Member to do a side quest. A busy target queues only: no interruption, no clearing intervention, and no automatic Resume. The backend is complete, but the default Group feed still waits for PR 10.Boundaries
Zero Member or Coordinator-only goes to Root. Mixed
@Coordinator + @Membermust be split into two sends. Do not creategroup_message_id, shared progress, or group-wide Stop/Retry. Do not self-send, cascade without bound, register a side quest as a formal Task automatically, or replay already-started side effects.How to test
Test unknown/over-limit/mixed-target zero-write, all-new/all-existing/mixed idempotency, crash after commit before kick, pending versus started recovery, bidirectional links and Coordinator always reachable,
TaskAssignedunaffected by links,call_idInbox deduplication, N+1/backpressure, all three Team states, and zero extra ordinary-SDE branches.