- Get Started

Operations & Monitoring

OpenFlows is an orchestration layer that runs on top of Coder. Operating it means monitoring the controller, the Redis state machine, the Coder AI Gateway, and the fleet of ephemeral worker workspaces. This guide covers production runbooks, TUI usage, log locations, Redis inspection, monitoring NEXUS reconcile, and scaling workers. It is written for operators who need to keep a multi-tenant deployment healthy.

The controller runs inside a per-tenant Coder workspace named openflows-nexus-{tenant}. That workspace is the only long-lived component. All other workspaces are ephemeral and are created and destroyed as tickets move through the pipeline. Operators should treat the NEXUS workspace as the source of truth for a tenant's health.

Production Runbooks

The following runbooks are the most common operational procedures. They assume you have shell access to the NEXUS workspace and the Redis instance, and that you have installed the openflows CLI.

ProcedureSummary
Start controllerStart the tenant NEXUS workspace and verify the controller process is running.
Stop controllerIsolate the tenant, wait for active workers to finish their segment, then stop the NEXUS workspace.
Scale FORGE workersEdit agents.forge.instances in registry.json. Hot-reload applies within one poll cycle.
Rotate Coder tokenUpdate the CODER_NEXUS_TOKEN environment variable and restart the NEXUS workspace.
Update binariesRun ./update-binaries.sh on the NEXUS workspace to pull the latest openflows CLI.
Recover from Redis outageRestart Redis, verify keyspace prefixes are intact, and run openflows doctor.
Handle runaway workerIsolate the tenant, inspect the worker workspace, and terminate the workspace if needed.
Investigate stuck mergeCheck VESSEL logs, GitHub mergeable status, and CI status via the TUI or redis-cli.

Starting the Controller

Ensure the Coder deployment is reachable, the NEXUS workspace is running, and the Redis URL is correct. Then start the controller process inside the NEXUS workspace.

bash
coder ssh openflows-nexus-my-team

export REDIS_URL=redis://redis.internal:6379
export CODER_URL=https://coder.example.com
export CODER_NEXUS_TOKEN=...

openflows controller start --tenant my-team

Stopping the Controller

Isolating the tenant first stops new work from being assigned. Active workers are allowed to finish their current segment, but they will not receive new segments. After a graceful drain, stop the NEXUS workspace.

bash
openflows tenant isolate my-team

# Wait for active workers to reach a safe point
tail -f /tmp/openflows-controller.log

coder stop openflows-nexus-my-team

Updating Binaries

The ./update-binaries.sh script pulls the latest openflows release, replaces the CLI binary, and restarts the controller. Run it inside the NEXUS workspace.

bash
coder ssh openflows-nexus-my-team
./update-binaries.sh

Updates are not zero-downtime

The controller process must restart to load a new binary. Isolate the tenant before running update-binaries.sh to avoid interrupting active workers mid-segment.

TUI Usage

The OpenFlows TUI is a ratatui-based dashboard that runs on the NEXUS workspace. It shows live tickets, worker slots, events, and logs. It also provides one-key diagnostics and tenant isolation. Operators should keep a TUI session open during incident response.

bash
openflows tui --tenant my-team
KeyAction
openflows tuiLaunch the interactive dashboard.
q / Ctrl-CQuit the TUI.
TabSwitch between panes: tickets, workers, events, logs.
EnterOpen detail view for the selected ticket or worker.
iIsolate the selected tenant.
rResume the selected tenant.
dRun doctor diagnostics for the selected tenant.
/Search tickets or workers by ID or status.

TUI is read-only by default

The TUI does not modify state unless you explicitly press an action key. The default view is read-only and safe to leave open on a shared screen. Isolation and resume keys require the operator to have the Coder Owner role for the tenant.

Log Locations

The controller writes a single log file on the NEXUS workspace. Worker logs are also forwarded to the controller, which writes them to the same file with a worker tag. This keeps all operational telemetry in one place.

bash
# Controller log on the NEXUS workspace
tail -f /tmp/openflows-controller.log

# Recent error lines
rg ERROR /tmp/openflows-controller.log | tail -50

# Recent worker-specific logs
rg 'forge-1' /tmp/openflows-controller.log | tail -100

The log format is structured JSON with a human-readable prefix. Each line contains a timestamp, tenant, worker ID, level, and message. The structured fields are stable and can be shipped to a central log aggregator with a simple forwarder.

