YARLI
What is this?
YARLI is a Rust workspace for executing plan-driven engineering workflows with durable state and explicit operator control. It treats runs, tasks, worktrees, merges, command execution, and policy decisions as state-machine entities persisted through an event log.
The primary workflow is yarli run: resolve prompt context, discover open tranches, dispatch execution tasks, and emit explainable run/task status. YARLI supports both local ephemeral development and durable Postgres-backed operation.
This project is for teams that want reproducible orchestration behavior, auditable transitions, and safe defaults around Git operations, policy checks, and runtime controls.
Features
- Config-first orchestration (
yarli.toml) with plan-driven tranche dispatch. - Durable event store and queue backends (Postgres) with in-memory mode for local testing.
- Explicit operator controls (
pause,resume,cancel,drain) and explainability commands. - Policy and gate evaluation over task/run state.
- Parallel workspace execution with scoped merge and recovery artifacts.
- Startup salvage of abandoned git-worktree run roots before parallel slot allocation.
- Optional memory provider adapters via
[memory.providers.<name>]. - REST API crate (
yarli-api) with health, status, control, webhook, and websocket event routes.
Installation
Build from source
Cargo install (local path)
Shared commithooks
This repo tracks project-local hooks in .githooks/. Building yarli-cli
refreshes the shared dispatchers and hook library into .git/hooks/ and
.git/lib/ when COMMITHOOKS_DIR or $HOME/Documents/commithooks is
available.
Install script
Docker
Quick Start
# 1) Generate config template
# 2) For local ephemeral writes, set in yarli.toml:
# [core]
# backend = "in-memory"
# allow_in_memory_writes = true
# 3) Ensure PROMPT.md exists, then run
For durable mode, configure:
[]
= "postgres"
[]
= "postgres://postgres:postgres@localhost:5432/yarli"
Then apply migrations:
Core Concepts
Prompt Resolution
yarli run resolves the prompt file in this order:
yarli run --prompt-file <path>[run].prompt_fileinyarli.toml- Fallback lookup for
PROMPT.mdby walking upward from your current directory
Relative prompt paths are resolved from repo root (.git ancestor) when available, otherwise from the config file directory. @include <path> directives are expanded (confined under the directory containing the resolved prompt file).
Default execution discovers incomplete tranches in IMPLEMENTATION_PLAN.md, dispatches each tranche as a task, then appends a verification task. If no run-spec configuration exists and no incomplete tranches are found, it dispatches the full prompt text as one task.
Minimum PROMPT.md structure:
@include IMPLEMENTATION_PLAN.md
Tranche Metadata
Optional metadata on IMPLEMENTATION_PLAN.md tranche lines:
tranche_group=<name>— group adjacent entries for dispatch togetherallowed_paths=path/a,path/b— scope constraints (requires[run].enforce_plan_tranche_allowed_paths = true)verify="cmd"— post-tranche verification command hintdone_when="criteria"— explicit completion contractmax_tokens=N— per-tranche token-budget hint
Control Terminology
- Policy gates: code-defined checks evaluated by YARLI (
yarli gate ...). - Verification command chain: plan/config/script-defined command execution (tranche + verification tasks).
- Observer mode: monitoring/reporting only; observer events never gate or mutate active run execution.
- Operator controls: explicit control-plane actions via
yarli run pause|resume|cancel|drain.
Output Modes
Global flags:
--stream: force stream output (inline, no fullscreen UI)--tui: force fullscreen dashboard UI
If --stream is requested but the current environment is not a TTY, YARLI falls back to headless mode.
CLI Reference
yarli init
Creates a documented yarli.toml template to bootstrap a workspace. This is where you initialize durability (Postgres vs ephemeral), execution backend (native vs Overwatch), budgets, policy mode, and UI mode.
yarli run
Start, monitor, and explain orchestration runs. yarli run (no subcommand) is the primary config-first, plan-driven workflow.
- Parallel mode defaults to enabled (
[features].parallel = true); requires[execution].worktree_root. - In parallel mode, YARLI prepares one workspace per task under
execution.worktree_root. - Before creating new git-worktree task slots, YARLI sweeps
execution.worktree_rootfor abandonedrun-*roots, salvages dirty worktrees onto durable branches, and reclaims empty stale roots. - On
RunCompleted, YARLI scopes each task merge to paths that actually differ, then applies a patch withgit apply --3way. - Merge conflict resolution is controlled by
[run].merge_conflict_resolution:fail(default),manual,auto-repair. - Auto-advance policy:
[run] auto_advance_policy = "improving-only" | "stable-ok" | "always"(default:stable-ok). - Task health trends (
[run.task_health.improving|stable|deteriorating]) can triggercontinue,checkpoint-now,force-pivot, orstop-and-summarize. [run].soft_token_cap_ratiotriggers checkpoint-now when total token usage reachesratio * max_run_total_tokens(default:0.9).
# Run the workspace's default prompt-defined loop.
# Override the prompt file for this invocation.
# Start an ad-hoc run with explicit commands (one task per --cmd).
# Query status (run-id can be a full UUID or unique prefix from `yarli run list`).
# Explain why the run exited (or why it is not done).
# List all runs.
# Operator controls.
# Continue from the latest persisted continuation payload.
# Legacy pace-based execution.
Plan guard (recommended for tranche/card workflows):
[]
= "CARD-R8-01"
= "implement" # "implement" (default) or "verify-only"
yarli task
Inspect tasks and clear blockers.
yarli gate
Inspect configured gates and manually re-run gate evaluation.
yarli worktree
Inspect and recover git worktree state for a run.
# action values: abort | resume | manual-block
yarli merge
Request, approve, reject, and inspect merge intents.
# strategy values: merge-no-ff | rebase-then-ff | squash-merge
yarli audit
Tail and query the JSONL audit log emitted by policy decisions, governance accounting, and command execution events.
yarli plan
Manage the structured tranches file (.yarli/tranches.toml) used by plan-driven dispatch.
yarli debug
Inspect live scheduler internals and queue/runtime telemetry.
yarli migrate
Manage Postgres migration lifecycle for durable mode.
yarli serve
Start the HTTP API server for run, task, and audit introspection.
yarli info
Print version and detected terminal capabilities.
AI Agent Integration
YARLI integrates with agent CLIs through [cli] configuration (for example codex, claude, gemini, or custom command wiring).
[]
= "codex"
= "arg"
= "codex"
= ["exec"]
YARLI is not currently an MCP server. Agent integration is command-dispatch based.
gRPC API
YARLI does not currently expose a native gRPC API. I did not find any .proto
files in this repo, and the supported network API surface today is the HTTP
server from crates/yarli-api.
REST API
Routes from crates/yarli-api/src/server.rs:
| Method | Path | Description |
|---|---|---|
| GET | /health |
Health check |
| GET | /metrics |
Prometheus metrics |
| GET | /v1/events/ws |
WebSocket event stream |
| POST | /v1/webhooks |
Register webhook |
| POST | /v1/runs |
Create run |
| GET | /v1/runs |
List runs |
| GET | /v1/runs/:run_id/status |
Run status |
| POST | /v1/runs/:run_id/pause |
Pause run |
| POST | /v1/runs/:run_id/resume |
Resume run |
| POST | /v1/runs/:run_id/cancel |
Cancel run |
| GET | /v1/tasks |
List tasks |
| GET | /v1/tasks/:task_id |
Task status |
| POST | /v1/tasks/:task_id/annotate |
Annotate task |
| POST | /v1/tasks/:task_id/unblock |
Unblock task |
| POST | /v1/tasks/:task_id/retry |
Retry task |
| GET | /v1/audit |
Audit log |
| GET | /v1/metrics/reporting |
Reporting metrics |
Debug-only routes (feature-gated: debug-api):
| Method | Path | Description |
|---|---|---|
| POST | /v1/tasks/:task_id/priority |
Override priority |
| GET | /debug/queue-depth |
Queue depth |
| GET | /debug/active-leases |
Active leases |
| GET | /debug/resource-usage/:run_id |
Resource usage |
Authentication is enabled when YARLI_API_KEYS is set. Public endpoints (/health, /metrics) bypass auth.
Configuration
yarli.toml
Main config file, generated via yarli init. Example in yarli.example.toml. Run yarli init --help for a full annotated list of every config key and its default.
Key sections:
| Section | Purpose |
|---|---|
[core] |
Backend (in-memory/postgres), safe mode, worker identity |
[postgres] |
Database URL, URL file (Kubernetes secret pattern) |
[cli] |
LLM CLI backend (codex/claude/gemini/custom), prompt mode, command, args |
[features] |
Parallel execution, git worktree mode |
[queue] |
Claim batch size, lease TTL, per-class caps |
[execution] |
Runner (native/overwatch), working dir, worktree root, timeouts |
[run] |
Prompt file, auto-advance policy, task health, merge conflict resolution, plan guard |
[budgets] |
Per-task and per-run resource limits (RSS, CPU, IO, tokens) |
[git] |
Default target branch, destructive operation deny |
[policy] |
Policy enforcement, audit toggle |
[memory] |
Provider selection and adapter config |
[observability] |
Audit file path, log level |
[ui] |
Display mode, verbose output, cancellation diagnostics |
[sw4rm] |
Agent name, capabilities, registry/router/scheduler URLs (requires --features sw4rm) |
Memory Providers
YARLI can store and query memories (short, reusable incident summaries) via provider adapters.
[]
= "default"
[]
= "cli"
= true
= "memory-backend"
= 8
= true
= true
Bootstrap per repo: memory-backend init -y
Environment Variables
| Variable | Purpose |
|---|---|
DATABASE_URL |
Postgres DSN fallback |
YARLI_LOG |
Log level (populates RUST_LOG when unset) |
YARLI_ALLOW_RECURSIVE_RUN |
Recursive-run override |
YARLI_API_KEYS |
Comma-separated API auth keys |
YARLI_API_RATE_LIMIT_PER_MINUTE |
API rate limit (default: 120) |
OTEL_EXPORTER_OTLP_ENDPOINT |
OTLP tracing exporter endpoint |
YARLI_TEST_DATABASE_URL |
Postgres URL for integration tests |
YARLI_REQUIRE_POSTGRES_TESTS |
Enable Postgres integration tests |
Architecture
+---------------------+
| yarli CLI (run/*) |
+----------+----------+
|
v
+---------------------+
| Scheduler + Queue |
| (yarli-queue) |
+----------+----------+
|
+------------------+------------------+
v v
+---------------+ +------------------+
| Command Runner| | Policy + Gates |
| (yarli-exec) | | (yarli-policy, |
+-------+-------+ | yarli-gates) |
| +--------+---------+
v |
+---------------+ |
| Git/Worktree |<----------------------------+
| (yarli-git) |
+-------+-------+
|
v
+---------------+
| Event Store |
| (in-memory or |
| Postgres) |
+-------+-------+
|
v
+---------------+
| API / Observe |
| (yarli-api) |
+---------------+
Workspace crates: yarli-core, yarli-store, yarli-queue, yarli-exec, yarli-git, yarli-gates, yarli-policy, yarli-memory, yarli-observability, yarli-sw4rm, yarli-api, yarli-cli.
Security
- Safe mode and policy enforcement are configurable (
observe,restricted,execute,breakglass). - Destructive Git operations are denied by default (
git.destructive_default_deny = true). - API authentication is enabled when
YARLI_API_KEYSis set (supportsAuthorization: Bearer,x-api-key,api-keyheaders). - API key rate limiting uses
YARLI_API_RATE_LIMIT_PER_MINUTE(default 120/min). - Durable mode is recommended for write commands; in-memory mode blocks writes unless explicitly allowed.
Examples
# Bootstrap config, then run the default plan-driven loop.
# Start an ad-hoc run with explicit commands.
# Inspect or control a live run.
# Recover interrupted worktree state.
Playbooks
Runtime Guard Response
When guard-related telemetry indicates a stop or pivot condition:
yarli run status <run-id>— inspect budget and deterioration signals.yarli run explain-exit <run-id>— inspect guard breach reasons and trend summary.yarli task explain <task-id>— inspect task-level budget, usage, and failure provenance.yarli run pause|resume|cancel|drain <run-id>— hold, stop, or finish-current-then-exit while adjusting scope.yarli run continue— continue only after guard intent has been reviewed.
Merge Conflict Recovery
When run.status or run.explain-exit show unresolved merge state:
- Inspect:
yarli run status <run-id>andyarli audit tail --category merge.apply.conflict. - Open
PARALLEL_MERGE_RECOVERY.txtin the preserved workspace root. - Follow the printed recovery steps (inspect, review patch, retry apply, resolve markers).
- Pick action based on
[run].merge_conflict_resolutionpolicy (fail,manual,auto-repair). yarli run continueafter remediation.
Troubleshooting
"write commands blocked" in in-memory mode
Either configure durable mode (core.backend = "postgres" + DATABASE_URL or [postgres].database_url) and apply migrations, or explicitly opt into ephemeral writes:
[]
= "in-memory"
= true
Secret rotation
- Mount credentials as files in a dedicated secret volume (e.g.
/run/secrets/...). - Set
postgres.database_url_fileto that mounted path inyarli.toml. - Update the secret, then restart YARLI (
kubectl rollout restart ...).
Stream requested but "headless mode"
If you run yarli run --stream in a non-interactive environment (no TTY), YARLI falls back to headless mode and still executes the run.
License
Dual licensed under MIT OR Apache-2.0.