Implementation Plan: Messaging Substrate

Unified reliability layer for cross-context messaging: NATS JetStream with outbox/inbox patterns, canonical event envelopes, per-context streams, deduplication, DLQ handling, and external integration transports.

Consolidation Note: This plan merges P006 (Integration Gateway) and the previous P017 (Messaging Infrastructure) per ADR-032, which defines outbox/inbox + JetStream as a unified reliability pattern.

Provenance & Traceability

Architectural Decisions (ADRs)

ADR ID Decision Title Impact on This Plan
ADR-032 NATS JetStream Messaging Architecture Establishes outbox/inbox + subject versioning, per-context streams, delivery semantics.
ADR-033 Kernel-Shell Architecture Integration is a shell concern: translate protocols → publish/consume events.
ADR-011 Internal Federated Ledger (IFL) All externally significant events should be attestable and traceable.

Product Requirements (PRDs)

PRD ID Requirement Title Satisfied By (SDS) Acceptance Criteria
PRD-022 Reliable Cross-Context Messaging Platform SDS-047 REQ-050..REQ-056 (outbox/inbox, dedupe, streams)
PRD-003 Internal Federated Ledger + Identity Tokens SDS-050 Provenance + identity anchoring for emitted artifacts

Software Design Specifications (SDS)

SDS ID Service/Component Bounded Context SEA-DSL Spec File Implementation Status
SDS-047 Messaging Infrastructure Service shared N/A Draft
SDS-030 Semantic Observability Envelope shared N/A Draft

Provenance Chain

graph TD
  ADR32[ADR-032: JetStream + Outbox/Inbox] --> PRD22[PRD-022: Cross-Context Messaging]
  ADR11[ADR-011: IFL] --> PRD3[PRD-003: IFL + Identity Tokens]
  PRD22 --> SDS47[SDS-047: Messaging Infrastructure]
  PRD3 --> SDS30[SDS-030: Observability Envelope]
  SDS47 --> Impl[Implementation]
  SDS30 --> Impl

Architecture and Design

Design Principles Applied

High-Level Architecture

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
┌─────────────────────────────────────────────────────────────────────────┐
│                        Messaging Substrate                               │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  ┌──────────────────────────────────────────────────────────────────┐   │
│  │                    Internal Messaging Layer                       │   │
│  │  ┌─────────────┐        ┌─────────────┐        ┌─────────────┐   │   │
│  │  │   Outbox    │───────▶│  JetStream  │◀───────│    Inbox    │   │   │
│  │  │  Publisher  │        │   Streams   │        │   Consumer  │   │   │
│  │  └──────┬──────┘        └──────┬──────┘        └──────┬──────┘   │   │
│  │         │                      │                      │          │   │
│  │         ▼                      ▼                      ▼          │   │
│  │  ┌───────────────────────────────────────────────────────────┐   │   │
│  │  │                 PostgreSQL (per-context DB)                │   │   │
│  │  │         outbox_events  │  inbox_messages                   │   │   │
│  │  └───────────────────────────────────────────────────────────┘   │   │
│  └──────────────────────────────────────────────────────────────────┘   │
│                                                                          │
│  ┌──────────────────────────────────────────────────────────────────┐   │
│  │                    Integration Layer (Shell)                      │   │
│  │  ┌─────────────────┐                    ┌─────────────────────┐   │   │
│  │  │ Outbound Edge   │                    │  Inbound Edge       │   │   │
│  │  │ (JetStream →    │                    │  (Partner Signal →  │   │   │
│  │  │  Webhooks/A2A)  │                    │   Kernel Command)   │   │   │
│  │  └─────────────────┘                    └─────────────────────┘   │   │
│  └──────────────────────────────────────────────────────────────────┘   │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘

Dependency Justification

NATS JetStream

Dependency Type Version NPM/PyPI Package Justification ADR/SDS Reference
NATS Client Node/Python Library 2.x nats (Node); nats-py (Python) Publish/subscribe to JetStream streams. ADR-032, SDS-047
NATS Server Docker Service 2.10.x nats:2.10-alpine (Docker) JetStream-enabled message broker. ADR-032

Outbox/Inbox Pattern

Dependency Type Version NPM/PyPI Package Justification ADR/SDS Reference
ts-event-bus Node Library 4.x ts-event-bus Transactional outbox pattern implementation. PRD-022, SDS-047
uuid Node/Python Library 10.x uuid (Node); uuid (Python) Generate idempotency keys for message deduplication. SDS-047

Rust Worker (sea-mq-worker)

Dependency Type Version Crate Justification ADR/SDS Reference
async-nats Rust Library 0.34.x async-nats JetStream client for Rust worker. SDS-047
sqlx Rust Library 0.8.x sqlx Compile-time checked PostgreSQL queries. SDS-047
tokio Rust Library 1.x tokio Async runtime. SDS-047
reqwest Rust Library 0.12.x reqwest HTTP client for calling FastAPI handlers. SDS-047

Installation Commands

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Node.js dependencies
pnpm add nats ts-event-bus uuid

