Orchestrator for agentic coding tools
Project description
Coding agents produce dramatically better results when they plan before they code, and when their output is reviewed by a second agent — ideally from a different model provider. The catch: manually running that cycle (design → review → revise → approve → plan → review → revise → implement → review → revise → commit) across multiple agents is extremely time-consuming.
millstone automates that end to end. It wraps any combination of coding CLIs (Claude Code, Codex, Gemini, OpenCode) in a deterministic build-review loop: one agent authors, a second reviews, feedback cycles until the reviewer approves, then the change is committed. The same loop governs designs, plans, and code — with optional autonomous outer loops that discover opportunities, generate designs, and break them into tasks without human prompting.
Documentation | Getting Started | Meta Invoke | Contributing | Changelog
Quick Start
Before installing millstone, install and authenticate at least one supported coding agent CLI.
See Supported Agents.
# 1) Install
pipx install millstone
# 2) Move into the repo you want to run on
cd /path/to/your/project
# 3) Recommended: give your coding agent an operator prompt
# @docs/prompts/execute.md (run a tasklist)
# @docs/prompts/design.md (design + plan a new feature)
Pick the path that matches your intent:
# 1) One task now (no tasklist setup required)
millstone --task "add retry logic to API client"
# 2) Existing local backlog -> migrate once, then execute
millstone --migrate-tasklist backlog.md
millstone
# 3) Design -> plan -> execute one objective (skips analyze)
millstone --deliver "Add retry logic to API client"
# 4) New app / fresh repo
millstone --init
millstone --deliver "Build a CLI app for release note generation"
# 5) Full autonomous loop on an existing project
millstone --cycle
For a series of human-written goals with no analyze step, use roadmap + cycle:
millstone --cycle --roadmap docs/roadmap.md
millstone reads from .millstone/tasklist.md by default.
Highlights
- Deterministic inner loop:
Builder -> Sanity -> Reviewer -> Sanity -> Fix -> Commit. - Autonomous outer loops:
analyze,design,plan,cycle— every authoring step is write/review gated. --max-cyclesgoverns both inner build-review iterations and outer-loop authoring loops.- Parallel execution via
git worktree— run multiple tasks concurrently with isolated checkouts and a serialized merge queue. - Primary operating mode is coding-agent-invoked execution (
docs/prompts/execute.md). - Built-in evaluation flow with result capture and regression comparison.
- Multi-provider CLI routing per role (
claude,codex,gemini,opencode). - Stateful runs with logs, evals, and recovery under
.millstone/.
Usage Patterns
| Goal | Command |
|---|---|
| Coding agent mediated execution (recommended) | Give your coding agent docs/prompts/execute.md |
| Execute next tasks from tasklist | millstone |
| Limit to one task | millstone -n 1 |
| Run custom one-off task | millstone --task "..." |
| Migrate an existing local backlog to tasklist format | millstone --migrate-tasklist backlog.md |
| Design, plan, and execute one scoped objective | millstone --deliver "..." |
| Claude code as author, codex as reviewer, one task, max of 6 write/review cycles task | millstone --cli claude --cli-reviewer codex -n 1 --max-cycles 6 |
| Run 4 tasks in parallel (worktree mode) | millstone --worktrees --concurrency 4 |
| Dry-run prompt flow without invoking agents | millstone --dry-run |
| Scan codebase for opportunities | millstone --analyze |
| Generate a design doc | millstone --design "Add caching layer" |
| Turn design into atomic tasks | millstone --plan .millstone/designs/add-caching-layer.md |
| Plan and execute from existing design | millstone --plan .millstone/designs/foo.md --complete |
| Execute roadmap goals without analyze | millstone --cycle --roadmap docs/roadmap.md |
| Run autonomous cycle end-to-end | millstone --cycle |
| Resume an interrupted run | millstone --continue |
How It Works
Inner loop (delivery):
Builder -> Sanity Check -> Reviewer -> Sanity Check -> Fix Loop -> Commit
Outer loop (self-direction):
Analyze -> Design -> Plan -> [Inner Loop] -> Eval -> (repeat)
Every authoring step in the outer loop (analyze, design, plan) is write/review gated: a
reviewer agent checks the output and requests revisions until it approves or --max-cycles
is exhausted. This is the same iterative loop that governs inner-loop code changes.
Supersedes prior behavior:
--analyzepreviously ran the analysis agent once with no review step. All outer-loop authoring steps (analyze, design, plan) now run an iterative write/review/fix loop identical in structure to the inner build-review loop.
Installation Options
# PyPI (recommended when release is available)
pipx install millstone
# GitHub latest
pipx install git+https://github.com/wittekin/millstone.git
# Contributor install
pip install -e .
Optional extras:
pip install -e .[test] # pytest + coverage
pip install -e .[quality] # ruff + mypy
pip install -e .[security] # pip-audit
pip install -e .[release] # build + twine
Minimal Tasklist Format
# Tasklist
- [ ] First task to implement
- [ ] Second task
- [x] Already completed task
millstone executes the first unchecked - [ ] task.
Configuration Snapshot
Create .millstone/config.toml in the target repo:
max_cycles = 3
max_tasks = 5
tasklist = ".millstone/tasklist.md"
cli = "claude"
cli_builder = "codex"
cli_reviewer = "claude"
eval_on_commit = false
approve_opportunities = true
approve_designs = true
approve_plans = true
Multi-maintainer setup
By default, artifact files (tasklist, designs, opportunities) are written under .millstone/ and are gitignored — suitable for single-maintainer or local-only workflows.
To commit artifacts to the repo and share them with teammates, opt in per artifact type:
commit_tasklist = true # stores at docs/tasklist.md
commit_designs = true # stores at designs/
commit_opportunities = true # stores at opportunities.md
For full multi-maintainer collaboration, use an external artifact provider (Jira, Linear, or GitHub Issues) instead of file-backed defaults.
Tasklist filter contract
All tasklist providers (Jira, Linear, GitHub Issues) respect a provider-agnostic [tasklist_filter] section in .millstone/config.toml:
[tasklist_filter]
labels = ["sprint-1"] # AND – task must carry ALL listed labels
assignees = ["alice", "bob"] # OR – task assigned to ANY of these users
statuses = ["Todo", "In Progress"] # OR – task in ANY of these statuses
Omit any key (or leave the list empty) to skip filtering on that dimension. The filter is applied when the outer loop fetches the next task from the remote provider. An explicit filter key inside [tasklist_provider_options] takes precedence over this section.
Scoping remote backlogs
When using a remote tasklist provider (Jira, Linear, or GitHub Issues), the default scope is the full open-issue set for the configured project/team/repo. Use [millstone.tasklist_filter] to restrict millstone to a specific subset without modifying provider options.
When to use local tasklist vs remote filters
| Situation | Recommendation |
|---|---|
| Personal project or solo maintainer | Local .millstone/tasklist.md |
| Team with shared backlog in Jira/Linear/GitHub | Remote provider + [millstone.tasklist_filter] |
| Ad-hoc spike or one-off work | millstone --task "..." |
| Sprint-scoped automation on a shared board | Remote provider + label/cycle/milestone filter |
Quick examples by backend
Jira — current sprint label:
[tasklist_provider_options]
type = "jira"
project = "PROJ"
[millstone.tasklist_filter]
label = "sprint-1"
assignee = "john.doe"
Linear — active cycle for a team:
[tasklist_provider_options]
type = "linear"
team_id = "<uuid>"
[millstone.tasklist_filter]
cycles = ["Cycle 5"]
label = "millstone"
GitHub Issues — label + milestone:
[tasklist_provider_options]
type = "github"
owner = "myorg"
repo = "myrepo"
[millstone.tasklist_filter]
label = "sprint-1"
milestone = "v1.2"
See full filter option reference in the per-backend docs under docs/providers/.
See full config and CLI options with:
millstone --help
Project Signals
- Canonical loop ontology:
docs/architecture/ontology.md - Scope and safety boundaries:
docs/architecture/scope.md - Parallel execution with worktrees:
docs/worktrees.md - CLI providers:
docs/cli-providers/ - Artifact providers:
docs/providers/ - Release checklist:
docs/maintainer/release_checklist.md
Build and Release Workflows
This repository ships with CI, quality, docs, release, security, CodeQL, dependency review, and weekly maintenance workflows in .github/workflows/.
Tag release flow:
git tag -a vX.Y.Z -m "Release vX.Y.Z"
git push origin vX.Y.Z
Star History
Planned after initial public release and first community adoption.
Working Directory
Creates .millstone/ in your repo containing:
runs/- Timestamped logs of each runevals/- JSON eval results for comparisoncycles/- Logs of autonomous cycle decisionsstate.json- Saved state for --continue (inner-loop halts and outer-loop stage checkpoints)config.toml- Per-repo configurationSTOP.md- Created by sanity check to halt
This directory is auto-added to .gitignore.
Safety Checks
Mechanical:
- No changes detected -> Warn (proceeds to review)
- Too many lines changed -> Halt for human review
- Sensitive files (
.env, credentials) -> Halt for human review - New test failures (with
--eval-on-commit) -> Halt
Judgment (via LLM):
- Builder output is gibberish -> Create
STOP.md-> Halt - Reviewer feedback is nonsensical -> Create
STOP.md-> Halt
Exit Codes
0- Success1- Halted (needs human intervention)
Expected Runtime
Depending on cycles, tasks, and your agent provider / model, millstone can run for minutes or hours.
Requirements
- Python 3.10+
claudeCLI installed and authenticated (default), orcodexCLI installed and authenticated (if using--cli codex), orgeminiCLI installed and authenticated (if using--cli gemini), oropencodeCLI installed and authenticated (if using--cli opencode)
Open Source Project Files
- License: LICENSE
- Contributing guide: CONTRIBUTING.md
- Code of conduct: CODE_OF_CONDUCT.md
- Security policy: SECURITY.md
- Changelog: CHANGELOG.md
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file millstone-0.4.2.tar.gz.
File metadata
- Download URL: millstone-0.4.2.tar.gz
- Upload date:
- Size: 380.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1f7393dd64c9fb04187d1cdbdee4640e6bf861bb9c40e0b7e8838ea8e7262d31
|
|
| MD5 |
d825331067157a9ae30fe8c7364b00d3
|
|
| BLAKE2b-256 |
814f9400e680437ca4a464bfd56828e6dc0bd98e8c279cb56c0a7026dcd63ab1
|
Provenance
The following attestation bundles were made for millstone-0.4.2.tar.gz:
Publisher:
release.yml on wittekin/millstone
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
millstone-0.4.2.tar.gz -
Subject digest:
1f7393dd64c9fb04187d1cdbdee4640e6bf861bb9c40e0b7e8838ea8e7262d31 - Sigstore transparency entry: 1059171405
- Sigstore integration time:
-
Permalink:
wittekin/millstone@b74759f3ee1e01b28e0d10fa41a2fdf813e6baca -
Branch / Tag:
refs/tags/v0.4.2 - Owner: https://github.com/wittekin
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@b74759f3ee1e01b28e0d10fa41a2fdf813e6baca -
Trigger Event:
push
-
Statement type:
File details
Details for the file millstone-0.4.2-py3-none-any.whl.
File metadata
- Download URL: millstone-0.4.2-py3-none-any.whl
- Upload date:
- Size: 234.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4413bdd4f43045e83cca49b7904bf2a39c96b9c493fb37c0401eb545b440b305
|
|
| MD5 |
26c4d9c93751229ba8149f22f0f46dac
|
|
| BLAKE2b-256 |
06ddacabe924c491312849efee70b5a5fc5ed07e07dc119b03428c5dab5acb30
|
Provenance
The following attestation bundles were made for millstone-0.4.2-py3-none-any.whl:
Publisher:
release.yml on wittekin/millstone
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
millstone-0.4.2-py3-none-any.whl -
Subject digest:
4413bdd4f43045e83cca49b7904bf2a39c96b9c493fb37c0401eb545b440b305 - Sigstore transparency entry: 1059171460
- Sigstore integration time:
-
Permalink:
wittekin/millstone@b74759f3ee1e01b28e0d10fa41a2fdf813e6baca -
Branch / Tag:
refs/tags/v0.4.2 - Owner: https://github.com/wittekin
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@b74759f3ee1e01b28e0d10fa41a2fdf813e6baca -
Trigger Event:
push
-
Statement type: