enallagi 发布单二进制编码智能体任务循环工具
thmsmtylr/enallagi
enallagi 是一个以单个静态二进制分发的自主任务循环工具,读取任务队列并逐个执行,每个任务都在全新的智能体进程中运行而非长期会话。它把工作拆给五个不能互相评分的角色,每次 done 结论都从代码树重新推导而非采信声明,每条泳道在独立 git worktree 中运行并在成功后快进。
The fractional harness that could.
An autonomous task loop for a coding agent, in one static binary.
Highlights
- Reads a queue of tasks and works them one at a time.
- Runs each task in a fresh agent process, never a long-lived session.
- Splits the work across five roles that cannot grade each other.
- Re-derives every
donefrom the tree instead of trusting a claim. - Runs each lane in its own git worktree and fast-forwards on success.
- Wraps any headless agent CLI, with thirteen presets shipped.
- Pins every vendored skill by commit and hash.
Install
curl -fsSL https://raw.githubusercontent.com/thmsmtylr/enallagi/main/install.sh | shFrom source:
cargo install --locked --git https://github.com/thmsmtylr/enallagi enallagi
Releasing is one procedure, stated in .github/workflows/release.yml.
From install to a landed task
docs/setup.md walks the same path on a real repository, step by step.
enallagi init # one pass: detects the check, asks what it cannot decide, writes and commits everything enallagi init --yes # or takes every default, as a stdin that is not a terminal does
Turn an issue into a task:
enallagi issue owner/repo#12 # appends a proposed block to .enallagi/TASKS.md; `init --issue <url>` does the sameThe block quotes the issue in notes:. The first run's adjudicator writes what done means and
sets it ready; $EDITOR .enallagi/TASKS.md does the same by hand.
Or write a task into .enallagi/TASKS.md by hand:
## [T-001] the date parser drops a timezone scope: src/date.ts, src/date.test.ts blockedBy: status: ready rows: none — harness criteria: - `npm test -- date` passes with a case for `+10:00` notes:
Run it:
enallagi run --pipeline task --iterations 1 # one task, in this checkout enallagi worktree 1 # or one task, in its own worktree enallagi watch # attach read-only to the live loop enallagi pr T-001 --push # one pull request for the landed task enallagi run --pr-per-task --iterations 3 # or one pull request per task, opened as each lands
--pr-per-task stacks a task on the branch of a blocker landed earlier in the same run.
How a run works
Each iteration takes the first ready task whose blockers are done.
- The implementer edits only the paths on the task's
scope:line. - It commits, writes its notes, and sets the task to
review. - The verifier reads the criteria and returns
doneor a rejection. - Gates then re-run behind that verdict and can overturn it.
A done the gates disagree with goes back to ready. A question the criteria do not answer
becomes needs-spec and halts the run.
enallagi run --pipeline task runs only the pipeline named. Repeat the flag to name more than one.
With none named, every pipeline in .enallagi/enallagi.toml is eligible.
The pipeline, gate, probe, key and file tables are in docs/reference.md. Changing a skill, a pipeline or a stage is in docs/pipeline.md.
Configuration
.enallagi/enallagi.toml holds the whole configuration.
Every key and its default is in docs/configuration.md.
enallagi init writes only the keys whose value differs from the embedded defaults.
A key left out takes its default.
A re-run names every key that still equals one.
enallagi init --prune-defaults deletes those keys.
A first enallagi init also detects the test runner from the files the repository already carries.
Seven runners ship: cargo, node, bun, vitest, jest, pytest and go.
Detection writes check.command, check.fail_name and the layout test keys.
Each detected value is printed with the file:line it came from.
A tree that matches more than one runner keeps the defaults and names the candidates.
A tree that matches none has the agent propose a check, written only once the check proves it.
agent.presetnames the CLI to drive, orcustomwith your ownagent.command.agent.modelandagent.effortset defaults. A role or a task can override both.- A
claudelane runs sandboxed with edits accepted, so it needs no bypass flag. See docs/configuration.md. agent.dangerously_skip_permissionsadds the preset's bypass flag to every lane. Defaultfalse.enallagi run --dangerously-skip-permissionsdoes the same for one run. A preset that declares no bypass flag refuses the run.run.startrecords the choice aspermissions_skipped, andenallagi eventsprints it.check.commandis the single command that decides green.[[skill]]declares a skill to vendor, with itsrevand the gate that enforces it.
Budgets come from the environment. Set BUDGET_USD, BUDGET_SECONDS, or BUDGET_TOKENS.
BUDGET_TOKENS counts every token lane [agent.usage] names, cached reads and cache writes included.
Commands
initinstalls into a repository.ejectremoves it and keeps the record outside it. Both commit one change to the product's.gitignore: init adds/.enallagi/, and eject removes it.rundrives the pipelines in place.worktreedrives them in an isolated checkout.runprints its version and build commit first, andbinary predates HEADwhen HEAD descends from that commit.watchattaches to a live loop.eventsqueries the log. Each event carriessha, the product HEAD, andrun.startcarriesbinary.events --summaryprints one row per task: stages, verify rounds, rejections, overturned verdicts, seconds, cost and token lanes.tasksreads and edits the queue.baseprints the commit a task was queued against.tasks landedlists each done task, its commits, andno branch,built <branch>orpushed <url>.--builtkeeps the branches waiting on a push.issueappends a GitHub issue, andreviewa pull request's review comments, asproposedtasks.probereports findings.gateruns one gate.hookis the agent's lifecycle entry point.auditproposes a learning for each class of finding that recurs.skillsresolves declared skills.evalruns the evals.prbuilds a pull request. It builds a task whose commits conflict with the default branch on the newesttask/<id>branch, built this run or on the remote, that changed a conflicting file and takes the commits, and its description names that task. AblockedBy:task whose branch is on the remote is a base the same way. When no branch takes the commits, the refusal names the conflicting files.
enallagi pr --push reads the target's contribution guide first.
A sentence there that refuses or conditions generated changes stops the push.
Pass --policy-read once you have read it. enallagi pr records either outcome in the description file, and commits it under <harness directory>/pr/.
Run enallagi <command> --help for the flags.
License
MIT
来源:GitHub · github.com