# Python dependencies
pip install nats-py uuid

# Docker (add to infra/docker-compose.yml)
# nats:
#   image: nats:2.10-alpine
#   command: ["--jetstream", "--store_dir=/data"]
#   ports: ["4222:4222"]

# Rust dependencies (in Cargo.toml)
# async-nats = "0.34"
# sqlx = { version = "0.8", features = ["postgres", "runtime-tokio"] }
# tokio = { version = "1", features = ["full"] }
# reqwest = { version = "0.12", features = ["json"] }

Integration Surface (Conceptual)

Outbound (Internal → External):

Inbound (External → Internal):

Expected Filetree

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/
├── schemas/events/
│   ├── envelope-v1.schema.json          # Canonical event envelope
│   └── messaging/                        # Outbox/inbox schemas
│       ├── outbox-event.schema.json
│       └── inbox-message.schema.json
├── docs/specs/shared/
│   ├── adr/032-nats-jetstream-messaging.md
│   └── sds/047-messaging-infrastructure.md
├── libs/shared/messaging/               # Messaging library (TS)
│   └── src/gen/**                       # Generated adapters/publishers
└── apps/sea-mq-worker/                  # Rust worker
    └── src/
        ├── outbox_publisher.rs
        ├── inbox_consumer.rs
        └── main.rs

Proposed Cycles

Cycle Branch Wave Files Modified Files Created Specs Implemented
C1A cycle/p017-c1a-outbox-inbox-schemas 1 docs/specs/shared/sds/047-messaging-infrastructure.md schemas/events/messaging/* Outbox/inbox entities, event envelopes
C1B cycle/p017-c1b-streams-subjects 1 docs/specs/shared/adr/032-nats-jetstream-messaging.md Per-context streams + subject versioning
C2A cycle/p017-c2a-outbox-publisher 2 apps/sea-mq-worker/src/outbox_publisher.rs Outbound publishing with dedupe
C2B cycle/p017-c2b-inbox-consumer 2 apps/sea-mq-worker/src/inbox_consumer.rs Inbound processing with dedupe
C3A cycle/p017-c3a-dlq-handling 3 docs/specs/shared/sds/047-messaging-infrastructure.md Poison handling + DLQ routing
C3B cycle/p017-c3b-envelope-validation 3 schemas/events/envelope-v1.schema.json schemas/events/integration/* Canonical envelope for external transports
C4A cycle/p017-c4a-inbound-adapters 4 docs/specs/shared/sds/030-semantic-observability.md generated **/src/gen/** Partner signal normalization + correlation

Task Breakdown

Wave 1: Core Schemas & Conventions (Parallel)

Wave 2: Core Workers (Depends on Wave 1)

Wave 3: Error Handling & Envelope (Depends on Wave 2)

Wave 4: Integration Adapters (Depends on Wave 3)


Validation & Verification

Spec Validation

Implementation Validation

System Invariants Enforced

INV-ID Invariant Enforcement
INV-020 At-least-once delivery JetStream redelivery
INV-021 Exactly-once processing Inbox PK constraint
INV-022 State and event atomically written Same DB transaction
INV-023 Events versioned immutably Subject naming

Open Questions (Resolved)

# Question Resolution
1 Which contexts should have streams in MVP? sea, vibespro, governance
2 What is the dedupe window for JetStream? 2 minutes, configured in jetstream.conf
3 Which transport(s) are in MVP? JetStream only (webhooks/A2A post-MVP)
4 Where is the canonical list of external event contracts? schemas/events/<ctx>/ + versioned JSON
5 Which events are external-facing vs internal-only? x-sea-visibility annotation in envelope
6 “Replay from offset” workflow? Deferred (post-MVP)

Risks & Mitigation

Risk Likelihood Impact Mitigation Strategy
Incorrect subject versioning causes contract drift Medium High Enforce naming rules + schema-lint checks for subjects.
Inbox table grows unbounded Medium Medium Add retention policies + archiving strategy.
Event contract drift across transports Medium High Single envelope schema + versioned subjects + contract tests.
Leaking sensitive provenance externally Medium High Use SDS-030 payload modes and sensitivity rules; strip/aggregate by default.

Rollback Strategy

  1. Partial: Disable external transport adapters while keeping internal broker publishing intact.
  2. Full: Disable inbound consumers (keep outbox publishing) while fixing inbox/dedupe issues.

Linked Specifications

Type ID/Doc Document
ADR ADR-032 docs/specs/shared/adr/032-nats-jetstream-messaging.md
ADR ADR-033 docs/specs/shared/adr/033-kernel-shell-architecture.md
ADR ADR-011 docs/specs/shared/adr/011-internal-federated-ledger.md
PRD PRD-022 docs/specs/shared/prd/022-cross-context-messaging.md
PRD PRD-003 docs/specs/shared/prd/003-internal-federated-ledger.md
SDS SDS-047 docs/specs/shared/sds/047-messaging-infrastructure.md
SDS SDS-030 docs/specs/shared/sds/030-semantic-observability.md

Superseded Plans