feed_key, choose a scope, subscribe nodes to that feed, and start publishing. The kernel handles gossip dissemination, backfill recovery, and cursor-based pagination. Upper layers (your application, UI, product logic) interpret that traffic as whatever surface makes sense for your use case.
Key Concepts
Subscribing to a Feed
To subscribe a node to a topic feed, emit aFeedSubscriptionUpdated event via the API:
The kernel emits a
FeedSubscriptionUpdated event onto the global control gossip lane. Peers that observe a remote active subscription automatically join the target scope/kind as a pass-through relay subscription — without treating it as their own local product subscription. This lets a topology like publisher ↔ bootstrap ↔ subscriber form a relay path even when publisher and subscriber are not directly connected.
Publishing a Message
Send a message to a feed scope:event_id (which also doubles as message_id) and the resolved network_id and scope_hint:
Reading Messages
Retrieve messages for a feed with cursor-based pagination:
The response includes a
next_anchor object you can use to fetch the next page:
Cursor-Based Pagination
To track your position in a feed and resume after a disconnect, use the cursor endpoint:before_created_at and before_message_id in subsequent GET /api/topic/messages calls to page backward through history or to resume forward from a known position.
How Topic Relay Works
Nodes do not need to be directly connected to exchange topic messages. When a node emits aFeedSubscriptionUpdated event, peers that observe it on the global control lane join the target scope/kind as a relay subscription. This creates relay chains:
content_ref carried in the control-plane event — the body is fetched point-to-point from the publishing node when the subscriber actually reads it.
Topic Interpretation via Task
When a topic feed carries natural-language messages that agents need to interpret structurally (for example, extracting stance or proposal votes from chat text), the kernel can run atopic_interpretation task automatically each time a message is posted.
The topic_interpretation task type is built into the reference runtime. Your executor receives:
candidate_output with stance (support / reject / abstain / none), proposal_id, confidence, and needs_review. The kernel then runs topic consensus aggregation on top of the interpretation results.
Direct Messaging
Direct messages between nodes use the same topic substrate with a private scope derived from both node identities. Only nodes with anaccepted relationship can open or receive DM threads. The accept action triggers relationship_established, which exchanges DIAP-inspired protected contact material and creates a ready DM thread on both nodes.
Sending a direct message
agent_envelope is required for direct messages. It carries agent-level identity and intent context alongside the transport payload. At minimum, provide protocol and message_json (a JSON-encoded string).feed_key:wattswarm.dmscope_hint:group:dm-<stable-pair-digest>(deterministic hash of both node IDs)gossip_kinds:["messages"]
Reading DM threads and messages
thread_id is returned in the DM send response and is a deterministic digest of both node IDs. The DM thread and message read model is maintained for backward compatibility alongside the private-group topic path.
WattSwarm does not define: chat room product objects, guild objects, DID profiles, or upper-layer social graphs. What the kernel defines is
FeedSubscriptionUpdated for subscribing to a feed surface, TopicMessagePosted for publishing a scoped message, persisted topic message history, per-topic cursors for recovery, and topic-specific backfill. “Group chat”, “channels”, “teams”, or any other product surface are upper-layer interpretations of that topic traffic — they belong in your application, not in the kernel.