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.
| Procedure | Summary |
|---|---|
| Start controller | Start the tenant NEXUS workspace and verify the controller process is running. |
| Stop controller | Isolate the tenant, wait for active workers to finish their segment, then stop the NEXUS workspace. |
| Scale FORGE workers | Edit agents.forge.instances in registry.json. Hot-reload applies within one poll cycle. |
| Rotate Coder token | Update the CODER_NEXUS_TOKEN environment variable and restart the NEXUS workspace. |
| Update binaries | Run ./update-binaries.sh on the NEXUS workspace to pull the latest openflows CLI. |
| Recover from Redis outage | Restart Redis, verify keyspace prefixes are intact, and run openflows doctor. |
| Handle runaway worker | Isolate the tenant, inspect the worker workspace, and terminate the workspace if needed. |
| Investigate stuck merge | Check 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.
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.
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.
coder ssh openflows-nexus-my-team ./update-binaries.sh
Updates are not zero-downtime
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.
openflows tui --tenant my-team
| Key | Action |
|---|---|
openflows tui | Launch the interactive dashboard. |
q / Ctrl-C | Quit the TUI. |
Tab | Switch between panes: tickets, workers, events, logs. |
Enter | Open detail view for the selected ticket or worker. |
i | Isolate the selected tenant. |
r | Resume the selected tenant. |
d | Run doctor diagnostics for the selected tenant. |
/ | Search tickets or workers by ID or status. |
TUI is read-only by default
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.
# 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.
{
"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.
| Command | Purpose |
|---|---|
KEYS ns:{"{tenant}"}:* | List all keys for a tenant (avoid in production; use SCAN instead). |
SCAN 0 MATCH ns:{"{tenant}"}:tickets COUNT 100 | Paginate through ticket keys safely. |
HGET ns:{"{tenant}"}:tickets ISSUE-123 | Read the status of a specific ticket. |
HGETALL ns:{"{tenant}"}:worker_slots | Read all worker slot statuses. |
LRANGE ns:{"{tenant}"}:event_ring 0 99 | Read the most recent 100 events. |
HLEN ns:{"{tenant}"}:pending_prs | Count PRs awaiting merge. |
# 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
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.
| Category | What NEXUS does |
|---|---|
| orphaned_tickets | Tickets assigned to a worker that no longer exists. Reassign or escalate to AwaitingHuman. |
| unmerged_prs | PRs with all checks passed but not yet merged. VESSEL should pick these up. |
| stale_workers | Workers whose last heartbeat is older than the timeout. Mark as failed and reassign. |
| completed_without_pr | Tickets marked completed but with no open PR. FORGE must reopen or escalate. |
| sentinel_reject_loop | SENTINEL has rejected the same segment more than the limit. Escalate to AwaitingHuman. |
| merge_conflict | PR mergeable state is false. VESSEL retries, then escalates if unresolved. |
# 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
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:
- Each instance consumes a Coder workspace slot and a GitHub MCP connection.
- Concurrency is bounded by the Coder provisioner's capacity and the AI Gateway rate limits.
- More instances do not make a single ticket faster; they increase the number of tickets that can be processed in parallel.
- Reduce instances during off-hours to lower Coder and LLM costs.
{
"agents": {
"forge": { "instances": 4 }
}
}| Dimension | How to scale |
|---|---|
| Vertical scaling | Use a larger Coder workspace template for the NEXUS controller or FORGE workers. |
| Horizontal scaling | Increase FORGE instances in registry.json. Each instance is a separate Coder workspace. |
| Redis scaling | Move from a single Redis node to a managed Redis cluster or replica set. |
| Coder scaling | Scale the Coder control plane and workspace provisioner to handle more concurrent workspaces. |
| Gateway scaling | Add more replicas of the Coder AI Gateway or LiteLLM proxy for throughput. |
Set a Coder workspace quota