Baker Street

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

SubjectPublisherConsumerPatternDescription
baker.jobs.dispatchBrainWorkersQueue groupNew job dispatched for execution
baker.jobs.status.<jobId>WorkersBrainPub/SubReal-time job status updates
baker.jobs.result.<jobId>WorkersBrainPub/SubFinal 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

SubjectPublisherConsumerPatternDescription
baker.extensions.announceExtensionsBrainPub/SubExtension announces availability
baker.extensions.heartbeatExtensionsBrainPub/SubPeriodic liveness signal
baker.extensions.deregisterExtensionsBrainPub/SubExtension graceful shutdown

Task Pod Subjects

SubjectPublisherConsumerPatternDescription
baker.tasks.launchBrainK8s JobDirectLaunch a new task pod
baker.tasks.status.<taskId>Task PodBrainPub/SubTask pod status updates
baker.tasks.result.<taskId>Task PodBrainPub/SubTask pod final result

System Subjects

SubjectPublisherConsumerPatternDescription
baker.system.healthAllMonitorPub/SubService health heartbeats
baker.system.handoffBrainBrainPub/SubBlue-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');