NATS Subjects
NATS JetStream subject hierarchy and message patterns used for inter-service communication.
NATS Subjects
All communication between Baker Street components flows through NATS JetStream. This page documents the subject hierarchy, message patterns, and delivery guarantees.
Subject Hierarchy
Baker Street uses a structured naming convention for NATS subjects:
baker.<domain>.<action>
Job Subjects
| Subject | Publisher | Consumer | Pattern | Description |
|---|---|---|---|---|
baker.jobs.dispatch | Brain | Workers | Queue group | New job dispatched for execution |
baker.jobs.status.<jobId> | Workers | Brain | Pub/Sub | Real-time job status updates |
baker.jobs.result.<jobId> | Workers | Brain | Pub/Sub | Final job result |
Jobs are published to baker.jobs.dispatch and consumed by a shared queue group (workers). NATS automatically load-balances across available workers. If a worker crashes mid-job, the message acknowledgment times out and NATS redelivers to another worker.
Extension Subjects
| Subject | Publisher | Consumer | Pattern | Description |
|---|---|---|---|---|
baker.extensions.announce | Extensions | Brain | Pub/Sub | Extension announces availability |
baker.extensions.heartbeat | Extensions | Brain | Pub/Sub | Periodic liveness signal |
baker.extensions.deregister | Extensions | Brain | Pub/Sub | Extension graceful shutdown |
Task Pod Subjects
| Subject | Publisher | Consumer | Pattern | Description |
|---|---|---|---|---|
baker.tasks.launch | Brain | K8s Job | Direct | Launch a new task pod |
baker.tasks.status.<taskId> | Task Pod | Brain | Pub/Sub | Task pod status updates |
baker.tasks.result.<taskId> | Task Pod | Brain | Pub/Sub | Task pod final result |
System Subjects
| Subject | Publisher | Consumer | Pattern | Description |
|---|---|---|---|---|
baker.system.health | All | Monitor | Pub/Sub | Service health heartbeats |
baker.system.handoff | Brain | Brain | Pub/Sub | Blue-green deployment handoff |
Message Patterns
Queue Groups (Load Balancing)
Worker jobs use NATS queue groups. All workers subscribe to baker.jobs.dispatch with the group name workers. NATS delivers each message to exactly one worker in the group, providing automatic load balancing.
// Worker subscribes to the job queue
const sub = nc.subscribe('baker.jobs.dispatch', {
queue: 'workers',
});
for await (const msg of sub) {
const job = JSON.parse(msg.data);
await processJob(job);
msg.ack();
}
Pub/Sub (Broadcast)
Status updates use standard pub/sub. The Brain subscribes to job-specific subjects to receive updates:
// Brain listens for status updates on a specific job
const sub = nc.subscribe(`baker.jobs.status.${jobId}`);
for await (const msg of sub) {
const status = JSON.parse(msg.data);
// Update job status in the database
// Push update to the client via SSE
}
JetStream Configuration
Baker Street configures JetStream with durable consumers for reliable delivery:
// Stream configuration
{
name: 'BAKER_JOBS',
subjects: ['baker.jobs.>'],
retention: 'workqueue',
maxAge: 86400000000000, // 24 hours in nanoseconds
storage: 'file',
replicas: 1,
maxMsgs: 10000,
}
Key guarantees:
- At-least-once delivery -- messages are redelivered if not acknowledged within the timeout
- Durable consumers -- consumer state survives pod restarts
- Work queue retention -- messages are removed after acknowledgment
- 24-hour retention -- unprocessed messages expire after 24 hours
Trace Context Propagation
NATS messages carry OpenTelemetry trace context in message headers. This allows a single user request to be traced across Brain -> NATS -> Worker -> Tool Execution as a single distributed trace.
// Headers include W3C trace context
msg.headers.set('traceparent', '00-abc123-def456-01');