json
{
  "ts": "2026-07-20T15:43:21Z",
  "tenant": "my-team",
  "worker": "forge-1",
  "level": "INFO",
  "msg": "segment review APPROVED",
  "ticket": "ISSUE-123",
  "segment": 2
}

Redis Inspection

Redis is the production SharedStore backend. Every tenant's keys are prefixed with ns:{tenant}:. Operators can inspect the live state directly with redis-cli. This is useful when the TUI is unavailable or when you need to run programmatic checks.

CommandPurpose
KEYS ns:{"{tenant}"}:*List all keys for a tenant (avoid in production; use SCAN instead).
SCAN 0 MATCH ns:{"{tenant}"}:tickets COUNT 100Paginate through ticket keys safely.
HGET ns:{"{tenant}"}:tickets ISSUE-123Read the status of a specific ticket.
HGETALL ns:{"{tenant}"}:worker_slotsRead all worker slot statuses.
LRANGE ns:{"{tenant}"}:event_ring 0 99Read the most recent 100 events.
HLEN ns:{"{tenant}"}:pending_prsCount PRs awaiting merge.
bash
# Live event stream for a tenant
redis-cli MONITOR | rg 'ns:my-team'

# Check if a worker is still alive
redis-cli HGET ns:my-team:worker_slots forge-1

Redis is the source of truth

The controller keeps state in Redis, not in memory. If the controller restarts, it resumes from Redis on the next poll cycle. Do not manually edit Redis keys unless you are following a runbook; inconsistent state will trigger NEXUS reconcile recovery.

Monitoring NEXUS Reconcile

NEXUS runs reconcile() on every poll cycle. It scans the SharedStore for inconsistencies and takes corrective action. Reconcile is the heart of OpenFlows' ability to self-heal. Monitoring it means watching for the categories of problems it detects and the actions it takes.

Reconcile events are emitted to the tenant's event ring and logged at INFO level. Look for lines containing reconcile: in the controller log. Each reconcile event has a category field that describes the type of inconsistency detected.

CategoryWhat NEXUS does
orphaned_ticketsTickets assigned to a worker that no longer exists. Reassign or escalate to AwaitingHuman.
unmerged_prsPRs with all checks passed but not yet merged. VESSEL should pick these up.
stale_workersWorkers whose last heartbeat is older than the timeout. Mark as failed and reassign.
completed_without_prTickets marked completed but with no open PR. FORGE must reopen or escalate.
sentinel_reject_loopSENTINEL has rejected the same segment more than the limit. Escalate to AwaitingHuman.
merge_conflictPR mergeable state is false. VESSEL retries, then escalates if unresolved.
bash
# Watch reconcile events in real time
tail -f /tmp/openflows-controller.log | rg 'reconcile:'

# Read the last 50 reconcile events from Redis
redis-cli LRANGE ns:my-team:event_ring 0 49 | rg 'reconcile'

Too many reconcile events is a smell

A healthy deployment emits a small, steady number of reconcile events. A sudden spike in orphaned tickets, stale workers, or merge conflicts usually indicates an upstream problem: Coder API instability, Redis latency, or a change in the GitHub repository settings. Investigate the root cause rather than letting NEXUS mask it.

Scaling Workers

FORGE workers are the primary parallel resource. Each instance is an independent Coder workspace. Scaling is done by changing the agents.forge.instances value in registry.json. The change is hot-reloaded on the next NEXUS poll cycle.

Scaling considerations:

json
{
  "agents": {
    "forge": { "instances": 4 }
  }
}
DimensionHow to scale
Vertical scalingUse a larger Coder workspace template for the NEXUS controller or FORGE workers.
Horizontal scalingIncrease FORGE instances in registry.json. Each instance is a separate Coder workspace.
Redis scalingMove from a single Redis node to a managed Redis cluster or replica set.
Coder scalingScale the Coder control plane and workspace provisioner to handle more concurrent workspaces.
Gateway scalingAdd more replicas of the Coder AI Gateway or LiteLLM proxy for throughput.

Set a Coder workspace quota

Coder supports per-user or per-group workspace quotas. Set a quota on the tenant's NEXUS service account to prevent runaway FORGE instances from exhausting the provisioner. A reasonable starting point is 10 workspaces per tenant (1 NEXUS + up to 9 FORGE/SENTINEL/VESSEL/LORE).