Turn your issue tracker into an autonomous coding pipeline.
Linear issues in โ sandboxed AI agents out โ PRs delivered.
Overview โ active issues, recent events, and run statistics
Board โ Kanban view with workflow columns |
Settings โ Tracker, provider, sandbox, and Codex admin controls |
Risoluto is a local orchestration engine that watches your project tracker for actionable issues, spins up sandboxed AI coding agents to work on each one, and delivers the results โ all without you supervising a single prompt.
You create an issue โ Risoluto picks it up โ AI agent writes code โ PR lands on GitHub
No cloud service. No SaaS. Your code stays on your machine. Risoluto runs on your local machine or a VDS you control, connecting your existing Linear project to AI-powered Codex agents running inside isolated Docker containers. It communicates with configured external services (Linear, model providers) via their APIs, but your source code and workspace data never leave your infrastructure.
flowchart LR
A["๐๏ธ Linear / GitHub<br/><sub>Issue Tracker</sub>"] -->|"poll"| B["๐ต Risoluto<br/><sub>Orchestrator</sub>"]
B -->|"create"| C["๐ Workspace<br/><sub>Per-Issue Isolation</sub>"]
B -->|"launch"| D["๐ณ Docker<br/><sub>Sandboxed Container</sub>"]
D -->|"contains"| E["๐ค Codex<br/><sub>AI Agent</sub>"]
E -->|"JSON-RPC"| B
B -->|"persist"| F["๐พ Archive<br/><sub>Attempt History</sub>"]
B -->|"serve"| G["๐ฅ๏ธ Dashboard<br/><sub>Web UI + API</sub>"]
B -->|"push"| H["๐ GitHub<br/><sub>Branches + PRs</sub>"]
B -->|"alert"| I["๐ฌ Multi-Channel<br/><sub>Slack, Webhook, Desktop</sub>"]
style A fill:#7c3aed,stroke:#6d28d9,color:#fff
style B fill:#2563eb,stroke:#1d4ed8,color:#fff
style C fill:#059669,stroke:#047857,color:#fff
style D fill:#0ea5e9,stroke:#0284c7,color:#fff
style E fill:#d97706,stroke:#b45309,color:#fff
style F fill:#6366f1,stroke:#4f46e5,color:#fff
style G fill:#dc2626,stroke:#b91c1c,color:#fff
style H fill:#1f2937,stroke:#111827,color:#fff
style I fill:#e11d48,stroke:#be123c,color:#fff
The fastest way to get running. No environment variables needed upfront โ the web-based setup wizard handles everything.
1. Clone and launch
git clone https://github.com/OmerFarukOruc/risoluto.git
cd risoluto
docker compose up --buildTip
Enable real-time Linear webhooks by starting with the tunnel profile: docker compose --profile tunnel up -d. Webhooks are the fast path; Risoluto still keeps a slower polling sweep as anti-entropy. See the Cloudflare Tunnel Guide.
2. Open the dashboard
Navigate to http://localhost:4000 โ the setup wizard starts automatically.
3. Complete the wizard (3โ5 min)
| Step | What you'll do |
|---|---|
| ๐ Protect secrets | Generates an encryption master key for credentials |
| ๐๏ธ Connect Linear | Paste your API key and select a project |
| ๐ค Add OpenAI | Choose direct API key, browser sign-in, or a proxy / compatible provider |
| ๐ Add GitHub | Paste a GitHub PAT (optional) |
4. Create an issue and watch it run
Set a Linear issue to "In Progress". Within one poll cycle (~30s), Risoluto picks it up, launches a sandboxed agent, and shows progress on the dashboard.
Tip
All credentials and configuration are stored in encrypted Docker volumes โ nothing is saved to your source tree.
๐ฆ Development Setup โ without Docker
pnpm install && pnpm run build && bash bin/build-sandbox.sh
node dist/cli/index.js --port 4000Open http://127.0.0.1:4000 โ the setup wizard guides you through credentials. No workflow file needed; all config is stored in ~/.risoluto/ via the WebUI.
Set your Codex auth before or after setup:
export OPENAI_API_KEY="sk-..." # API key path
# โ or โ
codex login # ChatGPT/Codex subscription pathFor OpenAI-compatible proxies such as CLIProxyAPI or LiteLLM, use the setup wizard's Proxy / compatible provider option. Risoluto stores the provider token as OPENAI_API_KEY and writes an explicit codex.provider block instead of silently switching the direct API-key path.
|
|
|
|
Risoluto's active roadmap is tracked in #354 โ Symphony v2 Feature Roadmap (2026 Research Reset). As of 2026-04-04, the reconciled local roadmap shows 71 open feature issues across 11 currently named bundle categories, excluding the active epic #354 and the long-range vision issue #62. The older #9 roadmap issue is preserved as historical context only.
The latest roadmap reconciliation closed already-implemented issues #254, #258, #260, #262, #275, #276, #278, #282, #286, #292, #299, #303, #307, #308, #315, #318, #319, #326, #333, #335, #346, and #375, while the remaining stronger partials were promoted from research to triage.
The newest still-open post-reset additions are #366 fanout/merge execution, #367 risoluto doctor (triage), #368 dependency graph UI, #369 per-step success criteria, and #373 the Docker Sandboxes executor backend (triage).
Note
For the reconciled roadmap summary, shipped bundle status, and the current v1.0 delivery slice, see the Roadmap and Conformance Audit.
Risoluto runs in Docker with a zero-configuration start โ or scales to a control/data plane split for advanced deployments.
docker compose up --buildAll data persists in named Docker volumes:
| Volume | Purpose |
|---|---|
risoluto-archives |
Encrypted secrets, config overlay, run archives |
risoluto-workspaces |
Cloned repositories for each issue |
codex-auth |
OpenAI Codex login tokens |
For hot upgrades, multi-host workers, or scale-out scenarios:
flowchart TD
subgraph Docker ["๐ณ Docker Compose"]
CP["๐ต Control Plane<br/><sub>:4000 โ Dashboard, polling, config</sub>"]
DP["โ๏ธ Data Plane<br/><sub>:9100 โ Agent execution</sub>"]
end
CP -->|"HTTP + SSE<br/>Bearer auth"| DP
DP -->|"Docker CLI"| CX1["๐ค Worker 1"]
DP -->|"Docker CLI"| CX2["๐ค Worker 2"]
style CP fill:#2563eb,stroke:#1d4ed8,color:#fff
style DP fill:#059669,stroke:#047857,color:#fff
style CX1 fill:#d97706,stroke:#b45309,color:#fff
style CX2 fill:#d97706,stroke:#b45309,color:#fff
Enable with DISPATCH_MODE=remote in your .env. See the Operator Guide for details.
Risoluto exposes a full JSON API at http://localhost:4000/api/v1/. Here are the key endpoints:
| Endpoint | What it does |
|---|---|
GET /api/v1/state |
Runtime snapshot โ queued, running, retrying, completed issues |
GET /api/v1/runtime |
Version, workflow path, provider summary |
GET /api/v1/events |
SSE stream of real-time orchestrator events |
GET /api/v1/models |
List available Codex models, including richer picker metadata when the host control plane is available |
GET /api/v1/codex/* |
Host-side Codex admin surface โ threads, MCP status, auth state, and interactive prompt plumbing |
POST /api/v1/:issue/abort |
Abort a running issue |
POST /api/v1/:issue/steer |
Inject steering message into a running agent |
POST /api/v1/refresh |
Trigger immediate orchestration pass |
GET /api/v1/:issue/attempts |
Archived attempts + current live attempt |
POST /api/v1/:issue/model |
Save per-issue model override |
GET /metrics |
Prometheus-format service metrics |
๐ Full API reference โ 50+ endpoints
| Method | Endpoint | Description |
|---|---|---|
GET |
/ |
Local operator dashboard |
GET |
/metrics |
Prometheus metrics |
GET |
/api/v1/runtime |
Runtime info โ version, workflow path, provider summary |
GET |
/api/v1/state |
Runtime snapshot โ queued, running, retrying, completed, workflow columns, and token totals |
POST |
/api/v1/refresh |
Trigger immediate orchestration refresh |
GET |
/api/v1/transitions |
List available Linear workflow transitions |
GET |
/api/v1/:issue_identifier |
Issue detail, recent events, archived attempts |
GET |
/api/v1/:issue_identifier/attempts |
Archived attempts + current live attempt id |
GET |
/api/v1/attempts/:attempt_id |
Archived event stream for a specific attempt |
POST |
/api/v1/:issue_identifier/model |
Save per-issue model override |
POST |
/api/v1/:issue_identifier/transition |
Transition a Linear issue to a new state |
POST |
/api/v1/:issue_identifier/abort |
Abort a running issue |
POST |
/api/v1/:issue_identifier/steer |
Inject a steering message into a running agent |
GET |
/api/v1/events |
SSE stream of real-time orchestrator events |
GET |
/api/v1/models |
List available Codex models; returns richer app-server metadata when the host control plane is available |
GET |
/api/v1/git/context |
Git repository context and configured repo routes |
GET |
/api/v1/workspaces |
Workspace inventory with disk usage |
DELETE |
/api/v1/workspaces/:workspace_key |
Remove a workspace directory |
GET |
/api/v1/openapi.json |
OpenAPI 3.0 specification |
GET |
/api/docs |
Swagger UI for interactive API exploration |
These routes are backed by a long-lived host-side codex app-server control-plane connection. They power the Codex Admin block in /settings and stay separate from the disposable Docker-backed worker sessions used for automated issue execution.
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/v1/codex/capabilities |
List detected app-server methods and notification support |
GET |
/api/v1/codex/features |
List experimental app-server features with stage metadata |
GET |
/api/v1/codex/collaboration-modes |
List available collaboration presets |
GET |
/api/v1/codex/mcp |
List MCP servers, auth state, tools, and resources |
POST |
/api/v1/codex/mcp/oauth/login |
Start MCP OAuth login for one configured server |
POST |
/api/v1/codex/mcp/reload |
Reload MCP server config from disk |
GET |
/api/v1/codex/threads |
Paginated thread history with archived/provider/source filters |
GET |
/api/v1/codex/threads/loaded |
List thread ids currently loaded in the host control plane |
GET |
/api/v1/codex/threads/:threadId |
Read a stored thread without resuming it |
POST |
/api/v1/codex/threads/:threadId/fork |
Fork a stored thread |
POST |
/api/v1/codex/threads/:threadId/name |
Rename a thread |
POST |
/api/v1/codex/threads/:threadId/archive |
Archive a thread rollout |
POST |
/api/v1/codex/threads/:threadId/unarchive |
Restore an archived thread rollout |
POST |
/api/v1/codex/threads/:threadId/unsubscribe |
Unsubscribe the host connection from a loaded thread |
GET |
/api/v1/codex/account |
Read host-side Codex auth state |
GET |
/api/v1/codex/account/rate-limits |
Read ChatGPT/Codex quota visibility |
POST |
/api/v1/codex/account/login/start |
Start API-key or browser-based Codex login |
POST |
/api/v1/codex/account/login/cancel |
Cancel a pending browser login |
POST |
/api/v1/codex/account/logout |
Clear host-side Codex auth state |
GET |
/api/v1/codex/requests/user-input |
List pending tool/requestUserInput and item/tool/requestUserInput prompts |
POST |
/api/v1/codex/requests/user-input/:requestId/respond |
Submit an operator response for a pending interactive prompt |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/v1/config |
Effective merged operator config |
GET |
/api/v1/config/overlay |
Persistent overlay values only |
PUT |
/api/v1/config/overlay |
Update overlay values |
DELETE |
/api/v1/config/overlay/:path |
Remove one overlay path |
GET |
/api/v1/secrets |
List configured secret keys |
POST |
/api/v1/secrets/:key |
Store one secret |
DELETE |
/api/v1/secrets/:key |
Delete one secret |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/v1/setup/status |
Setup wizard progress and step completion |
POST |
/api/v1/setup/reset |
Reset all configuration |
POST |
/api/v1/setup/master-key |
Initialize encryption master key |
GET |
/api/v1/setup/linear-projects |
List available Linear projects |
POST |
/api/v1/setup/linear-project |
Select a Linear project |
POST |
/api/v1/setup/openai-key |
Validate and store OpenAI API key |
POST |
/api/v1/setup/codex-auth |
Store Codex auth.json |
POST |
/api/v1/setup/pkce-auth/start |
Start browser-based PKCE login flow |
GET |
/api/v1/setup/pkce-auth/status |
Poll PKCE authorization status |
POST |
/api/v1/setup/pkce-auth/cancel |
Cancel active PKCE flow |
POST |
/api/v1/setup/github-token |
Validate and store GitHub token |
Risoluto stores all config in ~/.risoluto/ (or the directory passed via --data-dir). There is no workflow file to edit โ credentials and settings are managed through the WebUI setup wizard or the /api/v1/config/overlay API.
| Mode | How to configure | How it works |
|---|---|---|
| API Key | Paste sk-... in the setup wizard |
Forwards OPENAI_API_KEY into the container |
| Codex Login | Browser PKCE flow or upload auth.json |
Injects auth.json from the encrypted secrets store |
| Custom Provider | codex.provider overlay key |
OpenAI-compatible endpoints with base_url, headers, query params |
Note
Host-bound provider URLs like http://127.0.0.1:8317/v1 are automatically rewritten to host.docker.internal inside Docker containers.
pnpm test # Deterministic unit tests (Vitest, 2904 tests)
pnpm run test:watch # Watch mode for local iteration
pnpm run test:integration # Opt-in live integration (requires credentials)The dashboard has a full Playwright E2E suite with 119 smoke tests across 17 spec files and 4 visual regression baselines. Tests run against a Vite dev server with fully mocked API routes โ no backend needed.
pnpm exec playwright test --project=smoke # Smoke tests (119 tests, ~7s)
pnpm exec playwright test --project=visual # Visual regression (4 baselines)
pnpm exec playwright test --project=visual --update-snapshots # Regenerate baselinesFull-pipeline integration test that drives the complete Risoluto lifecycle against real Linear + GitHub APIs:
cp scripts/e2e-config.example.yaml scripts/e2e-config.yaml
# Edit scripts/e2e-config.yaml with your credentials and test project
./scripts/run-e2e.shRuns 12 phases: preflight, start, setup wizard, issue creation, agent monitoring, PR verification, restart resilience, and cleanup. Produces a structured report in e2e-reports/. See E2E Testing Guide for full setup and config reference.
Tip
The integration suite skips cleanly when required credentials are absent โ safe to run without API keys. E2E smoke tests require Playwright browsers (pnpm exec playwright install chromium). The lifecycle test requires Linear/GitHub credentials and Docker.
| Document | What you'll learn |
|---|---|
| Getting Started | First 10 minutes: install, setup wizard, first issue |
| Operator Guide | Full setup walkthrough, deployment options, Docker networking, wizard details |
| Document | What it covers |
|---|---|
| Runbooks | Troubleshooting playbooks for common failures |
| Observability | Prometheus metrics, request tracing, error tracking, alert rules |
| E2E Testing | Automated lifecycle test: setup, config, phases, diagnostics |
| Releasing | Release preparation checklist |
| Cloudflare Tunnel | Expose webhook endpoint via Cloudflare Tunnel for real-time Linear events |
| Document | What it covers |
|---|---|
| Trust & Auth | Trust boundaries, sandbox security, credential chain |
| Conformance Audit | Per-requirement spec conformance tracking |
| Roadmap | Reconciled roadmap summary aligned to epic #354 |
| Document | What it covers |
|---|---|
| EXECPLAN.md | Internal implementation log |
| Visual Verify Skill | Dashboard screenshot diffing and QA workflow |
The default operating mode is intentionally high trust and local-only.
flowchart TB
S["๐ต Risoluto<br/><sub>Decides WHEN to launch<br/>and WHICH workspace</sub>"]
C["๐ค Codex<br/><sub>Decides HOW each<br/>turn executes</sub>"]
P["๐ Provider / Proxy<br/><sub>Decides HOW the model<br/>call is routed</sub>"]
S --> C --> P
style S fill:#2563eb,stroke:#1d4ed8,color:#fff
style C fill:#d97706,stroke:#b45309,color:#fff
style P fill:#059669,stroke:#047857,color:#fff
Caution
The default posture (danger-full-access sandbox, never approval policy) is appropriate only for local, operator-controlled environments. See Trust & Auth for the full security model.
This project draws direct inspiration from OpenAI's Symphony โ a framework that turns project work into isolated, autonomous implementation runs. We loved the vision and built our own TypeScript implementation tailored for local, single-host operator use.
Note
While OpenAI's Symphony provides a spec and an Elixir reference implementation, Risoluto is an independent TypeScript implementation that follows the same core philosophy: poll tracker โ create workspaces โ launch agents โ report results.
Built with โค๏ธ โ Inspired by OpenAI Symphony


