# Agent-to-Agent (A2A) Protocol (/docs/a2a) # Agent-to-Agent (A2A) Protocol [#agent-to-agent-a2a-protocol] Arbiter implements standard **Agent-to-Agent (A2A)** interoperability, allowing autonomous coding agents, orchestration frameworks, and peer AI systems to discover Arbiter's capabilities and delegate environment management tasks through a standardized contract. *** ## The Agent Card (`/.well-known/agent-card.json`) [#the-agent-card-well-knownagent-cardjson] Arbiter serves a machine-readable **Agent Card** at `/.well-known/agent-card.json`. This endpoint describes the agent's identity, capabilities, supported skills, and task delegation endpoints. ### Agent Card JSON Schema [#agent-card-json-schema] ```json { "name": "Arbiter", "description": "Understands, diagnoses, and safely reconciles local Linux development environments.", "capabilities": { "streaming": false, "pushNotifications": false }, "skills": [ { "id": "prepare_project", "name": "Prepare local project" }, { "id": "resolve_port_conflicts", "name": "Resolve port conflicts" }, { "id": "diagnose_project", "name": "Diagnose local environment" }, { "id": "inspect_docker", "name": "Inspect Docker state" }, { "id": "check_stack_readiness", "name": "Check policy-controlled stack readiness" } ], "taskEndpoint": "/api/v1/projects/{id}/prepare" } ``` *** ## Supported A2A Skills [#supported-a2a-skills] When another agent delegates a task to Arbiter, it references one of the following skill identifiers: ### 1. `prepare_project` [#1-prepare_project] * **Objective**: Inspect a project, audit its Compose and `.env` files against live host ports, resolve collisions to deterministic free ports, and stage safety approvals. * **Underlying Action**: `agent.prepare_project(identifier=project)` * **Safety Policy**: Creates a pending safety approval with time-travel diffs before applying any file modifications. ### 2. `resolve_port_conflicts` [#2-resolve_port_conflicts] * **Objective**: Identify port collisions for a registered project and compute deterministic port reassignment plans. * **Underlying Action**: `agent.prepare_project(identifier=project, resolve_port_conflicts=True)` ### 3. `diagnose_project` [#3-diagnose_project] * **Objective**: Analyze Compose services, container health, missing environment variables, and listening sockets. * **Underlying Action**: `agent.diagnose_project(identifier=project)` * **Safety Policy**: Read-only diagnostic report; no approval required. ### 4. `inspect_docker` [#4-inspect_docker] * **Objective**: Query running containers, images, volumes, and networks associated with the project workspace. * **Underlying Action**: `services.docker.list_containers()` ### 5. `check_stack_readiness` [#5-check_stack_readiness] * **Objective**: Evaluate health check gates (TCP sockets, HTTP endpoints, container health) for a multi-project stack preset subject to destination safety policies. * **Underlying Action**: `services.stacks.check_stack_readiness(identifier=project)` *** ## Task Delegation Flow [#task-delegation-flow] When an external orchestrator (e.g. LangGraph supervisor, AutoGen, CrewAI, or another Antigravity instance) interacts with Arbiter: ```text ┌────────────────────────┐ ┌────────────────────────┐ │ Orchestrator Agent │ │ Arbiter Instance │ └───────────┬────────────┘ └───────────┬────────────┘ │ │ │ 1. Discover capabilities │ │ GET /.well-known/agent-card.json │ ├───────────────────────────────────────────►│ │ 2. Return declared skills & task endpoints│ │◄───────────────────────────────────────────┤ │ │ │ 3. Delegate task (e.g. "prepare_project") │ │ POST /api/v1/projects/billing-app/prepare │ ├───────────────────────────────────────────►│ │ │ │ 4. Return diagnosis & Approval ID │ │◄───────────────────────────────────────────┤ │ │ │ 5. Operator approves via CLI/TUI/UI │ │ POST /api/v1/approvals/{id}/approve │ │───────────────────────────────────────────►│ ``` *** ## Inter-Agent Integration Example (Python) [#inter-agent-integration-example-python] An orchestrator can easily interact with Arbiter using standard HTTP requests: ```python import httpx ARBITER_URL = "http://127.0.0.1:8765" # 1. Fetch Agent Card client = httpx.Client(base_url=ARBITER_URL) card = client.get("/.well-known/agent-card.json").json() print(f"Connected to agent: {card['name']}") # 2. Delegate project preparation response = client.post( "/api/v1/projects/my-service/prepare", json={ "resolve_port_conflicts": True, "start": True, "verify": True, }, ) result = response.json() if result.get("status") == "approval_required": approval_id = result["approval"]["id"] print(f"Safety approval created: {approval_id}") print(f"Proposed actions: {result['approval']['summary']}") ``` # AI Agent & Tool Runtime (/docs/agent-runtime) # AI Agent & Tool Calling Runtime [#ai-agent--tool-calling-runtime] Arbiter features an intelligent agent runtime that combines **deterministic intent dispatching** with **LangChain v1 / LangGraph tool-calling agents**. It is designed to safely answer natural-language infrastructure queries, diagnose runtime issues, and propose environment fixes without having unrestricted shell or arbitrary filesystem write access. ```text ┌────────────────────────────────────────────────────────┐ │ User Query / REST / Web UI / CLI │ └───────────────────────────┬────────────────────────────┘ │ ┌───────────────────────────▼────────────────────────────┐ │ Deterministic Intent Router │ │ (Handles common patterns instantly without LLM) │ └───────────────────────────┬────────────────────────────┘ │ (fallback for complex queries) ┌───────────────────────────▼────────────────────────────┐ │ LangGraph Tool-Calling Agent Loop │ │ ┌────────────────────────────────────────────────┐ │ │ │ Models: OpenAI / Anthropic / Ollama / Local │ │ │ ├────────────────────────────────────────────────┤ │ │ │ Typed Tool Registry (23+ Read/Propose Tools) │ │ │ ├────────────────────────────────────────────────┤ │ │ │ Redaction & Privacy Guard │ │ │ └────────────────────────────────────────────────┘ │ └───────────────────────────┬────────────────────────────┘ │ NDJSON / Markdown Stream ┌───────────────────────────▼────────────────────────────┐ │ Structured Audit Events + Explanatory Output │ └────────────────────────────────────────────────────────┘ ``` *** ## Agent Architecture Principles [#agent-architecture-principles] 1. **Deterministic-First**: If a user asks a predictable query (e.g., *"What is using port 5432?"* or *"List all containers"*), the agent routes directly to optimized service calls without incurring LLM latency or token costs. 2. **Strict Tool Boundaries**: The LLM interacts with the host *only* through typed, structured tools (e.g., `find_port_owner`, `detect_port_conflicts`, `inspect_docker`). It has **no raw shell (`bash`) tool** and **no arbitrary file edit tool**. 3. **Propose-Only Mutations**: If the agent decides a configuration file needs editing or a container needs recreating, it cannot perform the action directly. It can only generate a typed `ActionSpec`, which yields a persisted safety approval. 4. **Redacted Execution Trace**: Streaming traces provide full transparency over model routing, tool invocations, and execution phases, while redacting sensitive environment variables and omitting private model chain-of-thought. *** ## Supported LLM Providers & Configuration [#supported-llm-providers--configuration] Arbiter supports any standard OpenAI-compatible API, Anthropic, or local model providers. ### Environment Configuration (`.env`) [#environment-configuration-env] ```bash # OpenAI or OpenAI-Compatible API (Ollama, vLLM, OpenRouter, LiteLLM) LLM_BASE_URL=https://api.openai.com/v1 LLM_API_KEY=sk-... LLM_MODEL=gpt-4o-mini LLM_REASONING_EFFORT=none # Lightweight model for natural language topology search FILTER_LLM_MODEL=gpt-5.4-nano # Maximum tool loop iterations per query AGENT_MAX_STEPS=12 ``` ### Local Models via Ollama [#local-models-via-ollama] To run completely offline with Ollama: ```bash LLM_BASE_URL=http://127.0.0.1:11434/v1 LLM_API_KEY=ollama LLM_MODEL=llama3.2 ``` *** ## Typed Agent Tool Registry [#typed-agent-tool-registry] The agent runtime exposes 23+ structured tools registered via `arbiter/agent/tools.py`: | Tool Name | Scope | Description | | :------------------------------- | :--------- | :------------------------------------------------------- | | `topology_get` | Topology | Fetch complete live machine graph. | | `resource_inspect` | Topology | Inspect one resource and its direct neighbors. | | `project_inspect` | Projects | Retrieve workspace topology and Compose evidence. | | `project_diagnose` | Projects | Analyze errors, missing ports, and stopped containers. | | `project_reconciliation_plan` | Projects | Generate dry-run port conflict resolution plan. | | `config_drift_audit` | Config | Audit `.env` drift vs `compose.yaml` and `.env.example`. | | `list_ports` | Ports | List active TCP listening ports and process owners. | | `find_port_owner` | Ports | Find PID/container owning a specific TCP port. | | `find_free_port` | Ports | Find available host port at or above target port. | | `detect_port_conflicts` | Ports | Detect duplicate port claims across projects. | | `containers_list` | Docker | List all containers with Compose labels. | | `container_inspect` | Docker | Inspect detailed Docker container inspection state. | | `volume_inspect` | Docker | Inspect Docker volume metadata. | | `network_inspect` | Docker | Inspect Docker network bridge/driver state. | | `processes_list` | System | List processes with listening ports and cmdlines. | | `process_inspect` | System | Inspect specific process by PID. | | `make_targets_list` | Makefile | Extract targets and comments from project Makefile. | | `dockerfile_inspect` | Dockerfile | Heuristic inspection of Dockerfile stages and exposures. | | `prepare_project` | Mutation | Propose port conflict reconciliation and approval. | | `stacks_list` | Stacks | List multi-project presets and active state. | | `stack_inspect` | Stacks | Inspect stack members, tags, and readiness probes. | | `stack_boot_order` | Stacks | Compute DAG boot plan with Kahn's algorithm. | | `stack_readiness_check` | Stacks | Probe TCP/HTTP/Docker health check gates. | | `stack_readiness_request_access` | Stacks | Request operator approvals for non-local probes. | | `stack_switch` | Stacks | Propose 1-click context switch to target stack. | *** ## Streaming Protocol (`POST /api/v1/agent/query/stream`) [#streaming-protocol-post-apiv1agentquerystream] The browser control panel and API clients receive real-time execution feedback via **NDJSON (Newline-Delimited JSON)** streaming. ### Event Frame Types [#event-frame-types] ```json {"type": "phase", "phase": "routing", "description": "Analyzing intent..."} {"type": "tool_call_start", "name": "list_ports", "arguments": {}} {"type": "tool_call_end", "name": "list_ports", "result": [{"port": 5432, "process": "postgres"}]} {"type": "phase", "phase": "model", "description": "Synthesizing answer..."} {"type": "message", "delta": "Port 5432 is currently occupied by PostgreSQL (PID 12345)."} {"type": "phase", "phase": "done"} ``` *** ## Natural Language Topology Filtering [#natural-language-topology-filtering] Arbiter includes a specialized intelligence endpoint `POST /api/v1/intelligence/filter`. It translates natural-language queries (e.g., *"show all postgres containers listening on 5432"*) into a structured JSON filter plan using `FILTER_LLM_MODEL`. If the model is unreachable, the system automatically falls back to an offline deterministic token parser. # REST API & Streaming Reference (/docs/api) # REST API & Streaming Reference [#rest-api--streaming-reference] Arbiter exposes a complete, typed REST API under `http://127.0.0.1:8765/api/v1`. By default, the API binds strictly to `127.0.0.1` for local safety. *** ## Health & Discovery Endpoints [#health--discovery-endpoints] ### `GET /health` [#get-health] Returns the status, server name, and active version of the Arbiter daemon. * **Response**: `{"status": "ok", "name": "Arbiter", "version": "0.5.0"}` ### `GET /.well-known/agent-card.json` [#get-well-knownagent-cardjson] Returns the standardized Agent-to-Agent (A2A) Agent Card declaring Arbiter's skills and task endpoints. *** ## Ports Endpoints (`/api/v1/ports`) [#ports-endpoints-apiv1ports] | Method | Endpoint | Description | | :----- | :------------------------ | :-------------------------------------------------------------------------------------------------- | | `GET` | `/api/v1/ports` | List all active host TCP listening ports and correlated process/Docker owners. | | `GET` | `/api/v1/ports/free` | Find `count` free host ports in the configured or requested range (`?start=3000&end=4000&count=5`). | | `GET` | `/api/v1/ports/conflicts` | Detect collisions across registered project declarations and live host sockets. | | `POST` | `/api/v1/ports/suggest` | Suggest the nearest free port at or above `{"preferred_port": 3000}`. | | `GET` | `/api/v1/ports/{port}` | Inspect process or Docker container owning a specific port (or `{"available": true}`). | *** ## Projects Endpoints (`/api/v1/projects`) [#projects-endpoints-apiv1projects] | Method | Endpoint | Description | | :------- | :------------------------------------------ | :----------------------------------------------------------------------- | | `GET` | `/api/v1/projects` | List all registered development projects. | | `POST` | `/api/v1/projects` | Register a new project by path (`{"path": "/home/user/dev/app"}`). | | `POST` | `/api/v1/projects/scan` | Scan configured `PROJECT_ROOTS` up to `PROJECT_SCAN_DEPTH` for projects. | | `GET` | `/api/v1/projects/{id}` | Inspect registered project metadata, compose files, and detected ports. | | `DELETE` | `/api/v1/projects/{id}` | Unregister project from SQLite database without deleting any files. | | `GET` | `/api/v1/projects/{id}/workspace` | Get workspace topology graph specific to the project. | | `GET` | `/api/v1/projects/{id}/ports` | List ports declared across the project's Compose services. | | `GET` | `/api/v1/projects/{id}/services` | List all Compose service names in the project. | | `GET` | `/api/v1/projects/{id}/environment` | Get resolved environment key-value pairs for the project. | | `GET` | `/api/v1/projects/{id}/status` | Diagnose project status, stopped containers, and missing variables. | | `GET` | `/api/v1/projects/{id}/reconciliation-plan` | Generate dry-run port conflict resolution plan. | | `POST` | `/api/v1/projects/{id}/prepare` | Propose port conflict reconciliation and create safety approval. | | `POST` | `/api/v1/projects/{id}/start` | Propose starting project containers via Compose. | | `POST` | `/api/v1/projects/{id}/stop` | Propose stopping project containers. | | `POST` | `/api/v1/projects/{id}/restart` | Propose restarting project containers. | *** ## File Editor Endpoints (`/api/v1/projects/{id}/files`) [#file-editor-endpoints-apiv1projectsidfiles] | Method | Endpoint | Description | | :----- | :--------------------------------------------- | :--------------------------------------------------------------------------------------- | | `GET` | `/api/v1/projects/{id}/files` | List editable configuration files (`.env*`, `compose*.yaml`, `Makefile`, `Dockerfile*`). | | `GET` | `/api/v1/projects/{id}/files/content?path=...` | Read configuration file content and SHA-256 hash. | | `POST` | `/api/v1/projects/{id}/files/preview` | Preview unified diff and secret-masked changes. | | `POST` | `/api/v1/projects/{id}/files/save` | Stage reviewed file save with `expected_sha256` verification. | | `POST` | `/api/v1/projects/{id}/files/undo` | Undo latest managed edit from automatic backup. | *** ## Makefile & Dockerfile Endpoints [#makefile--dockerfile-endpoints] | Method | Endpoint | Description | | :----- | :------------------------------------------------ | :--------------------------------------------------------------------- | | `GET` | `/api/v1/projects/{id}/make/targets` | List parsed Makefile targets, comments, and risk levels. | | `GET` | `/api/v1/projects/{id}/make/targets/{target}` | Inspect specific Make target and commands. | | `POST` | `/api/v1/projects/{id}/make/targets/{target}/run` | Propose running a Make target in project directory. | | `GET` | `/api/v1/projects/{id}/dockerfiles` | Inspect Dockerfile base images, exposed ports, and multi-stage builds. | *** ## Docker & Compose Endpoints [#docker--compose-endpoints] | Method | Endpoint | Description | | :------- | :--------------------------------------------------------- | :-------------------------------------------------------------------- | | `GET` | `/api/v1/containers` | List all local Docker containers with Compose metadata. | | `GET` | `/api/v1/containers/{id}` | Inspect detailed container properties and port mappings. | | `GET` | `/api/v1/containers/{id}/logs?tail=200` | Stream recent container log lines on demand. | | `GET` | `/api/v1/containers/{id}/stats` | Fetch one-shot CPU, memory, and network metrics. | | `POST` | `/api/v1/containers/{id}/start` | Propose starting a stopped container (`LOW_RISK`). | | `POST` | `/api/v1/containers/{id}/stop` | Propose stopping a container (`LOW_RISK`). | | `POST` | `/api/v1/containers/{id}/restart` | Propose restarting a container (`LOW_RISK`). | | `GET` | `/api/v1/images` | List Docker images. | | `DELETE` | `/api/v1/images/{id}` | Propose image removal (`HIGH_RISK`). | | `GET` | `/api/v1/volumes` | List Docker volumes. | | `DELETE` | `/api/v1/volumes/{id}` | Propose volume removal (`DESTRUCTIVE`). | | `GET` | `/api/v1/networks` | List Docker networks. | | `GET` | `/api/v1/docker/disk-usage` | Get Docker disk usage breakdown across images, volumes, and cache. | | `GET` | `/api/v1/compose/projects` | List Compose projects grouped by project label and working directory. | | `POST` | `/api/v1/compose/projects/{id}/validate` | Validate Compose file syntax with `compose config`. | | `POST` | `/api/v1/compose/projects/{id}/services/{service}/restart` | Restart a specific Compose service container. | | `POST` | `/api/v1/compose/projects/{id}/services/port` | Rewrite host port binding in Compose file and recreate service. | *** ## Multi-Project Stacks Endpoints (`/api/v1/stacks`) [#multi-project-stacks-endpoints-apiv1stacks] | Method | Endpoint | Description | | :------- | :--------------------------------------------- | :----------------------------------------------------------------------- | | `GET` | `/api/v1/stacks` | List all stack presets. | | `POST` | `/api/v1/stacks` | Create a new multi-project stack preset. | | `POST` | `/api/v1/stacks/seed-defaults` | Seed default environment stack presets if empty. | | `GET` | `/api/v1/stacks/active` | Get the currently running stack preset. | | `GET` | `/api/v1/stacks/{id}` | Inspect a stack preset by ID or name. | | `PUT` | `/api/v1/stacks/{id}` | Update stack metadata, projects, or tags. | | `DELETE` | `/api/v1/stacks/{id}` | Delete a stack preset from database. | | `GET` | `/api/v1/stacks/{id}/boot-order` | Compute DAG boot plan using Kahn's algorithm. | | `GET` | `/api/v1/stacks/{id}/readiness` | Evaluate live readiness gates (`tcp_port`, `http_get`, `docker_health`). | | `POST` | `/api/v1/stacks/{id}/readiness/authorizations` | Request operator approvals for non-local readiness gates. | | `GET` | `/api/v1/readiness/authorizations` | List persisted readiness destination grants. | | `DELETE` | `/api/v1/readiness/authorizations/{id}` | Revoke a readiness grant. | | `POST` | `/api/v1/stacks/{id}/switch` | Propose 1-click context switch to target stack. | | `POST` | `/api/v1/stacks/{id}/stop` | Propose stopping/hibernating active stack containers. | *** ## Config & Secrets Intelligence Endpoints [#config--secrets-intelligence-endpoints] | Method | Endpoint | Description | | :----- | :----------------------------------- | :-------------------------------------------------------- | | `GET` | `/api/v1/config-drift` | Global port drift and missing environment variable audit. | | `GET` | `/api/v1/projects/{id}/config-drift` | Config drift audit for a specific registered project. | *** ## Topology & Search Endpoints [#topology--search-endpoints] | Method | Endpoint | Description | | :----- | :----------------------------------- | :------------------------------------------------------------ | | `GET` | `/api/v1/topology` | Fetch complete live machine topology graph (`?project=name`). | | `GET` | `/api/v1/topology/project/{id}` | Fetch topology scoped to a single project. | | `GET` | `/api/v1/resources/{type}/{id:path}` | Inspect a resource and its direct neighbors. | | `GET` | `/api/v1/search?q=...&limit=30` | Keyword search across all topology nodes. | | `POST` | `/api/v1/intelligence/filter` | Natural language resource query filter plan. | *** ## Safety & Approvals Endpoints (`/api/v1/approvals`) [#safety--approvals-endpoints-apiv1approvals] | Method | Endpoint | Description | | :----- | :------------------------------- | :---------------------------------------------------------------------- | | `GET` | `/api/v1/approvals` | List all pending and historical safety approvals. | | `GET` | `/api/v1/approvals/{id}` | Inspect approval payload, arguments, and time-travel visual diff. | | `POST` | `/api/v1/approvals/{id}/approve` | Approve and execute stored action payload with verification. | | `POST` | `/api/v1/approvals/{id}/reject` | Reject a pending safety approval. | | `GET` | `/api/v1/actions` | Query immutable audit log of executed actions and verification results. | | `POST` | `/api/v1/impact` | Compute pre-execution impact analysis for an action. | *** ## Streaming Endpoints [#streaming-endpoints] ### 1. Activity Stream (Server-Sent Events) [#1-activity-stream-server-sent-events] * **Endpoint**: `GET /api/v1/events/stream` * **Media Type**: `text/event-stream` * **Description**: Real-time stream of Docker lifecycle events (container start, stop, die, destroy) and host process observations. ### 2. AI Agent Query Stream (NDJSON) [#2-ai-agent-query-stream-ndjson] * **Endpoint**: `POST /api/v1/agent/query/stream` * **Media Type**: `application/x-ndjson` * **Request Body**: `{"message": "What is using port 5432?"}` * **Description**: Streams typed agent execution events (`phase`, `routing`, `tool_call_start`, `tool_call_end`, `message`, `error`) with sanitized traces and markdown text deltas. # System Architecture & Safety Boundaries (/docs/architecture) # Architecture & Safety [#architecture--safety] Arbiter is structured to enforce strong safety boundaries while orchestrating local operations. It behaves like a small development-focused SRE operator. It deliberately avoids unrestricted shell access, arbitrary file editing, and unverified success claims. ## Architecture Diagram [#architecture-diagram] ```text Browser UI TUI / CLI REST clients MCP clients A2A clients │ │ │ │ │ └────────────────┴────────────────┴──────────────────┴─────────────────┘ │ Interface adapters │ Agent and high-level orchestration │ ┌───────────┬───────────┬───────────┬───────────┐ │ Projects │ Stacks │ Ports │ Docker │ ├───────────┼───────────┼───────────┼───────────┤ │ Compose │ Makefiles │ System │ Safety │ └───────────┴───────────┴───────────┴───────────┘ │ Linux /proc + ss Docker SDK SQLite project files ``` Business logic does not live in the UI, TUI, CLI, or API routes. Those layers translate requests into calls to shared domain services. This prevents one interface from bypassing safety rules or implementing behavior differently from another interface. The application is a single Python process. It does not require Redis, Celery, Kafka, Kubernetes, or another background infrastructure service. ## Core Domains [#core-domains] * `ports`: parses Linux `ss`, resolves processes through `/proc`, correlates Docker/Compose metadata, finds predictable free ports, and detects duplicate project claims and runtime port collisions. * `projects`: bounded discovery below configured roots and a refreshable SQLite registry. No whole-filesystem scan occurs. * `stacks`: multi-project environment profiles, 1-click context switching with dynamic `.env` override injection, port collision reconciliation, and topological DAG boot order orchestration. * `topology`, `system`, and `events`: generate a live, typed machine graph from Compose/Docker metadata, `/proc`, `ss`, and Docker events; runtime state is not persisted as authoritative data. * `docker` and `compose`: typed Docker SDK inspection, Compose label awareness, lifecycle operations, validation, and structured port editing. * `dockerfile`, `make`, `files`, and `impact`: Dockerfile and Make intelligence, safe registered-project editing with backup/diff/rollback/undo, and deterministic pre-operation impact summaries. * `config_intelligence`: cross-file port drift detection (`.env` vs `compose.yaml` vs `.env.example`), credential-safe missing env variable auditing, and visual diff dry-run time-travel state forecasting. * `safety`, `actions`, and `persistence`: immutable persisted approvals, one typed action dispatcher, history, and mandatory verification outcomes. * `agent`: deterministic intents plus LangChain v1's `create_agent` runtime, backed by LangGraph and restricted to the control plane's typed tools. * `api`, `cli`, `tui`, and `integrations`: thin adapters over the same services. ## Safety Model [#safety-model] Every state-changing operation has one of five risk levels: | Risk | Meaning | Default behavior | | ------------- | ------------------------------------------- | --------------------------------------------- | | `READ_ONLY` | Inspection and diagnosis | Automatically allowed | | `LOW_RISK` | Limited reversible operation | Approval required unless configured otherwise | | `MEDIUM_RISK` | Restart, stop, project start, config change | Approval required | | `HIGH_RISK` | Container/image removal and broad cleanup | Explicit approval required | | `DESTRUCTIVE` | Persistent data or volume deletion | Always explicit approval | An approval is a persisted object with a UUID, request ID, exact action name, exact serialized arguments, summary, risk, creation time, expiration time, and status. Approving an action executes the stored payload. The agent cannot replace or modify arguments after approval. Expired, rejected, or previously approved requests cannot be reused. ## Verification [#verification] Execution success and verification success are separate concepts. An action may return `verification_failed` even if its command completed. Examples of verification include: * checking a started/restarted container is running; * checking a stopped Compose project has stopped containers; * confirming a removed image or volume no longer exists; * refreshing project configuration after a port change; * checking the recreated service is running; * checking the new host port has the expected owner; * verifying stack readiness gates (`tcp_port`, `http_get`, `docker_health`) and checking measured endpoint latency. Network readiness gates pass through a destination policy before any socket is opened. Connections use the validated resolved IP directly to prevent DNS rebinding. Loopback and registered Compose services are automatic; non-local targets require a persisted, revocable approval scoped to protocol, host, port, and resolved addresses. Redirect hops are independently checked, while link-local and metadata destinations are unconditionally denied. ## Security Boundaries [#security-boundaries] The server binds to `127.0.0.1` by default. Important boundaries include: * no arbitrary shell API; * no generic filesystem read or write API; * bounded automatic project scanning; * explicit project registration; * recognized Compose filename validation; * fixed subprocess argument arrays with no `shell=True`; * subprocess timeouts and captured output; * bounded Docker log retrieval; * exact container lookup with ambiguity rejection; * secret-key redaction for names containing `PASSWORD`, `SECRET`, `TOKEN`, `API_KEY`, `PRIVATE_KEY`, or `CREDENTIAL`; * persisted approval for risky actions; * no automatic persistent-volume removal. # CLI Commands & Terminal Ergonomics (/docs/cli) # Command-line Interface [#command-line-interface] Arbiter provides a fast, developer-first command-line tool `arbiter` with interactive fuzzy pickers, a keyboard-driven Terminal UI (like lazydocker / k9s), shell prompt hooks, and structured JSON outputs for automation. *** ## Interactive Terminal UI (`arbiter tui`) [#interactive-terminal-ui-arbiter-tui] Launch a full-screen, keyboard-driven Terminal UI dashboard without opening a browser: ```bash arbiter tui ``` ### Key Features & Vim Keybindings [#key-features--vim-keybindings] * **Tabbed Views**: `[1] Ports`, `[2] Containers`, `[3] Approvals`, `[4] Projects`, `[5] Logs`, `[6] Readiness`. * **Navigation**: * `j` / `k` (or `Down` / `Up`): Navigate list items. * `1`..`5` or `Tab`: Switch active tab. * `g` / `G`: Jump to start / end of list. * `Enter`: Inspect item details / drill down. * `a`: Quickly approve and execute selected pending action. * `l`: Jump straight to container live log stream. * `p`: Propose project preparation with agent. * `r`: Force data reload. * `/`: Live fuzzy search within current view. * `?`: Toggle help overlay. * `q`: Quit. *** ## Interactive CLI Pickers (Fuzzy Search) [#interactive-cli-pickers-fuzzy-search] When running commands without explicit target arguments in an interactive terminal, Arbiter automatically opens an fzf-style fuzzy search picker with a live preview pane: ```bash # Interactively search and inspect registered projects arbiter inspect # Interactively search and prepare a project arbiter prepare # Interactively pick a running container to view logs arbiter logs # Interactively pick and execute a pending safety approval arbiter approve ``` *** ## Shell Prompt & Starship Integration (`arbiter prompt`) [#shell-prompt--starship-integration-arbiter-prompt] Display real-time environment status pills directly inside your terminal prompt (e.g. `⚡ Arbiter: 1 pending approval | 0 conflicts`): ### Output Formats [#output-formats] ```bash # ANSI colored pill (default) arbiter prompt # Starship prompt format arbiter prompt --format starship # Plain text without color codes arbiter prompt --format plain # Compact badge format arbiter prompt --format short # Structured JSON for scripts / statusbars arbiter prompt --format json ``` ### Shell Integration Setup [#shell-integration-setup] Generate one-line integration hooks for your shell configuration: ```bash # Starship prompt (~/.config/starship.toml) arbiter prompt init starship # Zsh (~/.zshrc) arbiter prompt init zsh # Bash (~/.bashrc) arbiter prompt init bash # Fish (~/.config/fish/config.fish) arbiter prompt init fish ``` *** ## Common Non-Interactive Commands [#common-non-interactive-commands] ```bash # Start the Arbiter web server arbiter serve # Ask the agent a natural-language question arbiter ask "what is using port 5432?" # List all current port listeners arbiter ports # Find available free ports arbiter ports --free 3000:4000 --count 10 # View registered projects arbiter projects # Discover projects under configured PROJECT_ROOTS arbiter projects --scan # Register a specific project arbiter register /path/to/project # Inspect a specific registered project arbiter inspect project-name # Prepare a specific project (detect conflicts, propose replacement ports, create approvals) arbiter prepare project-name # List Docker containers arbiter containers # View the last 200 log lines of a specific container arbiter logs container-name --tail 200 # View Docker disk usage statistics arbiter disk # Audit configuration and port drift across projects arbiter config drift # Audit configuration drift for a specific project arbiter config drift project-name # Safe audit of missing environment variables and masked credentials arbiter config audit project-name # Approve an action by its specific ID arbiter approve APPROVAL_ID # Multi-Project Stacks & Environment Switcher arbiter stack list --seed-defaults arbiter stack inspect "Billing Microservices" arbiter stack boot-order "Billing Microservices" arbiter stack readiness "Billing Microservices" arbiter stack readiness "Billing Microservices" --request-access arbiter stack readiness-access arbiter stack readiness-access --revoke AUTHORIZATION_ID `readiness` reports `allowed`, `approval_required`, or `blocked` for every gate. `--request-access` creates ordinary safety-queue approvals only for the gates that need them; it never approves access automatically. The TUI's **Readiness** tab lists persisted grants, and `x` revokes the selected grant after confirmation. arbiter stack switch "AI Pipeline + Vector DB" arbiter stack stop "AI Pipeline + Vector DB" # Start the MCP stdio adapter arbiter mcp ``` ## Output Format [#output-format] The CLI outputs structured JSON for machine-readable operations. This enables scripting and automation, while maintaining identical business logic as the API and browser control panel. # Config & Secrets Intelligence (/docs/config-secrets-intelligence) # Smart Config, .env & Secrets Intelligence [#smart-config-env--secrets-intelligence] Arbiter's **Smart Config, .env & Secrets Intelligence** engine proactively detects configuration drift across `.env`, `compose.yaml`, and `.env.example` files, conducts safe environment variable audits without leaking plaintext secrets, and provides visual diffs with dry-run state previews before applying changes. *** ## Overview [#overview] Local development environments frequently suffer from subtle configuration drift between environment files, container orchestrators, and runtime process states. The Config Intelligence engine eliminates these issues by: 1. **Port Drift & Variable Detection**: Reconciling port declarations across `.env`, `compose.yaml`, `.env.example`, and host network listeners. 2. **Safe Secrets Auditing**: Comparing active environment variables with example templates and detecting unconfigured placeholders while strictly masking sensitive credentials. 3. **Visual Diffs & Time-Travel Previews**: Generating unified side-by-side diffs and forecasting before-and-after state transitions across files, ports, and container lifecycles in the operator approval workflow. *** ## Core Capabilities [#core-capabilities] ### 1. Port Drift Detection [#1-port-drift-detection] The engine inspects and cross-references port definitions across multiple sources: * **Compose Default Mismatch**: Detects when a `.env` variable overrides a default specified in `compose.yaml` (e.g., `WEB_PORT=3000` overriding `${WEB_PORT:-8080}:80`). * **Unresolved Compose Variables**: Identifies variables referenced in `compose.yaml` that lack a fallback default and are missing from `.env`. * **Unreferenced `.env` Port Variables**: Flags port definitions in `.env` that are not consumed by any compose service or project target. * **Example vs. Environment Divergence**: Highlights differences between template values in `.env.example` and local `.env` values. * **Runtime Port Collisions**: Checks configured host ports against live listening sockets and flags collisions with external processes before container creation. ### 2. Safe Environment & Secrets Auditing [#2-safe-environment--secrets-auditing] The audit system ensures complete visibility into missing or misconfigured configuration variables without risking credential exposure: * **Missing Variables**: Identifies variables defined in `.env.example` (or `.env.sample`, `.env.template`, `.env.dist`, `.env.default`) that are absent from `.env`. * **Placeholder Detection**: Flags variables set to common unconfigured placeholder strings (such as `change_me`, `your_api_key_here`, `todo`, `insert_secret`). * **Undocumented Variables**: Highlights local `.env` keys that have not been documented in the repository's `.env.example`. * **Zero Raw Secret Exposure**: Sensitive keys matching patterns such as `API_KEY`, `TOKEN`, `PASSWORD`, `SECRET`, `PRIVATE_KEY`, `CREDENTIALS`, etc. are masked with fixed-length redactions (e.g., `sk-proj-••••••••cdef`, `pa••••••••23`), retaining prefix/suffix tokens for operational debugging while preventing plaintext exposure in logs, APIs, and UIs. ### 3. Visual Diffs & Dry-Run Time Travel [#3-visual-diffs--dry-run-time-travel] Prior to executing any configuration change or port reconciliation action: * **Unified Visual Diffs**: Generates structured line-by-line diffs (`context`, `added`, `deleted`) for target files. If the modified file is an environment configuration file, secrets are masked automatically in the diff output. * **State Transition Forecasting**: Simulates the exact state transitions for affected resources (files updated, ports remapped, containers restarted or recreated). * **Approval Workflow Integration**: Embedded directly into Arbiter's approval system (`/api/v1/approvals`) and CLI to provide operators with full context before approving high-risk operations. *** ## CLI Reference [#cli-reference] ### `arbiter config drift` [#arbiter-config-drift] Audit all registered projects or a specific project for port drift and configuration mismatches. ```bash # Audit all registered projects arbiter config drift # Audit a specific project arbiter config drift ``` #### Example Output [#example-output] ```json { "project_name": "web-service", "status": "warning", "drift_score": 14, "port_drifts": [ { "service": "web", "variable": "WEB_PORT", "env_value": 3000, "compose_default": 8080, "drift_type": "compose_default_mismatch", "severity": "warning", "message": "WEB_PORT in .env (3000) differs from compose.yaml default (8080)", "suggested_fix": "Update compose.yaml default or align .env with compose.yaml" } ], "missing_env_vars": [ { "key": "DATABASE_URL", "status": "missing", "is_secret": true, "description": "Required database connection string" } ], "recommendations": [ "Align WEB_PORT in .env (3000) with compose.yaml (8080)", "Add DATABASE_URL to .env (see .env.example)" ] } ``` ### `arbiter config audit` [#arbiter-config-audit] Perform a credential-safe audit of environment variables and secrets. ```bash # Summary audit across all projects arbiter config audit # Detailed audit for a specific project arbiter config audit ``` *** ## REST API Reference [#rest-api-reference] ### `GET /api/v1/config-drift` [#get-apiv1config-drift] Returns configuration drift analysis and environment audit reports for all registered projects. ### `GET /api/v1/projects/{identifier}/config-drift` [#get-apiv1projectsidentifierconfig-drift] Returns configuration drift analysis and environment audit report for a specific project ID or name. ### Approval Integration: `GET /api/v1/approvals/{approval_id}` [#approval-integration-get-apiv1approvalsapproval_id] Approval records automatically include a `time_travel` object containing visual diffs and simulated state transitions for the proposed action. *** ## Agent Tool Reference [#agent-tool-reference] The deterministic and LLM agent service provides the `config_drift_audit` tool: * **Name**: `config_drift_audit` * **Description**: Audit a project for .env and Compose configuration drift, port divergences, and missing variables. * **Parameters**: * `identifier` (string, optional): Project name or ID to audit. If omitted, audits all registered projects. # Configuration Reference (/docs/configuration) # Configuration Reference [#configuration-reference] Arbiter is configured using environment variables loaded from a `.env` file located in the root directory, or via system environment variables. Copy the provided `.env.example` template to create your `.env` file: ```bash cp .env.example .env ``` *** ## Complete Settings Table [#complete-settings-table] | Variable | Type | Default | Description | | :-------------------------------- | :------------------------- | :-------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------- | | `ARBITER_HOST` | `string` | `127.0.0.1` | Network interface IP address to bind the REST API and Web UI server. Must remain loopback (`127.0.0.1` or `::1`) unless `ALLOW_REMOTE_ACCESS=true`. | | `ARBITER_PORT` | `integer` | `8765` | TCP port for the REST API and Web UI server. | | `ALLOW_REMOTE_ACCESS` | `boolean` | `false` | Security override allowing non-loopback binds (e.g. `0.0.0.0`). *Caution: Arbiter does not include built-in multi-tenant authentication.* | | `DATABASE_URL` | `string` | `sqlite:///./arbiter.db` | SQLAlchemy database connection string for persisting registered projects, approvals, stack presets, and action audit logs. | | `PROJECT_ROOTS` | `string` (comma-separated) | `""` | Base directory paths to search when discovering development repositories (e.g. `/home/user/dev,/home/user/work`). | | `PROJECT_SCAN_DEPTH` | `integer` (1 to 8) | `4` | Maximum directory recursion depth during automatic project discovery scans. | | `LLM_BASE_URL` | `string` | `https://api.openai.com/v1` | Base URL for OpenAI-compatible LLM endpoints (supports OpenAI, Ollama, vLLM, LiteLLM, OpenRouter). | | `LLM_API_KEY` | `string` | `""` | API key for LLM authentication (can be left blank when using local Ollama). | | `LLM_MODEL` | `string` | `""` | Model identifier for natural language agent query reasoning (e.g. `gpt-4o`, `gpt-4o-mini`, `claude-3-5-sonnet`, `llama3.2`). | | `LLM_REASONING_EFFORT` | `string` | `none` | Reasoning effort tier for reasoning models (`none`, `low`, `medium`, `high`). | | `FILTER_LLM_MODEL` | `string` | `gpt-5.4-nano` | Lightweight model for translating natural-language topology queries into structured JSON filter plans. Falls back to offline regex parser if unavailable. | | `AGENT_MAX_STEPS` | `integer` | `12` | Maximum tool-calling loop iterations the agent may execute per user query before returning a response. | | `AUTO_APPROVE_READ_ONLY` | `boolean` | `true` | When `true`, automatically allows `READ_ONLY` inspection and diagnostic operations without generating approval requests. | | `AUTO_APPROVE_LOW_RISK` | `boolean` | `false` | When `true`, automatically allows `LOW_RISK` actions (e.g., starting a stopped container) without requiring explicit approval. | | `DEFAULT_PORT_SEARCH_RANGE_START` | `integer` | `3000` | Lower bound for deterministic free port allocation algorithms. | | `DEFAULT_PORT_SEARCH_RANGE_END` | `integer` | `9999` | Upper bound for deterministic free port allocation algorithms. | | `OBSERVATION_INTERVAL_SECONDS` | `float` | `3.0` | Background observation polling interval for Linux socket and process state synchronization. | | `SUBPROCESS_TIMEOUT` | `float` | `30.0` | Default timeout in seconds for subprocess executions (Docker CLI, Make, etc.). | *** ## Security Boundaries & Bind Host Policy [#security-boundaries--bind-host-policy] Arbiter enforces strict network isolation out of the box: * **Loopback Enforcement**: If `ARBITER_HOST` is set to any non-loopback IP (such as `0.0.0.0` or a LAN IP) while `ALLOW_REMOTE_ACCESS` is `false`, Arbiter will refuse to start with an immediate configuration error. * **Bounded Scans**: Arbiter never performs unconstrained root filesystem scans. Discovery is strictly bounded by `PROJECT_ROOTS` and `PROJECT_SCAN_DEPTH`. * **Secret Redaction**: Environment variables containing sensitive keywords (`PASSWORD`, `SECRET`, `TOKEN`, `API_KEY`, `PRIVATE_KEY`, `CREDENTIAL`) are masked across all UI, CLI, REST API, and MCP outputs. # Development & Contributing Guide (/docs/development) # Development & Contributing Guide [#development--contributing-guide] This guide covers setting up a local development environment for contributing to Arbiter, running test suites, and building the web UI and documentation site. *** ## Prerequisites [#prerequisites] * **Operating System**: Linux (Ubuntu 22.04+, Debian 12+, Arch, Fedora, etc.) * **Python**: Version 3.12 or newer * **Package Manager**: [uv](https://docs.astral.sh/uv/) (Astral's fast Python package manager) * **Node.js**: Version 20.19+ (required only when building the Web UI or Documentation) * **Docker**: Version 24+ with Compose v2 (optional for core unit tests; required for container inspection) *** ## Local Setup [#local-setup] ```bash # 1. Clone repository git clone https://github.com/HazemHassine/Arbiter.git cd Arbiter # 2. Synchronize Python environment with all extras uv sync --all-extras # 3. Create local configuration file cp .env.example .env # 4. Start local development server uv run arbiter serve ``` *** ## Running Test Suites [#running-test-suites] Arbiter maintains an extensive automated test suite covering unit tests, property-based testing, and API integration tests: ### 1. Fast Unit & API Tests [#1-fast-unit--api-tests] ```bash # Run all unit tests uv run pytest # Run specific API test suite uv run pytest tests/api/ # Run CLI ergonomics tests uv run pytest tests/cli/ ``` ### 2. Property-Based Testing (`hypothesis`) [#2-property-based-testing-hypothesis] Arbiter uses [Hypothesis](https://hypothesis.readthedocs.io/) to verify port allocation and conflict resolution algorithms under arbitrary inputs: ```bash uv run pytest tests/test_port_allocator_properties.py ``` ### 3. Live Docker Integration Tests [#3-live-docker-integration-tests] ```bash # Runs against local Docker daemon uv run pytest tests/test_docker_live.py ``` *** ## Code Quality & Linting [#code-quality--linting] Arbiter uses [Ruff](https://docs.astral.sh/ruff/) for high-speed linting and code formatting: ```bash # Check for lint violations uv run ruff check . # Automatically fix lint issues and format code uv run ruff check --fix . uv run ruff format . ``` *** ## Building the Web Control Panel (`ui/`) [#building-the-web-control-panel-ui] The web control panel is built using Next.js and exported statically so that FastAPI can serve it directly from `src/arbiter/ui/out` without requiring a Node.js runtime in production. ```bash # Install UI dependencies cd ui npm install # Start local UI dev server with hot reload (proxies to FastAPI on 8765) npm run dev # Build and export static bundle for FastAPI npm run build ``` *** ## Building Documentation (`docs/`) [#building-documentation-docs] The documentation site is built with Fumadocs and Next.js: ```bash # Run docs development server npm --prefix docs run dev # Typecheck and validate docs MDX routes npm --prefix docs run types:check # Production build of docs site npm --prefix docs run build ``` # Docker & Compose Orchestration (/docs/docker-and-compose) # Docker & Compose Orchestration [#docker--compose-orchestration] Arbiter provides a typed, safety-first control layer over the local Docker daemon and Docker Compose projects. Rather than issuing unvalidated `docker` shell commands, Arbiter uses typed Docker SDK calls and structured Compose file editors with automatic syntax validation and rollback guarantees. *** ## Container Lifecycle & Observability [#container-lifecycle--observability] ### 1. Enriched Container Inspection [#1-enriched-container-inspection] Arbiter automatically correlates low-level Docker containers with high-level workspace metadata: * **Compose Metadata**: Inferred project name (`com.docker.compose.project`), service name (`com.docker.compose.service`), and working directory. * **Port Forwards**: Maps published container ports (`0.0.0.0:8080->80/tcp`) to host listeners and verified process owners. * **Health Checks**: Real-time status (`healthy`, `unhealthy`, `starting`, `none`). ### 2. On-Demand Container Logs & Metrics [#2-on-demand-container-logs--metrics] To minimize system overhead, Arbiter streams container logs and resource metrics strictly **on demand**: * **Logs Tailing**: Fetch bounded recent logs with configurable tail depth (default 200 lines). Logs are never permanently stored by Arbiter. * **One-Shot Metrics**: Query live CPU percentage, memory usage, memory limit, and network I/O stats for any container. ```bash # View recent logs from CLI arbiter logs web-service-1 --tail 100 # Query container stats via REST curl http://127.0.0.1:8765/api/v1/containers/web-service-1/stats ``` *** ## Compose Service Port Remapping [#compose-service-port-remapping] When port collisions occur between local services, Arbiter can safely rewrite Compose port bindings: ```text ┌────────────────────────────────────────────────────────┐ │ 1. Backup original compose.yaml / .env │ ├────────────────────────────────────────────────────────┤ │ 2. Rewrite host port binding in YAML/env │ ├────────────────────────────────────────────────────────┤ │ 3. Validate Compose file syntax with `compose config` │ ├────────────────────────────────────────────────────────┤ │ 4. Recreate only the affected service container │ ├────────────────────────────────────────────────────────┤ │ 5. Verify new host port has listener socket │ │ (If step 3, 4, or 5 fails: restore backup) │ └────────────────────────────────────────────────────────┘ ``` ### Safety & Compensation [#safety--compensation] If service recreation fails or the new port fails post-action verification, Arbiter immediately restores the timestamped backup (`.bak.`) and raises an error, ensuring your repository is never left in a broken state. *** ## Docker Resources & Disk Usage [#docker-resources--disk-usage] ### 1. Disk Usage Analytics [#1-disk-usage-analytics] Monitor local Docker resource consumption: ```bash arbiter disk ``` Returns total size, active count, and reclaimable space across images, containers, local volumes, and build cache. ### 2. Volume & Image Safety Policies [#2-volume--image-safety-policies] * **Image Removal (`image.remove`)**: Classified as `HIGH_RISK`. Requires explicit approval. * **Volume Removal (`volume.remove`)**: Classified as `DESTRUCTIVE`. Permanent data deletion is never auto-approved under any configuration. # Config Editor, Make & Dockerfile Intelligence (/docs/files-and-make) # Config Editor, Make & Dockerfile Intelligence [#config-editor-make--dockerfile-intelligence] Arbiter provides targeted tools for inspecting and safely modifying local repository configuration files without exposing generic, unbounded filesystem read/write access. *** ## Scoped Configuration File Editor [#scoped-configuration-file-editor] The Arbiter file editor is strictly restricted to recognized configuration files located inside explicitly registered project boundaries. ### Supported Configuration Files [#supported-configuration-files] * Environment definitions: `.env`, `.env.local`, `.env.development`, `.env.example`, `.env.template`, `.env.dist` * Docker Compose definitions: `compose.yaml`, `compose.yml`, `docker-compose.yaml`, `docker-compose.yml`, `compose.override.yaml` * Build files: `Makefile`, `Dockerfile`, `Dockerfile.*` ### Safety & Concurrency Guarantees [#safety--concurrency-guarantees] 1. **Path Traversal Protection**: Paths containing `..` or pointing outside registered project directories are rejected immediately. 2. **Optimistic Concurrency Control (SHA-256 Pre-Check)**: To avoid overwriting concurrent edits, save requests require an `expected_sha256` hash of the file. If the file on disk has changed since it was loaded in the editor, the save is aborted with a conflict error. 3. **Automatic Timestamped Backups**: Before applying any edit, Arbiter writes an exact copy to `.bak.`. 4. **One-Click Undo API**: Operators can roll back the latest managed edit at any time via `POST /api/v1/projects/{id}/files/undo`. ```bash # Preview file edit diff with secret masking curl -X POST http://127.0.0.1:8765/api/v1/projects/my-project/files/preview \ -H 'Content-Type: application/json' \ -d '{ "path": "compose.yaml", "content": "services:\n web:\n ports:\n - \"3001:80\"\n", "expected_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" }' ``` *** ## Makefile Intelligence & Target Runner [#makefile-intelligence--target-runner] Arbiter parses project Makefiles using static AST extraction rather than executing arbitrary shell targets: * **Target Discovery**: Lists all declared targets, comments, and prerequisite dependencies. * **Risk Inference**: Evaluates target commands to assign safety risk tiers (e.g. `make test` vs `make clean` vs `make deploy`). * **Target Execution**: Running Make targets generates typed `ActionSpec` proposals with execution timeouts and captured output logs. ```bash # List Make targets for a project via REST curl http://127.0.0.1:8765/api/v1/projects/my-project/make/targets # Inspect a specific target curl http://127.0.0.1:8765/api/v1/projects/my-project/make/targets/build ``` *** ## Dockerfile Heuristic Inspection [#dockerfile-heuristic-inspection] Arbiter inspects Dockerfiles in registered projects to provide instant static diagnostics: * **Base Images (`FROM`)**: Detects base image repositories, tags, and multi-stage build stages. * **Exposed Ports (`EXPOSE`)**: Identifies declared container listening ports to cross-reference with Compose port mappings. * **Entrypoints & Commands (`ENTRYPOINT`, `CMD`)**: Parses executable commands and default arguments. * **Potential Issues**: Flags missing expose declarations or outdated base image tags. ```bash # Inspect project Dockerfiles curl http://127.0.0.1:8765/api/v1/projects/my-project/dockerfiles ``` # Introduction (/docs) # Arbiter [#arbiter] **Arbiter** is a local-first Linux control plane for understanding, diagnosing, and safely operating local development projects, Docker/Compose resources, host processes, ports, files, and multi-service environments. It strictly adheres to an **observe → diagnose → propose → approve → act → verify** workflow and binds its REST API to `127.0.0.1` by default. *** ## Quick Start [#quick-start] ```bash # 1. Setup environment and install dependencies cp .env.example .env uv sync --all-extras # 2. Start the Arbiter daemon uv run arbiter serve # 3. Verify health and port listeners curl http://127.0.0.1:8765/health curl http://127.0.0.1:8765/api/v1/ports ``` Open [http://127.0.0.1:8765](http://127.0.0.1:8765) to access the **Web Control Panel**. *** ## Interfaces & Integrations [#interfaces--integrations] Arbiter provides consistent, safety-backed operational capabilities across multiple interfaces: | Interface / Protocol | Command / Entrypoint | Description | | :------------------------- | :----------------------------- | :---------------------------------------------------------------------------------------- | | **Web Control Panel** | `http://127.0.0.1:8765` | Interactive topology canvas, observability, container logs/metrics, approvals, and admin. | | **Terminal UI (TUI)** | `arbiter tui` | Fast, keyboard-driven terminal dashboard (like lazydocker/k9s) with vim navigation. | | **CLI & Fuzzy Pickers** | `arbiter ` | `fzf`-style interactive selectors for projects, ports, containers, and approvals. | | **Shell Prompt Hook** | `arbiter prompt` | Status pills in `zsh`, `bash`, `fish`, or Starship prompts. | | **Model Context Protocol** | `arbiter mcp` | Native stdio MCP server for Claude Desktop, Cursor, Zed, and Antigravity. | | **Agent-to-Agent (A2A)** | `/.well-known/agent-card.json` | Inter-agent discovery and task delegation protocol. | | **REST & Event APIs** | `/api/v1/*` | Standard REST endpoints, SSE activity stream, and NDJSON streaming agent query. | *** ## Core Capabilities [#core-capabilities] * **Live Machine Topology**: Real-time relational graph linking projects, Compose files/services, containers, images, volumes, networks, ports, host processes, Dockerfiles, and Make targets. * **Port Conflict Reconciliation**: Deterministic port collision detection and automatic free-port reassignment across `.env` and `compose.yaml` with backup and rollback. * **Multi-Project Stacks**: Named environment profiles with 1-click context switching, topological DAG boot ordering (Kahn's algorithm), and multi-probe readiness gates (`tcp_port`, `http_get`, `docker_health`). * **Config & Secrets Intelligence**: Proactive detection of port drift and missing `.env` variables compared to `.env.example`, with zero raw secret exposure and time-travel visual diffs. * **Safety Engine**: 5-tier risk classification (`READ_ONLY` to `DESTRUCTIVE`), immutable serialized approval payloads, and independent post-action verification. *** ## Documentation Navigation [#documentation-navigation] * **Concepts**: * [Architecture & Safety](/docs/architecture) — System domains and design principles. * [Safety & Verification](/docs/safety-and-verification) — Risk tiers, approval engine, and rollback compensations. * [Topology Graph](/docs/topology) — Real-time machine graph and correlation engine. * **Features**: * [Multi-Project Stacks](/docs/stacks) — Stacks, DAG boot plans, and readiness gates. * [Config & Secrets Intelligence](/docs/config-secrets-intelligence) — Port drift and credential audits. * [Docker & Compose](/docs/docker-and-compose) — Container lifecycles, logs, stats, and port editing. * [Config Editor & Make](/docs/files-and-make) — Safe file editing, Make targets, and Dockerfile diagnostics. * **Interfaces**: * [Web Control Panel](/docs/ui) — Browser console walkthrough and observability tools. * [CLI & Shell Ergonomics](/docs/cli) — CLI commands, pickers, and Starship prompt setup. * [Terminal UI (TUI)](/docs/tui) — Full-screen terminal dashboard and keybindings. * **Protocols & Integrations**: * [Model Context Protocol (MCP)](/docs/mcp) — Connecting Claude, Cursor, and Zed via stdio MCP. * [Agent-to-Agent (A2A)](/docs/a2a) — Agent Card specification and task delegation. * [AI Agent & Tool Runtime](/docs/agent-runtime) — LangGraph agent, tool loop, and NDJSON streaming. * **Reference & Development**: * [Configuration Reference](/docs/configuration) — Complete `.env` settings table. * [REST API Reference](/docs/api) — Exhaustive REST endpoints and SSE/NDJSON reference. * [Development Guide](/docs/development) — Contributing, testing (`pytest`/`hypothesis`), and building. # Model Context Protocol (MCP) (/docs/mcp) # Model Context Protocol (MCP) Integration [#model-context-protocol-mcp-integration] Arbiter implements a native [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) stdio server. This exposes Arbiter's local-first observation, topology, port reconciliation, Docker diagnostics, and multi-project stack readiness inspection directly to AI assistants like **Claude Desktop**, **Cursor**, **Zed**, and **Antigravity**. ```text ┌────────────────────────────────────────────────────────┐ │ AI Clients (Claude Desktop / Cursor / Zed) │ └───────────────────────────┬────────────────────────────┘ │ stdio (JSON-RPC) ┌───────────────────────────▼────────────────────────────┐ │ arbiter mcp adapter │ ├────────────────────────────────────────────────────────┤ │ Shared Arbiter Domain Services │ │ (Ports, Topology, Projects, Docker, Stacks, Safety) │ └────────────────────────────────────────────────────────┘ ``` *** ## Prerequisites & Installation [#prerequisites--installation] The MCP adapter is an optional extra to keep core Arbiter minimal. Install Arbiter with the `mcp` extra: ```bash # Using uv (recommended) uv sync --extra mcp # Or if installing via pip pip install "arbiter[mcp]" ``` Verify that the CLI command is available: ```bash uv run arbiter mcp --help ``` *** ## Starting the Server [#starting-the-server] The server communicates over standard input/output (`stdio`) using the MCP JSON-RPC protocol: ```bash # Start the stdio MCP server uv run arbiter mcp ``` When invoked by an MCP client, the adapter automatically bootstraps the shared Arbiter service container, connects to the local SQLite database (`DATABASE_URL`), and dynamically queries `/proc`, Linux `ss`, and Docker without running any separate web daemon. *** ## Client Configuration [#client-configuration] ### 1. Claude Desktop [#1-claude-desktop] Add the Arbiter MCP server to your Claude Desktop configuration file: * **Linux**: `~/.config/Claude/claude_desktop_config.json` * **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json` * **Windows**: `%APPDATA%\Claude\claude_desktop_config.json` ```json { "mcpServers": { "arbiter": { "command": "uv", "args": [ "--directory", "/absolute/path/to/dev-environment-agent", "run", "arbiter", "mcp" ], "env": { "PROJECT_ROOTS": "/home/user/dev", "DEFAULT_PORT_SEARCH_RANGE_START": "3000", "DEFAULT_PORT_SEARCH_RANGE_END": "9999" } } } } ``` *** ### 2. Cursor IDE [#2-cursor-ide] In Cursor, add Arbiter under **Settings → Features → MCP**: * **Name**: `arbiter` * **Type**: `command` * **Command**: `uv --directory /path/to/dev-environment-agent run arbiter mcp` Or configure `.cursor/mcp.json` in your workspace: ```json { "mcpServers": { "arbiter": { "command": "uv", "args": ["run", "arbiter", "mcp"] } } } ``` *** ### 3. Zed Editor [#3-zed-editor] Add the server to your Zed configuration (`~/.config/zed/settings.json`): ```json { "experimental": { "model_context_protocol": { "arbiter": { "command": "uv", "args": [ "--directory", "/path/to/dev-environment-agent", "run", "arbiter", "mcp" ] } } } } ``` *** ## Complete MCP Tool Catalog [#complete-mcp-tool-catalog] The Arbiter MCP adapter exposes **13 typed tools** spanning ports, containers, projects, topology, and stack readiness. All tools operate within strict read-only observation or propose-only safety semantics. ### Port Management Tools [#port-management-tools] #### `ports_list` [#ports_list] Lists all active TCP listening ports, correlated with host processes (PIDs, binary names, command lines) and Docker container/Compose service bindings. * **Arguments**: None * **Returns**: Array of port listener objects: ```json [ { "port": 5432, "protocol": "tcp", "bind_address": "0.0.0.0", "pid": 12345, "process_name": "postgres", "cmdline": "postgres -D /var/lib/postgresql/data", "docker_container_id": "a1b2c3d4", "docker_container_name": "db-postgres-1", "compose_project": "backend", "compose_service": "db" } ] ``` #### `ports_find_owner` [#ports_find_owner] Identifies the process or Docker container currently bound to a specific host port. * **Arguments**: * `port` (`integer`, required): The port number to inspect (e.g. `5432`). * **Returns**: Port owner object if bound, or `{"port": 5432, "available": true}` if free. #### `ports_find_free` [#ports_find_free] Finds a deterministic, unbound host port at or above the specified preferred port. * **Arguments**: * `preferred_port` (`integer`, required): Starting port preference (e.g. `3000`). * **Returns**: Integer port number guaranteed to be unbound on loopback and 0.0.0.0 (e.g. `3001`). #### `ports_detect_conflicts` [#ports_detect_conflicts] Scans all registered projects, Compose definitions, and active runtime sockets to detect duplicate port claims and active collisions. * **Arguments**: None * **Returns**: Array of conflict objects containing colliding services, port numbers, and owner details. *** ### Project & Reconciliation Tools [#project--reconciliation-tools] #### `projects_list` [#projects_list] Lists all explicitly registered development projects along with their detected Compose files, services, Dockerfiles, and declared ports. * **Arguments**: None * **Returns**: Array of project summaries including ID, name, path, compose files, and declared ports. #### `arbiter_prepare_project` [#arbiter_prepare_project] Performs an end-to-end inspection of a project, diagnoses collisions, proposes deterministic port reassignments, and generates a persisted safety approval. * **Arguments**: * `identifier` (`string`, required): Project name or UUID (e.g. `"billing-service"`). * **Returns**: Summary of detected conflicts, proposed `.env`/`compose.yaml` changes, and the resulting `approval_id`. #### `project_reconciliation_plan` [#project_reconciliation_plan] Generates a deterministic, read-only dry-run plan showing exactly which port bindings or `.env` variables would be remapped to resolve conflicts without applying any mutations. * **Arguments**: * `identifier` (`string`, required): Project name or UUID. * **Returns**: Structured reconciliation plan with current vs. suggested port mappings and affected services. *** ### Docker & Host Process Tools [#docker--host-process-tools] #### `docker_list_containers` [#docker_list_containers] Lists all local Docker containers enriched with Compose metadata, health status, published ports, image tags, and uptime. * **Arguments**: None * **Returns**: Array of container models with state, compose project/service labels, and port forwards. #### `processes_list` [#processes_list] Lists host processes with listening port evidence, working directories, and project correlation. * **Arguments**: None * **Returns**: Array of process objects with PID, process name, command line, listening ports, and detected project path. *** ### Topology & Machine Graph Tools [#topology--machine-graph-tools] #### `topology_get` [#topology_get] Retrieves the complete, freshly evaluated workstation topology graph linking projects, services, containers, networks, volumes, ports, Dockerfiles, and Make targets. * **Arguments**: None * **Returns**: Typed graph object with nodes and directional edges representing system relationships. #### `resource_inspect` [#resource_inspect] Inspects a specific topology resource and returns all directly connected upstream and downstream resources. * **Arguments**: * `resource_type` (`string`, required): One of `"project"`, `"container"`, `"port"`, `"process"`, `"service"`, `"image"`, `"volume"`, `"network"`, `"dockerfile"`, `"make_target"`. * `resource_id` (`string`, required): Unique identifier or path of the target resource. * **Returns**: Detailed node attributes and linked neighbors. *** ### Multi-Project Stacks & Readiness Tools [#multi-project-stacks--readiness-tools] #### `stack_readiness_check` [#stack_readiness_check] Probes all readiness gates (TCP sockets, HTTP endpoints, Docker container health) for a multi-project stack preset under Arbiter's strict destination safety policy. * **Arguments**: * `identifier` (`string`, required): Stack preset name or UUID (e.g. `"Billing Microservices"`). * **Returns**: Array of probe results with gate status (`allowed`, `approval_required`, `blocked`), probe type, target URL/port, and measured latency in milliseconds. #### `stack_readiness_request_access` [#stack_readiness_request_access] Creates pending safety approvals for any non-local or external network destinations defined in a stack's readiness gates. * **Arguments**: * `identifier` (`string`, required): Stack preset name or UUID. * **Returns**: Array of created approval objects scoped to protocol, host, port, and resolved IP addresses. #### `readiness_authorizations_list` [#readiness_authorizations_list] Lists all currently active, persisted operator grants for external readiness probes. * **Arguments**: None * **Returns**: Array of authorized grants with target key, protocol, host, port, and creation timestamp. *** ## Safety & Security Guarantees in MCP [#safety--security-guarantees-in-mcp] When AI models interact with Arbiter via MCP: 1. **Read-Only by Default**: Inspection tools (`ports_list`, `topology_get`, `docker_list_containers`, etc.) execute immediately without mutating any files or containers. 2. **Propose-Only for Mutations**: Any operation that changes state (such as `arbiter_prepare_project` or `stack_readiness_request_access`) does not mutate files directly; it creates an **immutable approval record** in the SQLite database. 3. **Operator Verification**: The developer must review the proposed visual diff and explicitly approve the change via the CLI (`arbiter approve `), TUI (`a` key), or Web UI (`http://127.0.0.1:8765/#approvals`). 4. **Credential Redaction**: Environment variables containing sensitive keywords (`PASSWORD`, `TOKEN`, `KEY`, `SECRET`) are masked automatically before being returned over MCP. # Safety, Approvals & Verification (/docs/safety-and-verification) # Safety, Approvals & Verification Engine [#safety-approvals--verification-engine] Arbiter is designed around a single core principle: **an AI agent or automation engine should never perform destructive or mutating operations on a developer's machine without explicit, verifiable human oversight**. It operates strictly on an **observe → diagnose → propose → approve → act → verify** loop. ```text ┌─────────────┐ ┌──────────────┐ ┌─────────────┐ │ 1. Observe ├─────►│ 2. Diagnose ├─────►│ 3. Propose │ └─────────────┘ └──────────────┘ └──────┬──────┘ │ (ActionSpec) ┌─────────────┐ ┌──────────────┐ ┌──────▼──────┐ │ 6. Verify │◄─────┤ 5. Act │◄─────┤ 4. Approve │ │ (Rollback │ │ (Execute) │ │ (Operator) │ │ on failure)│ └──────────────┘ └─────────────┘ └─────────────┘ ``` *** ## The 5 Risk Levels [#the-5-risk-levels] Every action in Arbiter is classified into one of five explicit risk tiers: | Risk Tier | Meaning | Operations | Default Behavior | | :------------ | :------------------------------------- | :------------------------------------------------------------------------------ | :----------------------------------------------------------- | | `READ_ONLY` | Read-only inspection and diagnosis | Listing ports, inspecting topology, container logs, reading file previews | **Auto-Approved** (`AUTO_APPROVE_READ_ONLY=true`) | | `LOW_RISK` | Lightweight, easily reversible actions | Starting stopped containers, stopping non-critical containers | **Approval Required** (Can set `AUTO_APPROVE_LOW_RISK=true`) | | `MEDIUM_RISK` | Configuration edits, service restarts | Modifying `.env` or `compose.yaml`, restarting Compose services, stack switches | **Always Requires Approval** | | `HIGH_RISK` | Resource deletion, image cleanup | Removing Docker images, pruning networks | **Always Requires Approval** | | `DESTRUCTIVE` | Irreversible persistent data loss | Deleting Docker volumes, wiping project databases | **Always Explicit Approval** | *** ## Immutable Approval Objects [#immutable-approval-objects] When an action requires approval, Arbiter does not execute it. Instead, it creates a persisted approval record in SQLite: ```json { "id": "appr_7f3b89a2-4c6e-41d8-9e5a-38b9c2419f01", "request_id": "req_88192a40", "action": "compose.change_port", "summary": "Change web-service/web host port from 3000 to 3001", "risk": "MEDIUM_RISK", "arguments": { "project_id": "proj_11928a", "service": "web", "old_port": 3000, "new_port": 3001 }, "status": "pending", "expires_at": "2026-09-01T02:30:00Z" } ``` ### Safety Guarantees [#safety-guarantees] 1. **Payload Immutability**: The agent cannot change or substitute arguments after generating an approval request. Execution runs *strictly* the serialized JSON stored in the database. 2. **One-Time Execution**: An approval cannot be executed more than once. Expired, rejected, or completed approvals are rejected immediately upon subsequent execution attempts. 3. **Port Reservations**: As soon as an approval involving port changes is staged, Arbiter temporarily reserves the target port (`new_port: 3001`) in memory to prevent other processes or stack boots from claiming it in a race condition. *** ## Visual Diffs & Dry-Run Time Travel [#visual-diffs--dry-run-time-travel] Every approval request for file edits or port reconciliations is accompanied by a **Time-Travel Dry Run Preview**: * **Unified File Diff**: Shows line-by-line additions and deletions with automatic secret masking. * **Resource State Transitions**: Forecasts which containers will be recreated, which ports will be released, and which services will be updated. ```diff --- compose.yaml (Current) +++ compose.yaml (Proposed) @@ -12,3 +12,3 @@ ports: - - "3000:80" + - "3001:80" ``` *** ## Verification & Automatic Compensation Rollback [#verification--automatic-compensation-rollback] Execution success and verification success are strictly decoupled. An action is only marked `completed` if post-action verification checks succeed. ### Verification Matrix [#verification-matrix] * **Port Reassignment**: Arbiter validates that the Compose file is syntactically valid, starts the recreated container, and inspects Linux socket tables to confirm the expected process owns the new port. * **File Updates**: Arbiter verifies that the target file exists, matches the SHA-256 hash, and that syntax validators pass. * **Stack Switches**: Arbiter probes each stage's readiness gates (`tcp_port`, `http_get`, `docker_health`) before proceeding to downstream dependencies. ### Automatic Compensation & Rollback [#automatic-compensation--rollback] If any step of a port reconciliation or file edit fails (e.g. `docker compose up` crashes due to invalid syntax): 1. Arbiter immediately restores the original file from an automatic backup (`.bak.`). 2. Arbiter attempts to restore the original container state. 3. The action result is marked `verification_failed`, recording full error diagnostics in the audit log. *** ## Network Destination Safety Policy [#network-destination-safety-policy] To prevent Server-Side Request Forgery (SSRF) and DNS rebinding attacks when probing external stack readiness gates: 1. **Loopback & Compose Services**: Localhost (`127.0.0.1`, `::1`) and registered Docker Compose service names are probed automatically. 2. **External Non-Local Targets**: Any external hostname or IP returns `approval_required` until the developer explicitly approves an authorization grant scoped to protocol, host, port, and resolved IP addresses. 3. **DNS Rebinding Prevention**: Arbiter resolves the hostname before connecting and binds directly to the validated IP address. 4. **Hard Denials**: Link-local addresses (`169.254.0.0/16`), cloud metadata services (`http://169.254.169.254`), multicast, and broadcast addresses are unconditionally blocked. # Multi-Project Stacks & Environment Switcher (/docs/stacks) # Multi-Project Stack Presets & Environment Switcher [#multi-project-stack-presets--environment-switcher] Developers rarely work on just one isolated repository; they switch between distinct multi-service environments throughout the day (e.g. *Billing Microservices*, *AI Pipeline + Vector DB*, or *Frontend App + Mock API*). Arbiter provides a **Multi-Project Stack Preset & Environment Switcher** subsystem that groups related projects into operational profiles, performs seamless 1-click context switching with dynamic `.env` port binding, and enforces topological boot ordering with live dependency readiness gates. *** ## Key Capabilities [#key-capabilities] ### 1. Multi-Project Environment Profiles [#1-multi-project-environment-profiles] Group multiple workspace repositories and Compose services into named stack profiles: * **Billing Microservices**: Payment Gateway, Webhook Handlers, Redis Queue, and Postgres Ledger. * **AI Pipeline + Vector DB**: Qdrant Vector Store, Embedding Generator Worker, and FastAPI LLM Gateway. * **Frontend App + Mock API**: Next.js / Vite Single Page Application paired with Local Mock API Server. Stack profiles are persisted in SQLite and can be created, updated, inspected, or deleted via the UI, CLI, REST API, or AI Agent. ### 2. 1-Click Context Switcher [#2-1-click-context-switcher] Switching from Stack A to Stack B executes a safe, atomic transition: 1. **Hibernate/Spin Down Previous Stack**: Automatically stops unneeded containers from the outgoing stack to free system memory, CPU, and host ports. 2. **Dynamic `.env` Overrides**: Injects stack-specific environment variables (e.g. `PORT=8001`, `DB_PORT=5432`) directly into project `.env` files with automatic timestamped backups (`.env.bak.`). 3. **Dynamic Port Collision Reconciliation**: Detects port conflicts against real listening host sockets and rewrites Compose or `.env` host port bindings to deterministic free ports before booting. 4. **Staged Boot Sequence**: Boots member projects stage-by-stage following topological dependencies. ### 3. Dependency Health Checks & Readiness Gates [#3-dependency-health-checks--readiness-gates] Instead of booting all containers concurrently and suffering race conditions (e.g. backend crashing because database isn't ready), Arbiter organizes the boot sequence into a directed acyclic graph (DAG): * **Topological Sorting**: Uses Kahn's algorithm to calculate boot stages (Stage 0: databases/queues, Stage 1: APIs, Stage 2: workers/frontends) with cycle detection. * **Multi-Probe Readiness Checks**: * `tcp_port`: Real-time socket connection test measuring connect latency in milliseconds. * `http_get`: HTTP endpoint probe verifying expected HTTP status codes (e.g. `200 OK`) and latency. * `docker_health`: Live container status inspection (`running`, `healthy`). * **Readiness Wait Loop**: Downstream boot stages wait until upstream readiness gates pass or timeout. * **Preflight Before Mutation**: A stack switch stops before changing files or services when any readiness destination is blocked or still needs access approval. * **Destination Safety Policy**: Loopback and registered Compose service targets run automatically. Other destinations return `approval_required` until an operator approves the exact protocol, hostname, port, and resolved IP set. * **Hard Blocks**: Link-local/cloud metadata, multicast, unspecified, and reserved destinations cannot be approved. Redirects are limited and every hop is validated before connecting. *** ## Browser UI [#browser-ui] The **Stacks** view in the Arbiter Control Panel (`http://127.0.0.1:8765/#stacks`) provides an interactive interface: * **Active Stack Banner**: Real-time indicator displaying the currently active environment preset. * **Stack Preset Cards**: Grid of configured stacks showing member projects, dependency links, tags, and status. * **1-Click Switch Button**: Triggers the context switch workflow with live progress updates. * **Boot Order DAG Visualizer**: Visual pipeline of boot stages, showing the exact boot sequence and dependencies. * **Live Readiness Gates**: Interactive cards for each health check with real-time status pills (`OK`, `FAIL`, `PENDING`) and measured latency in milliseconds. * **Context Switch Stepper Modal**: Step-by-step audit of stopped projects, `.env` overrides applied, port reconciliations, and readiness gate checks. * **Preset Creator Modal**: Form to define custom multi-project presets, configure environment overrides, and set readiness probes. *** ## CLI Reference [#cli-reference] The `arbiter stack` command group manages stack presets from the terminal: ```bash # List all stack presets (optionally seed standard default presets if empty) arbiter stack list --seed-defaults # Inspect a specific stack preset arbiter stack inspect "Billing Microservices" # View the computed topological boot stages and readiness gates arbiter stack boot-order "Billing Microservices" # Probe all readiness gates for a stack preset in real time arbiter stack readiness "Billing Microservices" # Create approval requests for non-local readiness destinations arbiter stack readiness "Billing Microservices" --request-access # Review or revoke persisted readiness access arbiter stack readiness-access arbiter stack readiness-access --revoke AUTHORIZATION_ID # 1-Click switch to a target stack preset arbiter stack switch "AI Pipeline + Vector DB" # Switch without waiting for readiness gates or without hibernating current stack arbiter stack switch "AI Pipeline + Vector DB" --no-wait --no-hibernate # Stop or hibernate an active stack preset arbiter stack stop "AI Pipeline + Vector DB" # Create a new custom stack preset arbiter stack create "Custom Analytics" \ --description "ClickHouse and Python dashboard" \ --projects clickhouse-db \ --projects analytics-api \ --tags analytics --tags data ``` *** ## REST API Reference [#rest-api-reference] The Stacks subsystem exposes standard REST endpoints under `/api/v1/stacks`: | Method | Endpoint | Description | | -------- | ---------------------------------------------- | -------------------------------------------- | | `GET` | `/api/v1/stacks` | List all stack presets | | `POST` | `/api/v1/stacks` | Create a new stack preset | | `POST` | `/api/v1/stacks/seed-defaults` | Seed standard environment presets | | `GET` | `/api/v1/stacks/active` | Get currently active stack | | `GET` | `/api/v1/stacks/{id}` | Inspect a stack preset by ID or name | | `PUT` | `/api/v1/stacks/{id}` | Update stack metadata, projects, or tags | | `DELETE` | `/api/v1/stacks/{id}` | Delete a stack preset | | `GET` | `/api/v1/stacks/{id}/boot-order` | Compute topological boot stages & gates | | `GET` | `/api/v1/stacks/{id}/readiness` | Check live readiness gates | | `POST` | `/api/v1/stacks/{id}/readiness/authorizations` | Request scoped approvals for non-local gates | | `GET` | `/api/v1/readiness/authorizations` | List persisted readiness grants | | `DELETE` | `/api/v1/readiness/authorizations/{id}` | Revoke a readiness grant | | `POST` | `/api/v1/stacks/{id}/switch` | Propose 1-click context switch action | | `POST` | `/api/v1/stacks/{id}/stop` | Propose stop/hibernate stack action | *** ## AI Agent Integration [#ai-agent-integration] The natural language agent can inspect, diagnose, and switch stacks directly: ```bash # Ask Arbiter about your stacks arbiter ask "What stacks are available and which one is active?" # Probe stack readiness arbiter ask "Check if all databases in the Billing Microservices stack are ready" # Switch stacks via natural language arbiter ask "Switch to the AI Pipeline stack and make sure port conflicts are resolved" ``` Agent actions route through the standard safety and approval pipeline with full audit trails. # Topology & Resource Graph (/docs/topology) # Topology & Machine Resource Graph [#topology--machine-resource-graph] Arbiter continuously synthesizes a connected, real-time **Topology Graph** of your workstation. Rather than treating Docker, processes, files, and ports as isolated data silos, Arbiter connects them into a unified, queryable relational machine graph. ```text ┌────────────────┐ declares ┌──────────────────┐ │ Project Root ├────────────────────►│ Compose File │ └───────┬────────┘ └────────┬─────────┘ │ │ defines │ contains ┌────────▼─────────┐ ▼ │ Compose Service │ ┌────────────────┐ └────────┬─────────┘ │ Dockerfile │ │ instances └────────────────┘ ┌────────▼─────────┐ │ Docker Container │ └──┬─────┬───────┬─┘ mounts / attaches │ │ │ publishes ┌──────────────────────────────────┘ │ └─────────────┐ ▼ ▼ ▼ ┌──────────────┐ ┌─────────────┐ ┌─────────────┐ │ Volume │ │ Network │ │ Host Port │ └──────────────┘ └─────────────┘ └──────┬──────┘ │ bound by ┌──────▼──────┐ │ Host Process│ │ (PID/proc) │ └─────────────┘ ``` *** ## Real-Time Correlation Sources [#real-time-correlation-sources] Arbiter queries the Linux kernel and local services without persistent caching: 1. **Linux `ss` (Socket Statistics)**: Captures exact TCP listening sockets, inode references, and bind addresses (`127.0.0.1`, `0.0.0.0`, `::`). 2. **Linux `/proc` Filesystem**: Correlates socket inodes with process IDs (`/proc//fd/*`), extracting binary names (`comm`), full command lines (`cmdline`), working directories (`cwd`), and parent PIDs. 3. **Docker Engine API**: Queries container inspection data, Compose project and service labels (`com.docker.compose.project`, `com.docker.compose.service`), port forwards, networks, volumes, and image tags. 4. **Project File Parsers**: Parses registered `compose.yaml`, `.env`, `Makefile`, and `Dockerfile` files to correlate declared intentions with live runtime states. *** ## Topology Node Types [#topology-node-types] | Node Type | Source | Attributes & Metadata | | :---------------- | :------------------ | :------------------------------------------------------------------------ | | `project` | SQLite Registry | Name, absolute path, detected services, registered timestamp. | | `compose_file` | Project Files | File path, syntax version, defined services, volumes, networks. | | `compose_service` | Compose Spec | Service name, image reference, declared environment vars, declared ports. | | `container` | Docker API | Container ID, name, status (`running`, `exited`), health, uptime. | | `image` | Docker API | Image ID, repository tags, size in bytes. | | `volume` | Docker API | Volume name, driver, mountpoint, scope. | | `network` | Docker API | Network ID, name, driver (`bridge`, `host`, `overlay`). | | `port` | Linux `ss` + Docker | Port number, protocol (`tcp`), bind address, runtime conflict status. | | `process` | Linux `/proc` | PID, PPID, executable name, command line, working directory. | | `dockerfile` | Project Files | Path, base image (`FROM`), exposed ports (`EXPOSE`), entrypoints. | | `make_target` | Project Files | Target name, prerequisite targets, inferred commands, risk tier. | *** ## Interactive Topology Canvas (Web UI) [#interactive-topology-canvas-web-ui] The browser control panel (`http://127.0.0.1:8765/#topology`) provides an interactive visualization canvas: * **Zoom & Fit Controls**: Navigate complex multi-project resource graphs with smooth pan/zoom. * **Path Tracing & Connected Focus**: Click any node (e.g. Port `5432`) to highlight all connected resources (Postgres container → Backend service → Compose file → Project root). * **Project Scoping**: Filter the canvas view to show only nodes belonging to a single registered workspace. * **Resource Inspector Drawer**: Click any resource to view its live runtime properties, open file descriptors, logs, and direct dependencies. *** ## Natural Language Topology Query Engine [#natural-language-topology-query-engine] Arbiter allows querying the topology using natural language via the REST API or Web UI: ```bash # Filter topology resources using natural language curl -X POST http://127.0.0.1:8765/api/v1/intelligence/filter \ -H 'Content-Type: application/json' \ -d '{"query": "show all containers published on port 3000 or 8080"}' ``` ### Response Filter Plan [#response-filter-plan] ```json { "query": "show all containers published on port 3000 or 8080", "plan": { "node_types": ["container", "port"], "predicates": [ {"field": "port", "operator": "in", "values": [3000, 8080]} ] }, "matching_node_ids": [ "container:a1b2c3d4e5f6", "port:3000", "port:8080" ] } ``` # Terminal UI (TUI) Mode (/docs/tui) # Terminal UI (TUI) Dashboard (`arbiter tui`) [#terminal-ui-tui-dashboard-arbiter-tui] Arbiter includes a fast, keyboard-driven **Terminal UI (TUI)** mode inspired by tools like `lazydocker` and `k9s`. It allows engineers to inspect runtime state, manage container logs, review pending approvals, and troubleshoot port conflicts without ever leaving the terminal. ```text ┌─ Arbiter v0.5.0 ──────────────────────────────────────────────┐ │ [1] Ports [2] Containers [3] Approvals [4] Projects [5] Logs [6] Readiness │ ├────────────────────────────────┬──────────────────────────────┤ │ PORT PROTO PROCESS PID │ Details: Port 5432 │ │ 5432 tcp postgres 12345 │ Process: /usr/lib/postgresql │ │ 3000 tcp node 23411 │ PID: 12345 (ppid: 1) │ │ 8080 tcp docker-pr 88921 │ Docker: db-postgres-1 │ │ 6379 tcp redis-ser 10293 │ Compose: backend / db │ │ │ Status: Active / Healthy │ ├────────────────────────────────┴──────────────────────────────┤ │ [j/k] Navigate [Tab/1..6] Tabs [a] Approve [/] Search [q] Quit │ └───────────────────────────────────────────────────────────────┘ ``` *** ## Launching the TUI [#launching-the-tui] To start the interactive full-screen dashboard: ```bash arbiter tui ``` *** ## Tabbed Views [#tabbed-views] Switch between tabs using number keys `1` through `6` or the `Tab` / `Shift+Tab` keys: ### 1. `[1] Ports` [#1-1-ports] Displays all currently listening host TCP sockets, resolved process owners, process command lines, PIDs, and Docker container mappings. Conflicts are highlighted with warning indicators. ### 2. `[2] Containers` [#2-2-containers] Lists all local Docker containers with live status (`running`, `exited`), health probe states (`healthy`, `unhealthy`), published port forwards, and Compose service labels. ### 3. `[3] Approvals` [#3-3-approvals] Lists all pending, executed, or rejected safety approval requests. Press `Enter` to inspect the full serialized argument payload and dry-run time-travel diffs, or press `a` to immediately approve and execute. ### 4. `[4] Projects` [#4-4-projects] Shows all registered repositories and their Compose files, detected services, and declared environment ports. Press `p` on any project to automatically trigger agent preparation and conflict resolution. ### 5. `[5] Logs` [#5-5-logs] Streams live, auto-refreshing logs from the currently selected Docker container with ANSI color formatting and auto-scrolling. ### 6. `[6] Readiness` [#6-6-readiness] Shows live dependency readiness gates for active stack presets. Lists granted network access authorizations and allows revoking grants with `x`. *** ## Complete Keybindings Reference [#complete-keybindings-reference] | Key | Action | Description | | :------------- | :------------------- | :-------------------------------------------------------------- | | `j` / `Down` | Move Down | Select the next item in the active table/list. | | `k` / `Up` | Move Up | Select the previous item in the active table/list. | | `g` | Jump to Top | Move cursor to the first row in the list. | | `G` | Jump to Bottom | Move cursor to the last row in the list. | | `1` .. `6` | Switch Tab | Direct jump to tab 1 (Ports) through 6 (Readiness). | | `Tab` | Next Tab | Cycle forward through tabs. | | `Shift+Tab` | Previous Tab | Cycle backward through tabs. | | `Enter` | Inspect / Drill Down | Open the full details modal or side pane for the selected item. | | `a` | Approve Action | Approve and execute the selected pending safety action. | | `p` | Prepare Project | Propose conflict reconciliation for the selected project. | | `l` | Stream Logs | Switch straight to the Logs tab for the selected container. | | `x` | Revoke Access | Revoke a selected readiness destination authorization grant. | | `r` | Force Refresh | Query the Linux kernel and Docker daemon for fresh state. | | `/` | Fuzzy Search | Open live search bar to filter entries in the active tab. | | `Esc` | Clear / Close | Close open modal, search bar, or inspect drawer. | | `?` | Help Overlay | Display an on-screen summary of all available shortcuts. | | `q` / `Ctrl+C` | Quit | Exit the TUI and restore terminal screen buffer. | # Web Control Panel & Observability (/docs/ui) # Browser Control Panel [#browser-control-panel] The control panel is available at `http://127.0.0.1:8765`. FastAPI redirects `/` to `/ui/` and serves the bundled static export directly, so production use does not require a separate Node.js server. ## Interface [#interface] Arbiter uses a flat, responsive product-console layout with light and dark themes, Radix icons, compact status indicators, and an explicit theme toggle. The sidebar can collapse on desktop and becomes a slide-out menu on smaller screens. Tables remain horizontally scrollable and card layouts collapse as the viewport narrows. All operations go through the REST API. The browser has no direct Docker or filesystem access, and it cannot bypass Arbiter's approval and verification pipeline. ## Navigation [#navigation] The sidebar groups the application into four areas: * **Workspace:** Overview, Stacks, Workspaces, and Topology. * **Runtime:** Observability, Containers, Processes, and Ports. * **Manage:** Files, Docker resources, Registry, and Ask agent. * **Safety:** Approvals, Audit log, Admin, and Settings. The top bar shows synchronization state, live status, theme controls, refresh, resource search, and a direct **Ask Arbiter** action. The command palette opens with `Cmd+K` or `Ctrl+K`. ## Workspace and Runtime [#workspace-and-runtime] ### Overview and Workspaces [#overview-and-workspaces] The overview summarizes listeners, registered projects, containers, approvals, host capacity, recent activity, active stack presets, and quick actions. Workspace views connect registered and runtime-discovered projects with their Compose services and resource evidence. ### Multi-Project Stacks & Environment Switcher [#multi-project-stacks--environment-switcher] The Stacks view (`#stacks`) manages operational environment profiles: * **Active Stack Banner**: Real-time indicator of the running stack preset. * **Stack Presets Grid**: Preset cards with project members, tags, and 1-click switcher buttons. * **Boot Order DAG Visualizer**: Shows dependency boot stages computed via Kahn's algorithm. * **Readiness Gate Cards**: Displays real-time TCP socket, HTTP endpoint, and Docker container health checks with latency metrics. * **Readiness Access Controls**: Cards distinguish offline, approval-required, and hard-blocked probes. Operators can request scoped access, review the resulting safety approval, and revoke persisted grants from the stack screen. * **Context Switch Stepper Modal**: Provides step-by-step visibility into stopped projects, dynamic `.env` override injection, port reconciliations, and readiness verification. ### Topology [#topology] The topology canvas links projects, Compose files and services, containers, images, volumes, networks, ports, host processes, Dockerfiles, and Make targets. It supports zoom and fit controls, project scoping, connected-path focus, local search, and strict natural-language filtering. ### Observability [#observability] The observability view combines the SSE activity stream with bounded container logs, one-shot metrics, filtering and pause controls, and localhost application previews. Logs and metrics are fetched on demand and are not persisted as authoritative state. ### Containers, Processes, and Ports [#containers-processes-and-ports] * Containers show state, health, image, published ports, Compose ownership, bounded logs, and metrics. Lifecycle actions create approval requests. * Processes show host runtime evidence and listening ports. * Ports support ownership search, conflict inspection, and deterministic free port suggestions. ## Management [#management] ### Files [#files] The editor is restricted to known configuration files inside explicitly registered projects. Saves show a diff, validate content, require approval when appropriate, create a backup, and support rollback and undo. ### Docker Resources [#docker-resources] Docker views cover disk usage, images, volumes, and networks. Destructive operations are proposals only; execution remains behind the safety workflow. ### Registry [#registry] Projects can be registered by explicit path or discovered below configured roots. Each project can be inspected, diagnosed, prepared for conflicts, started, stopped, restarted, or unregistered without deleting its files. ### Ask Agent [#ask-agent] Agent responses stream as GitHub-flavored Markdown alongside typed execution events for routing, model phases, tool calls, redacted arguments, evidence, and errors. The trace never exposes private model chain-of-thought. Any proposed mutation still becomes a separate approval. ## Safety and Administration [#safety-and-administration] ### Approvals and Audit Log [#approvals-and-audit-log] Pending approvals show the exact action, immutable arguments, risk level, summary, visual side-by-side diffs (with automatic secret masking), simulated runtime state transitions (time-travel previews), and expiration. Operators can reject a request or approve and execute the stored payload. The audit log keeps action and verification outcomes separate so an operation is never presented as successful when verification failed. ### Admin and Settings [#admin-and-settings] Admin surfaces rolling API latency, LLM usage, event-pipeline state, process/database health, the agent harness, and safety policy. Settings explains the active local configuration and the boundaries around remote exposure.