This packet replaces the old Task 15 notes. It is aligned to Phase 14 / Task 15 in docs/plans/2026-01-25-end-state.md and to the current repo layout (infra/nats/*, infra/docker/*, apps/sea-mq-worker/*).
Use this as the exact execution guide for an agent implementing Task 15.
Deliver messaging that scales single instance → cluster → mesh, with deterministic topology, JetStream durability, and federation across clusters.
Minimum outcomes (per plan):
Verify these in-repo surfaces:
infra/nats/nats.conf (cluster-only config)infra/nats/nats.mesh.conf (if present)infra/nats/setup-streams.sh (stream provisioning)infra/docker/docker-compose.*.yml (NATS wiring)apps/sea-mq-worker/src/main.rs (env config)apps/sea-mq-worker/tests/e2e_messaging_federation_test.rs (existing or placeholder)If any of these differ, adjust this packet before coding.
Use NATS supercluster gateways (resolved default).
infra/nats/nats.conf (keep cluster-only path for local HA)infra/nats/nats.mesh.conf (federation config for mesh profile)Cluster:
NATS_CLUSTER_NAMENATS_CLUSTER_PORT (default 6222)NATS_ROUTE_1/2/3Federation (supercluster gateways):
NATS_GATEWAY_NAMENATS_GATEWAY_PORT (default 7522)NATS_PEER_GATEWAY_NAMENATS_PEER_GATEWAY_URLJetStream:
JETSTREAM_DOMAINcluster { ... } with routes listgateway { ... } with peer gateway URLsjetstream { store_dir: /data, domain: $JETSTREAM_DOMAIN }Success signal: nats --domain <domain> stream ls works on each cluster domain.
Add a mesh profile with two 3-node clusters (sea-a, sea-b).
infra/docker/docker-compose.dev.yml orinfra/docker/docker-compose.mesh.yml (recommended for clarity)JETSTREAM_DOMAIN=sea-a.JETSTREAM_DOMAIN=sea-b.sea-nats-a-1, sea-nats-a-2, sea-nats-a-3sea-nats-b-1, sea-nats-b-2, sea-nats-b-34422/4423/44245422/5423/54248822/8823/88249822/9823/9824Success signal: Gateway connections appear in NATS monitoring endpoints, and cross-cluster pub/sub works.
Modify infra/nats/setup-streams.sh:
STREAM_REPLICAS (default 1)JETSTREAM_DOMAIN (optional)NATS_URL--replicas=$STREAM_REPLICAS when creating streams/consumers.JETSTREAM_DOMAIN is set, pass --domain to nats stream add and nats consumer add.apps/sea-mq-worker/src/main.rs must support env-only configuration for:
Add only what is missing; preserve defaults and backwards compatibility.
Create/replace:
apps/sea-mq-worker/tests/e2e_messaging_federation_test.rssea.event.federation_probe.v1).E2E_NATS_A_URL (e.g., nats://localhost:4422)E2E_NATS_B_URL (e.g., nats://localhost:5422)These can be separate tests or a combined suite, but must be deterministic and skip-safe if the mesh isn’t running.
Bring up mesh (example):
1
docker compose -f infra/docker/docker-compose.mesh.yml --profile nats-mesh up -d
Run E2E test:
1
2
3
export E2E_NATS_A_URL="nats://localhost:4422"
export E2E_NATS_B_URL="nats://localhost:5422"
cargo test -p sea-mq-worker e2e_federation_pubsub_across_clusters -- --nocapture
Only mark Task 15 complete after tests pass.