Skip to main content

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:
StrategyHow it worksDisk usage
directory (default)Full git clone per issueHigher — full repo each time
worktreeGit worktree from a shared bare cloneLower — shares object store

Sandbox Launch

Risoluto launches a Docker container for each issue with strict isolation:
  • Imagerisoluto-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:
  1. Reads the issue description as its task prompt
  2. Has access to the full repository in its workspace
  3. Executes tools (file edits, shell commands) per the configured approval policy
  4. Reports progress via JSON-RPC events streamed back to Risoluto

Delivery

When the agent completes successfully:
  1. Risoluto commits changes to a feature branch (risoluto/<issue-id>)
  2. Opens a GitHub pull request with the issue context
  3. Transitions the Linear issue to the configured success state
  4. Sends a Slack notification (if configured)

Cleanup

After delivery (or on failure after exhausting retries), the workspace is cleaned up and resources released. Archived run data persists in the SQLite database for observability.

Architecture Overview

Lifecycle Hooks

Workspaces support lifecycle hooks at each stage, letting you run linters, install dependencies, or clean up artifacts.
Hooks time out after 60 seconds by default. Override with hooks.timeout_ms in your config overlay.

Concurrency & Scheduling

SettingConfig keyDefaultDescription
Global limitagent.max_concurrent_agents10Maximum simultaneous workers
Per-state limitsagent.max_concurrent_agents_by_statee.g. {"In Progress": 5}
Priority sortingenabledHigher priority issues dispatch first
Blocked suppressionenabledIssues in blocked states are skipped

Retry & Recovery

When an agent fails, Risoluto applies exponential backoff:
BehaviorConfig keyDefault
Max retriesagent.max_continuation_attempts5
Backoff capagent.max_retry_backoff_ms300000 (5 min)
OOM detectionExit code 137 surfaced as container_oom
Stall detectionagent.stall_timeout_ms1200000 (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.
Last modified on March 31, 2026