How it works
A full walkthrough of the Chicago Bottleneck scenario — from the user typingrun baselineto a confirmed optimal solution, using the real data values.
FACTORY_SHENZHEN (50,000 unit supply)
│
│ SEA — $4.20/unit — 21 days
▼
WH_CHICAGO_01 (capacity: 10,000 ← the bottleneck)
│
┌────┼────┐
│ │ │
▼ ▼ ▼
CUST_NAPERVILLE CUST_EVANSTON CUST_AURORA
(4,800) (3,600) (3,000)
Total Q3 demand: 11,400 units → Deficit: 1,400 units → INFEASIBLEUser types the command
The user types run baseline into the TX-1 terminal prompt.
The CommandBar calls invoke("run_command") — this goes through the Tauri Rust layer to the FastAPI sidecar, which returns {"status":"accepted"} immediately. The graph runs asynchronously in a background thread. All progress comes back over WebSocket.
Intent Classification
Dispatcher · HaikuThe first LangGraph node sends the query to Claude Haiku with strict instructions: return one of four intent categories, no prose.
The graph routes to solver_engine. The terminal streams: Intent → SOLVE_REQUEST · Network → CHICAGO
OR-Tools Solver Runs
Solver EngineOR-Tools GLOP (linear programming) loads the Chicago network from SQLite and sets up the Transportation Problem:
- Factory outflow ≤ 50,000 (supply cap)
- Chicago warehouse outflow ≤ 10,000 (capacity cap) ← this binds
- Each customer receives exactly their demand
- Minimise: total transport cost
The solver returns INFEASIBLE. No combination of flows can route 11,400 units through a 10,000-unit bottleneck.
Archivist Query
Archivist · ChromaDBBefore the Strategist reasons, the Archivist queries ChromaDB for semantically similar past violations. On first run the store is empty. After the first approved fix, subsequent runs surface the historical context — informing the Strategist's headroom choice.
Strategist Reasons
Strategist · SonnetClaude Sonnet receives the violation and a minimal context payload — only the relevant rows from SQLite, never the full database:
node_capacitiesrow for WH_CHICAGO_01- Total Q3 demand aggregated from demand_forecast
- Historical context from Archivist (if any)
Sonnet reasons: the minimum viable fix is to raise capacity to at least 11,400. It proposes 12,000 — 5% headroom buffer.
Dry-Run Validation
Before the fix is ever shown to the user, the Strategist proves it works:
Only if dry_run_passed = true does the proposal proceed. This is the primary defence against hallucination.
Sensitivity Explorer renders
Sensitivity Analysis CardBefore the action card, a Sensitivity Explorer appears showing five capacity scenarios:
↑↓ arrow keys navigate between scenarios. Context before action.
InfeasibilityCard renders
HITL Approval GateThe action card appears below the explorer. The graph is now paused — the LangGraph Human Approval Gate is blocked on a threading.Event waiting for the user's decision. All older terminal entries dim to 30% opacity.
The user sees: violation details, Strategist rationale, before/after comparison table, the SQL patch, and dry-run confirmation.
User approves
User presses ⌘↵. The frontend calls invoke("resolve_approval", {decision: "APPROVED"}). The buttons lock immediately — no double-trigger possible.
Rust posts to localhost:8765/approve/{card_id}, which sets the threading.Event in the Approval Registry. The graph unblocks.
DB patched + Archivist updated
The apply_fix node executes the real SQL patch and writes the audit log:
The Archivist also stores the approved fix in ChromaDB — the system now has memory of this violation pattern for future sessions.
Solver reruns → SUCCESS
The graph loops back to solver_engine. OR-Tools runs again with the patched capacity. This time: OPTIMAL.
A green SolveSuccess card renders. The full loop — from run baseline to confirmed solution — completed with one human decision.
All terminal commands
❯ check healthData quality scan → HealthArtifact card with readiness score❯ run baselineChicago Auto-Fix loop — triggers INFEASIBLE → Approve → SUCCESS❯ run amsterdamEU network Auto-Fix loop — Rotterdam → Amsterdam → Brussels/Frankfurt/Paris❯ resetRestore Chicago WH_CHICAGO_01 to 10,000 units (dirty data)❯ reset amsterdamRestore Amsterdam WH_AMSTERDAM_01 to 15,000 units (dirty data)❯ reset allRestore both networks simultaneously❯ historyShow what the Archivist has learned from past approved fixes