Skip to main content
goldengoose is built around observable communication. Threads don’t just “talk” — they exchange messages in a way that stays attached to work, can be tracked, and is visible to humans. All of the concurrency-sensitive parts live in the native Rust runtime: team state, message queueing, per-recipient delivery records, and the event stream that drives the UI. The frontend can stay honest and simple (render state, don’t infer it), while the runtime does the heavy lifting — which is why delivery tracking stays reliable even when multiple threads are streaming tokens and tool output at once.

Two communication layers

1) The thread timeline (what happened in a session)

  • Every thread has a timeline that shows the conversation, tool calls, approvals, and results.
  • This is your source of truth for “what did the agent do?” and “what output did it see?”

2) Team Comms (what happened across the team)

  • Teams add a shared communications surface where messages can be broadcast to everyone or targeted to specific members.
  • Team Comms is ideal for coordination: task assignment, status updates, and “FYI” announcements.

Direct message vs broadcast

  • Direct messages are best for delegating a concrete task to one member (“Please update the keyboard shortcuts page and ping me when done.”).
  • Broadcasts are best for shared context and alignment (“We’re targeting a release today; prioritize failing tests.”).
In both cases, messages are delivered into the recipient’s thread so the agent can act on them with full context. Agents can send images to each other too. When a team message includes image attachments, gg injects those images into the recipient’s thread using that provider’s normal image-input support, so the receiving agent sees them the same way it would see a native multimodal input.

Delivery tracking (what the statuses mean)

Every team message has per-recipient delivery records so you can see what’s happening, not just hope it went through. Common delivery states you may see:
  • Pending: queued to deliver.
  • Deferred: waiting for the right moment to inject (for example, if the recipient is busy).
  • Injecting: actively delivering into the recipient thread.
  • Injected: delivered successfully (the recipient now has the message in its context).
  • Failed: delivery couldn’t complete; you can retry or re-send.
  • Cancelled: intentionally stopped (for example, a message was recalled).

Compaction notices (when a member “forgets”)

Long-running threads eventually hit context limits. When the provider compacts a team member’s chat to make room, gg treats that as something the coordinator should know about — not as an error, but as a signal. If you’re subscribed (typically whoever added the member — often the lead), gg injects a short notice into your timeline when that member completes a compaction. It’s intentionally lightweight and non-blocking, but it saves time: you don’t have to guess why a member suddenly stopped remembering an early constraint — you get a heads-up and can re-send the two or three facts that matter. If you’re adding members via gg_team_manage(add), you can opt out per member with unsubscribe_from_compaction_notifications. Compaction fallback targeting now distinguishes runtime branches:
  • no_hooks: default recipients are creator/subscribers only (the compacted member is excluded by default).
  • executed: configured hook output/overrides drive recipients and message text.
  • resolution_failed and execution_failed: runtime falls back to the canonical baseline contract instead of collapsing to no_hooks.

Desktop notifications (keep signal high)

gg can send desktop notifications when a thread finishes a turn, but teams can get noisy fast — so notifications are configurable:
  • All: notify for every thread
  • None: never notify
  • Leads only: notify for team leads, then opt-in additional agents as needed
The “leads only” mode is built for real multi-agent work: you get the important completions by default, and you can selectively enable or disable notifications for specific non-lead agents from the thread’s sidebar context menu. You can configure this in Preferences under Notifications.

Practical patterns that work well

  • Let the lead be the “router”: ask the lead to delegate, then follow up in Team Comms.
  • Keep messages small and actionable: include the goal, constraints, and where to report back.
  • When something changes, broadcast it once: “I updated the lead rules; please re-read them.”