Lattice Labs
Hands-on tutorials to learn Station Lattice step by step.
All lab materials are available in the Station repository under examples/lattice-lab/.
Lab Overview
| Lab | Description | Duration |
|---|
| Lab 1 | Local Docker setup with NATS | 10 min |
| Lab 2 | Embedded NATS orchestrator mode | 10 min |
| Lab 3 | Multi-station mesh network | 15 min |
| Lab 4 | NATS authentication | 10 min |
| Lab 5 | Async work assignment | 10 min |
Lab 1: Local Docker Setup
Start a NATS server with Docker and connect a station.
Prerequisites
- Docker installed
- Station CLI (
stn)
Steps
# 1. Start NATS with JetStream
docker run -d --name nats-lattice \
-p 4222:4222 -p 8222:8222 \
nats:latest -js
# 2. Verify NATS is running
curl http://localhost:8222/varz | jq '.server_name'
# 3. Start station with lattice
stn serve --lattice nats://localhost:4222 --workspace ./my-workspace
# 4. In another terminal, check status
stn lattice status
Expected Output
Lattice Status: MEMBER
Orchestrator: nats://localhost:4222
Connection: Connected
Station ID: abc123-def456
Station Name: my-laptop
Cleanup
docker stop nats-lattice && docker rm nats-lattice
Lab 2: Embedded NATS Orchestrator
Run a station as the orchestrator with embedded NATS.
Steps
# 1. Start orchestrator station
stn serve --orchestration --workspace ./orchestrator
# The orchestrator will:
# - Start embedded NATS on port 4222
# - Enable JetStream for persistence
# - Accept member connections
# 2. Verify embedded NATS
curl http://localhost:8222/varz | jq '.server_name'
# 3. Check lattice status
stn lattice status
# Expected output:
# Lattice Status: ORCHESTRATOR
# NATS URL: nats://0.0.0.0:4222
# Monitoring: http://0.0.0.0:8222
Connect a Member
In another terminal:
# Start a member station
stn serve --lattice nats://localhost:4222 --workspace ./member
# Check connected stations
stn lattice status
Lab 3: Multi-Station Mesh
Create a mesh with multiple specialized stations.
Architecture
┌──────────────────┐
│ Orchestrator │
│ (embedded NATS)│
└────────┬─────────┘
│
┌────────────────┼────────────────┐
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ SRE │ │ Security │ │ DevOps │
│ Station │ │ Station │ │ Station │
└──────────┘ └──────────┘ └──────────┘
Steps
# Terminal 1: Orchestrator
stn serve --orchestration --workspace ./orchestrator
# Terminal 2: SRE Station
stn serve --lattice nats://localhost:4222 --workspace ./sre-station
# Terminal 3: Security Station
stn serve --lattice nats://localhost:4222 --workspace ./security-station
# Terminal 4: DevOps Station
stn serve --lattice nats://localhost:4222 --workspace ./devops-station
Verify Mesh
# List all stations
stn lattice status
# List all agents across the mesh
stn lattice agents
# Execute agent on remote station
stn lattice agent exec k8s-health "Check pod status"
Lab 4: Authentication
Secure your lattice with token authentication.
Option 1: Token in NATS URL
# Start NATS with auth token
docker run -d --name nats-auth \
-p 4222:4222 -p 8222:8222 \
nats:latest -js --auth my-secret-token
# Connect with token in URL
stn serve --lattice "nats://my-secret-token@localhost:4222" --workspace ./station
Option 2: Embedded Orchestrator with Auth
# config.yaml
lattice:
orchestrator:
embedded_nats:
port: 4222
auth_token: my-secret-token
# Start orchestrator
stn serve --orchestration --config config.yaml
# Members must include token
stn serve --lattice "nats://my-secret-token@orchestrator:4222"
CLI Client with Auth
# Query lattice with auth token
stn lattice --nats "nats://my-secret-token@localhost:4222" agents
# Execute agent
stn lattice --nats "nats://my-secret-token@localhost:4222" \
agent exec echo-agent "Hello!"
Lab 5: Async Work Queue
Assign long-running tasks with progress tracking.
Steps
# 1. Start lattice (orchestrator mode for JetStream)
stn serve --orchestration --workspace ./station
# 2. Assign work asynchronously
stn lattice work assign log-analyzer "Analyze last 7 days of logs" --timeout 30m
# Output:
# Work assigned: work_abc123
# Agent: log-analyzer
#
# Use 'stn lattice work await work_abc123' to wait for results
# 3. Check status (non-blocking)
stn lattice work check work_abc123
# 4. Wait for completion
stn lattice work await work_abc123
Real-Time Dashboard
# Launch TUI dashboard
stn lattice dashboard
# Shows:
# - Active work items
# - Progress updates
# - Completed tasks
Lab Agents
The examples/lattice-lab/agents/ directory contains pre-built agents for testing:
| Agent | Purpose | Example Task |
|---|
echo-agent | Connectivity testing | "Hello World" |
math-agent | Calculations | "Calculate 25 * 17" |
joke-agent | Entertainment | "Tell me a programming joke" |
time-agent | Time queries | "What time is it?" |
sysinfo-agent | Status info | "What is the station status?" |
Using Lab Agents
# Copy agents to your workspace
mkdir -p ~/station/environments/default/agents
cp examples/lattice-lab/agents/*.prompt ~/station/environments/default/agents/
# Start station
stn serve --lattice nats://localhost:4222 --workspace ~/station
# Test agents
stn lattice agent exec echo-agent "Hello from the lab!"
stn lattice agent exec math-agent "What is 15 factorial?"
E2E Local Test
Run a complete local test with Docker:
cd examples/lattice-lab/e2e-local
# 1. Start NATS
docker compose up -d
# 2. Create .env from template
cp .env.example .env
# Edit .env with your OPENAI_API_KEY
# 3. Set up workspace
source .env
mkdir -p /tmp/e2e-lab/environments/default/agents
cp ../agents/*.prompt /tmp/e2e-lab/environments/default/agents/
# 4. Create config
cat > /tmp/e2e-config.yaml << EOF
workspace: /tmp/e2e-lab
ai_provider: openai
ai_model: gpt-4o-mini
encryption_key: "$(openssl rand -base64 32)"
lattice:
station_name: e2e-station
nats:
url: "nats://${NATS_AUTH_TOKEN}@localhost:14222"
EOF
# 5. Start station
export OPENAI_API_KEY=your-key
stn serve --config /tmp/e2e-config.yaml
# 6. Test (in another terminal)
source .env
stn lattice --nats "nats://${NATS_AUTH_TOKEN}@localhost:14222" agents
stn lattice --nats "nats://${NATS_AUTH_TOKEN}@localhost:14222" agent exec echo-agent "Hello E2E!"
# 7. Cleanup
docker compose down
Troubleshooting
”No responders available”
This usually means the target station isn’t subscribed. Check:
# Verify station is connected
curl http://localhost:8222/connz?subs=1 | jq '.connections[].subscriptions_list'
# Should see subscriptions like:
# lattice.station.{uuid}.agent.invoke
Stale station registrations
If a station was restarted, old entries may remain:
# List stations in registry
nats --server nats://localhost:4222 kv ls lattice-stations
# Delete stale entry
nats --server nats://localhost:4222 kv rm lattice-stations {old-uuid} -f
Connection refused
# Check NATS is running
docker ps | grep nats
curl http://localhost:8222/healthz
# Check firewall
nc -zv localhost 4222
Next Steps