How It Works
Risoluto is a local orchestration engine that connects your issue tracker to AI coding agents. It polls Linear, claims eligible issues, spins up isolated Docker sandboxes, runs an AI agent inside each one, and delivers the result as a GitHub pull request.Issue Lifecycle
Every issue that Risoluto processes follows the same six-stage pipeline.Polling
Risoluto polls Linear every 15 seconds (configurable via
polling.interval_ms).
Issues in active states (default: In Progress) are sorted by priority, then by age, then by identifier as a tiebreaker.Workspace Creation
Each claimed issue gets its own isolated directory under
workspace.root. Two strategies are available:| Strategy | How it works | Disk usage |
|---|---|---|
directory (default) | Full git clone per issue | Higher — full repo each time |
worktree | Git worktree from a shared bare clone | Lower — shares object store |
Sandbox Launch
Risoluto launches a Docker container for each issue with strict isolation:
- Image —
risoluto-codex:latest(Ubuntu 24.04 + Node.js 22 + Codex CLI) - Isolation — workspace bind-mounted at its original absolute path
- Permissions — runs as your UID/GID (
--user $(id -u):$(id -g)) - Resources — configurable memory (default 4 GB), CPU (default 2 cores), and tmpfs limits
- Security —
--cap-drop=ALL,--security-opt=no-new-privileges, optional egress allowlist
Agent Execution
Inside the container, the Codex agent:
- Reads the issue description as its task prompt
- Has access to the full repository in its workspace
- Executes tools (file edits, shell commands) per the configured approval policy
- Reports progress via JSON-RPC events streamed back to Risoluto
Delivery
When the agent completes successfully:
- Risoluto commits changes to a feature branch (
risoluto/<issue-id>) - Opens a GitHub pull request with the issue context
- Transitions the Linear issue to the configured success state
- Sends a Slack notification (if configured)
Architecture Overview
Lifecycle Hooks
Workspaces support lifecycle hooks at each stage, letting you run linters, install dependencies, or clean up artifacts.Concurrency & Scheduling
| Setting | Config key | Default | Description |
|---|---|---|---|
| Global limit | agent.max_concurrent_agents | 10 | Maximum simultaneous workers |
| Per-state limits | agent.max_concurrent_agents_by_state | — | e.g. {"In Progress": 5} |
| Priority sorting | — | enabled | Higher priority issues dispatch first |
| Blocked suppression | — | enabled | Issues in blocked states are skipped |
Retry & Recovery
When an agent fails, Risoluto applies exponential backoff:| Behavior | Config key | Default |
|---|---|---|
| Max retries | agent.max_continuation_attempts | 5 |
| Backoff cap | agent.max_retry_backoff_ms | 300000 (5 min) |
| OOM detection | — | Exit code 137 surfaced as container_oom |
| Stall detection | agent.stall_timeout_ms | 1200000 (20 min) |
Data Storage
All runtime state lives in a single directory (default:~/.risoluto/):
What’s Next
Runtime Behavior
Polling intervals, timeouts, retries, and the state machine.
Trust Model
Sandbox policies, credential handling, and security posture.
Configuration
Customize models, workspaces, hooks, and resource limits.
Docker Deployment
Run Risoluto as a persistent service with Docker Compose.