Skip to content

idea: board topic/subscription primitive for receiver-initiated announcements — inspired by MetaGPT's shared message pool #847

Description

@github-actions

Research brief

Landscape survey (2026-07-25), scoped to: "agent_mesh roadmap & comparable OSS
agent frameworks" (OpenHands, SWE-agent, Aider, MetaGPT/ChatDev, Renovate,
claude-code-action).

Landscape signal — MetaGPT's shared message pool. MetaGPT's agents don't
address each other directly for most coordination: each role "publishes
structured messages in a shared pool," and any other role can "subscribe to
relevant messages based on their own profiles" — an agent's next action fires
once its declared prerequisite messages have appeared in the pool, without
the publisher needing to know in advance who (or how many) will consume it.
Source (fetched, verified): https://arxiv.org/html/2308.00352v6 (MetaGPT
paper, full text — "shared message pool" / subscription mechanism sections).

Gap (confirmed against this repo, not just landscape-inspired)

agent_mesh has exactly two communication shapes today, and both require the
sender to already know every recipient:

  1. delegate_to_peer (src/a2a/peer-bridge.js) — synchronous, ask-only,
    point-to-point: caller names one specific peer per call.
  2. The task board create_task_for_peer (src/board/*) — durable and
    async, but still directed: from/to are a single named pair, framework
    stamped.
  3. fanOutToPeers (the orchestrator's parallel-dispatch helper, closed
    idea: multi-peer fan-out / scatter-gather — concurrent delegate_to_peer to N peers + synthesis (v2 unlock) #185 "multi-peer fan-out / scatter-gather") is the closest existing
    analog to "one caller reaching several peers" — but it is still
    caller-directed: the orchestrator enumerates the N peers itself,
    synchronously, for one conductor workflow run. It is not a durable
    artifact a peer can publish once and have an a priori unknown set of
    interested peers discover later, asynchronously, on their own polling
    cadence.

There is no primitive for "peer A publishes that something happened (a PRD
landed, an MIR regenerated, a spec moved to approved) once, and any peer
that has separately declared interest in that topic picks it up on its own
next poll" — without A needing to enumerate or even know who those peers
are. Every existing coordination path in this repo is 1:1 or a
caller-enumerated fan-out, never receiver-initiated subscription.

Proposed direction

Extend the existing board store (<mesh-root>/mesh/board/) — already a
framework-owned, ask-safe write surface, per src/board/store.js — with a
second, parallel primitive rather than modifying task semantics:

  • publish_board_topic({ topic, brief }) on the agentmesh_peerbridge
    bridge: framework-stamps from/id/timestamp exactly like
    create_task_for_peer does today (never trusts caller-supplied identity
    fields — same anti-spoof pattern), and appends a small durable record
    under a new <mesh-root>/mesh/board/topics/<topic>/ directory. No to
    field — publish is topic-addressed, not peer-addressed.
  • Each peer self-declares subscriptions in its own mesh.json/
    agent.json (x-agentmesh.subscribedTopics: [...]) — operator-owned, so
    a publisher can never force delivery to a peer that hasn't opted in, and a
    compromised publisher can't expand its own read/write reach (matches the
    existing webTools/writeTools self-declared-manifest pattern from idea: per-peer write-tool allowlist narrowing for do-mode — inspired by Claude Code's parameterized subagent permission rules #845
    and the webTools design).
  • A new read verb list_topic_updates() lets a subscribed peer poll for
    topic records newer than its own last-seen cursor — same polling shape the
    board-notify hook already uses for list_my_tasks, so this fits the
    existing async, agent-driven pickup model rather than inventing a push
    mechanism.
  • Purely additive: peers that declare no subscriptions see no behavior
    change; publishing writes only the framework-owned board store, never a
    peer's folder, so it stays ask-safe like task assignment.

Invariants preserved

  • Task-board identity is framework-set: from/id/timestamps on a
    published topic record come from the authentic caller identity, never tool
    args — same rule already governing create_task_for_peer.
  • Single writable root: publish only ever writes the shared board store,
    never a peer's own folder.
  • Anti-spoof: subscription lists are declared once, out-of-band, in each
    peer's own manifest — never negotiated via tool-call args, so a topic
    publisher cannot expand who receives it.

Scope hint

src/board/store.js (new topics/ namespace alongside tasks/),
src/a2a/peer-bridge.js (publish_board_topic/list_topic_updates verbs),
manifest schema addition for subscribedTopics, pure unit tests for the new
store/read-cursor logic (no spawn/hook changes).

Sources

Metadata

Metadata

Assignees

No one assigned

    Labels

    blockedBlocked on a dependencygenerated:analystAnalyst agent–generated improvement idea (analyst-daily-review)needs-humanspec:draftSpec being drafted

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions