autorize
autorize is a generic iterative-improvement harness. You point it at a project, a
scoring command, and an agent CLI, and it runs the agent in sandboxed git worktrees
against the score — keeping improvements, discarding regressions — until a deadline
fires.
It generalizes the autoresearch pattern
into a small Rust CLI you can point at any repo.
How it works
For each iteration, autorize:
- Creates a fresh git worktree off the
autorize/<name>tracking branch. - Builds a prompt from your
program.md, the boundary rules, the last 10 iteration records, and the diff of the best iteration so far. - Spawns your agent (any CLI — Claude Code, a shell script, anything)
inside the worktree with a hard wall-clock budget. On timeout the whole
process group gets
SIGTERM, thenSIGKILLafter 5 s. - Stages the agent's changes and rejects the iteration if its diff touches a
deny_pathsglob. - Runs your scoring command (raw float, regex capture, or JSONPath) and compares against the best score seen so far.
- Better? Commits onto
autorize/<name>and advances the tracking branch. Worse / no-op / denied / invalid? Discards the worktree. - Appends an
IterationRecordtoiterations.jsonland rewritesstate.jsonatomically so you canCtrl-C(or crash) at any point andautorize resumepicks up cleanly.
The loop exits when the total deadline fires, max_iterations is hit, or
max_consecutive_noops is reached.
Install
Linux only for v1.
Quickstart
# 1. Scaffold an experiment under .autorize/<name>/
# 2. Edit .autorize/myexp/config.toml and .autorize/myexp/program.md
# - point `objective.command` at your scoring script
# - point `agent.command` at your agent CLI
# - set a deadline (`total_budget = "4h"` or `deadline = "..."`)
# 3. Commit your repo (autorize refuses dirty trees by default), then run:
# 4. Check progress from another shell:
# 5. If the loop dies, restart it:
Subcommands
| Command | What it does |
|---|---|
autorize init <name> |
Scaffold .autorize/<name>/{config.toml,program.md}. |
autorize run <name> |
Run the loop until deadline / cap / noop streak. |
autorize status <name> |
One-shot summary from state.json + iterations.jsonl. |
autorize resume <name> |
Recover after a crash; any in-progress iter is recorded as killed and the loop continues. |
autorize llms |
Print an exhaustive agent-targeted markdown reference (config schema, on-disk layout, IterationRecord, state machine). |
autorize run accepts --allow-dirty if you need to start with uncommitted
changes outside .autorize/.
Config (.autorize/<name>/config.toml)
[]
= "myexp"
= "..."
[]
= "bash score.sh" # prints the score to stdout
= "min" # "min" | "max"
= { = "float" } # or { kind = "regex", pattern = "score=([0-9.]+)" }
# or { kind = "jq", path = ".metrics.loss" }
= "60s"
= "invalid" # "invalid" | "worst" | "abort"
[]
= ["src/**/*.py"] # prompt-only in v1
= [".autorize/**"] # ENFORCED via diff
[] { command = "", timeout = "5m" }
[] { command = "", timeout = "1m" }
[]
= "5m"
= 0 # 0 = unbounded
= false
= 5
[]
= "4h" # OR (exactly one):
# deadline = "2026-05-21T09:00:00-07:00"
[]
= "claude --print {prompt_file}" # {prompt_file}, {workdir}, {iter}
= "AUTORIZE_WORKDIR"
= "none" # "none" | "prompt"
[]
= "$ANTHROPIC_API_KEY"
program.md lives next to config.toml and is freeform instructions for the
agent — included verbatim at the top of every prompt.
On-disk layout
<repo>/
.autorize/<name>/
config.toml
program.md
state.json # atomic checkpoint of loop state
iterations.jsonl # durable append-only log
iter-0001/
prompt.md # what the agent saw
changes.diff # captured diff
agent.stdout
agent.stderr
iter-0002/
...
The tracking branch autorize/<name> records every merged iteration as a
single commit, so git log autorize/<name> is your improvement history and
git diff main..autorize/<name> is the cumulative change.
Example
See examples/pi-digits/ for an end-to-end demo where a
mock agent nudges a number in value.txt toward π:
Status
v1 is feature-complete on Linux. Out of scope for v1: parallel iterations, Pareto scoring, web/TUI, macOS, token accounting, retry/backoff, remote storage, allow-path enforcement (allow_paths is prompt-only).
License
AGPL-3.0-or-later.