{"id":48393167,"url":"https://github.com/tim-osterhus/millrace","last_synced_at":"2026-05-03T08:01:32.292Z","repository":{"id":348033272,"uuid":"1196214186","full_name":"tim-osterhus/millrace","owner":"tim-osterhus","description":"A governed, autonomous runtime for agent work too long, too stateful, or too recovery-sensitive to survive a single session.","archived":false,"fork":false,"pushed_at":"2026-05-03T06:03:39.000Z","size":4541,"stargazers_count":6,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-03T07:22:00.872Z","etag":null,"topics":["agentic-ai-development","agentic-coding","agentic-engineering","agentic-framework","agentic-workflow","autonomous-agents","harness-engineering"],"latest_commit_sha":null,"homepage":"https://millrace.ai","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tim-osterhus.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-30T13:35:35.000Z","updated_at":"2026-05-03T06:03:42.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/tim-osterhus/millrace","commit_stats":null,"previous_names":["tim-osterhus/millrace"],"tags_count":57,"template":false,"template_full_name":null,"purl":"pkg:github/tim-osterhus/millrace","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tim-osterhus%2Fmillrace","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tim-osterhus%2Fmillrace/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tim-osterhus%2Fmillrace/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tim-osterhus%2Fmillrace/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tim-osterhus","download_url":"https://codeload.github.com/tim-osterhus/millrace/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tim-osterhus%2Fmillrace/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32562118,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-03T06:36:36.687Z","status":"ssl_error","status_checked_at":"2026-05-03T06:36:09.306Z","response_time":103,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agentic-ai-development","agentic-coding","agentic-engineering","agentic-framework","agentic-workflow","autonomous-agents","harness-engineering"],"created_at":"2026-04-06T01:04:08.484Z","updated_at":"2026-05-03T08:01:32.285Z","avatar_url":"https://github.com/tim-osterhus.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Millrace\n\n[![PyPI](https://img.shields.io/pypi/v/millrace-ai.svg)](https://pypi.org/project/millrace-ai/)\n[![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)\n[![License](https://img.shields.io/github/license/tim-osterhus/millrace.svg)](LICENSE)\n\n\u003cp align=\"center\"\u003e\n  \u003cimg\n    src=\"docs/assets/images/millrace-icon-signal-transparent-glow.png\"\n    alt=\"Millrace signal mark\"\n    width=\"260\"\n  /\u003e\n\u003c/p\u003e\n\n## Other agents win sprints. Millrace wins marathons.\n\nRaw agent harnesses - Codex, Claude Code, Gemini - are built for sprints. Give\nthem a tight spec in a greenfield repo, let them rip, ship the result. They are\nvery good at this.\n\nMillrace starts where those runs end. When the work spans sessions,\naccumulates state, needs to survive a crash without losing context, or has to\ngate on real acceptance criteria rather than \"the agent said it was done\",\nthat is the problem Millrace was built for.\n\nMillrace is a governed runtime for long-running agent work. The harness still\ndoes the local stage work. Millrace owns the queue, the compiled plan, runtime\nstate, recovery paths, and closure behavior around that work.\n\n\u003e If you are an agent and your harness supports repo-local skills, for example\n\u003e Codex or Claude Code, install\n\u003e `docs/skills/millrace-ops-agent-manual/SKILL.md` to become a Millrace\n\u003e Operator before deciding whether work should enter Millrace. It teaches when\n\u003e to use Millrace, when not to, and how to run, monitor, and intervene safely.\n\n### Agent Install Examples\n\n- Codex: if your environment supports repo-local skills, load\n  `docs/skills/millrace-ops-agent-manual/` as the local skill package. The\n  entry file is `docs/skills/millrace-ops-agent-manual/SKILL.md`.\n- Claude Code: use the same package path or entry file as the local project\n  skill, then follow the autonomy handshake inside the skill before deciding\n  whether work should enter Millrace.\n- Other harnesses: if the harness accepts a `SKILL.md`, point it at\n  `docs/skills/millrace-ops-agent-manual/SKILL.md`; if it supports directory\n  packages, prefer `docs/skills/millrace-ops-agent-manual/`.\n\n## Runtime Lifecycle\n\nNeed the full implementation-accurate flow instead of the landing-page view?\nSee [the standalone lifecycle chart](docs/runtime/millrace-runtime-lifecycle-diagram.md).\n\n```mermaid\nflowchart TD\n    A[\"Initialize workspace, then compile the plan\"] --\u003e B{\"Deterministic tick loop\"}\n    B --\u003e C[\"Process control inputs:\u003cbr/\u003emailbox commands, watcher intake, reconciliation\"]\n    C --\u003e D{\"Scheduler claim decision\"}\n    D -- planning incident or spec --\u003e E[\"Planning loop:\u003cbr/\u003einterpret specs and incidents,\u003cbr/\u003egovern remediation, emit executable work\"]\n    D -- execution task --\u003e F[\"Execution loop:\u003cbr/\u003ebuild, verify, repair, recover, update\"]\n    D -- learning request --\u003e K[\"Learning loop:\u003cbr/\u003eanalyze runtime evidence,\u003cbr/\u003epropose skill improvements,\u003cbr/\u003ecurate accepted updates\"]\n    D -- nothing claimable --\u003e G{\"Completion behavior eligible?\"}\n    G -- yes --\u003e H[\"Arbiter closure pass\"]\n    G -- no --\u003e I[\"Idle until the next tick\"]\n    E --\u003e J[\"Runtime applies results,\u003cbr/\u003epersists state, and routes the next action\"]\n    F --\u003e J\n    K --\u003e J\n    H --\u003e J\n    J --\u003e B\n    I --\u003e B\n```\n\nMillrace does not try to replace raw harness reasoning with a thicker prompt.\nIt wraps long-horizon work in a real runtime:\n\n- workspace bootstrap is explicit: run `millrace init` before operator commands\n- runtime package updates are separate from workspace baseline refreshes: use\n  the deployment package manager to update `millrace-ai`, then run\n  `millrace upgrade` only when managed workspace assets should be refreshed\n- managed baseline refresh is explicit: run `millrace upgrade` to preview or apply packaged workspace asset updates\n- removed managed assets can be explicitly localized during upgrade when an\n  operator wants the workspace copy to become local content\n- compile happens at startup and again only on explicit config reload\n- compile tracks input fingerprints so operators can see whether the persisted compiled plan is current or stale\n- daemon mode uses a compiled plane scheduler; default modes remain serial,\n  while learning-enabled modes may run one Learning stage concurrently with one\n  permitted foreground Planning or Execution stage\n- runtime-owned mutation remains single-writer and serialized even when stage\n  runner workers execute concurrently\n- stage results are routed by the runtime, not by direct stage-to-stage\n  handoffs\n- runtime-generated planning handoff incidents preserve source work-item\n  lineage so closure-scoped remediation stays claimable while unrelated root\n  specs remain backpressured\n- Arbiter activates only when the scheduler finds no lineage work left and\n  closure behavior is actually ready\n- the shipped v1 usage-governance surface can pause and auto-resume between\n  stages when configured token or subscription quota rules are reached\n- runtime startup and config reload refuse to keep running on a stale\n  last-known-good plan when current compile inputs no longer match\n- opt-in usage governance can pause between stages from token or subscription\n  quota rules without clearing operator-owned pauses\n  and applies config-reload changes at the next runtime tick with status/monitor\n  visibility\n\nThe shipped core already includes separate planning and execution loops, typed\nterminal results, compiler-governed completion behavior, and persisted run\nartifacts for post-run inspection. Learning-enabled modes also ship the\nAnalyst, Professor, and Curator stages for evidence-backed skill improvement\nflows.\n\n## Early Proof\n\nMillrace's strongest early proof point is self-referential: Python\n`millrace-ai` built the first released Rust parity implementation of Millrace.\n\nThe campaign used Python `millrace-ai` `v0.16.1` in `learning_codex` mode to\ndrive the Rust `millrace-ai` `v0.1.0` implementation from seeded parity ideas\nthrough planning, execution, QA, Arbiter closure, remediation, and release-ready\nworkspace state. After the operator started the daemon, there were no\npause/resume cycles, continuation prompts, or external code interventions. The\nrun proceeded to completion with zero outside assistance. The only external\npost-run action was publication: Millrace's ops agent published the completed\nresult to GitHub and as a Rust crate without touching the code Millrace had\nproduced.\n\nHeadline evidence from the autonomous build campaign:\n\n| Metric | Value |\n|------|------:|\n| Seeded parity slices | `8` |\n| Completed specs | `11` |\n| Completed tasks | `57` |\n| Recorded runs | `99` |\n| Recorded stage results | `261` |\n| Resolved incidents/remediations | `5` |\n| Wall-clock campaign span | `28h 9m 49.5s` |\n| Input plus output tokens | `730,406,757` |\n| Cached-input share | `95.47%` |\n| Release tag | `v0.1.0` |\n| Release commit | `4c82685` |\n\nThe release moved the Rust crate from an initial claimed package to a parity\nruntime across `193` changed files and `87,992` insertions. The finished crate\nalso passed a post-publish real daemon smoke: an installed `millrace-ai v0.1.0`\ncrate completed a real Codex-backed `builder -\u003e checker -\u003e updater` run in\n`6m 32.9s` and produced the expected filesystem output.\n\nThe caveat is important and narrow: this proves that Python Millrace could\nautonomously build the Rust parity runtime. It does not claim that the Rust\ncrate independently self-hosted the whole port campaign.\n\nRead the full public evidence pack here:\n\n- [millrace-rs-port-docs](https://github.com/tim-osterhus/millrace-rs-port-docs)\n\n## How Millrace Fits With Raw Harnesses\n\nMillrace is not a replacement for Codex, Claude Code, Aider, or similar raw\nagent harnesses. It is the runtime layer you put around them when the work is\ntoo long-running, stateful, or recovery-sensitive to trust to a single session.\n\nThink of the split this way:\n\n- the raw harness reasons locally, edits code, and emits a stage result\n- Millrace decides which stage runs next and what contract that stage receives\n- Millrace persists queue state, runtime snapshots, artifacts, and recovery\n  context after each handoff\n- the operator or ops agent decides when work enters the runtime and how the\n  workspace is configured\n\nIf a direct Codex or Claude Code session is enough, use the direct session.\nMillrace matters when the work has crossed out of sprint territory.\n\n## When To Use Millrace\n\nUse Millrace when:\n\n- the work will outlast a single agent session\n- you want explicit stage gates instead of \"done enough\" chat conclusions\n- recovery and resumability matter\n- you need durable state, queue artifacts, and run history under\n  `\u003cworkspace\u003e/millrace-agents/`\n- completion has to clear a real closure pass rather than informal optimism\n- an operator or ops agent is intentionally managing intake and runtime control\n\nDo not use Millrace when:\n\n- the task is small, bounded, and cleanly handled in one direct session\n- the work is exploratory and governance would add more overhead than value\n- single-session throughput matters more than persistence and recovery\n- nobody is available to manage runtime configuration, intake, and workspace\n  hygiene\n\n## 60-Second Proof\n\nInstall:\n\n```bash\npip install millrace-ai\n```\n\nThen point Millrace at a workspace:\n\n```bash\nexport WORKSPACE=/absolute/path/to/your/workspace\n\nmillrace init --workspace \"$WORKSPACE\"\nmillrace compile validate --workspace \"$WORKSPACE\"\nmillrace run once --workspace \"$WORKSPACE\"\nmillrace status --workspace \"$WORKSPACE\"\n```\n\nThat flow proves seven things quickly:\n\n- workspace bootstrap is explicit and creates the managed baseline under\n  `millrace-agents/`\n- the selected mode compiles into one persisted `compiled_plan.json` before execution\n- compile output fingerprints the selected mode, runtime config, and packaged\n  assets so `compile show` / `status` can report whether the plan is current\n  or stale\n- that compiled plan carries node bindings, intake entries, recovery policies, closure-target activation, and post-stage routing\n- the shipped `default_codex` mode freezes closure behavior directly into that single compiled artifact\n- status and run inspection carry compiled-plan identity so operators can tie\n  runtime activity back to the compiled plan that produced it\n- the runtime can execute a deterministic tick and report persisted status\n\nFor a visible long-running session, use `millrace run daemon --monitor basic`.\nThe default daemon remains quiet unless that monitor is requested explicitly.\nThe basic monitor is a human-facing stream: it compacts stage labels, shortens\nlong run ids for display, omits unknown token filler, and leaves full ids and\nartifacts to `millrace runs ...` inspection commands.\nThe basic monitor prints the first `idle reason=no_work` line immediately, then\nthrottles repeated `no_work` idles to a 120-second heartbeat until runtime\nactivity or a different idle reason appears.\nUse `--monitor-log \u003cpath\u003e` when you want the same clean monitor stream written\nto a file without necessarily printing live monitor lines to stdout.\n\nFor an optional local dashboard, install the separate `millrace-web` package\nfrom PyPI and run `millrace-web serve --workspace \"$WORKSPACE\"`. The web\ndashboard is a read-only observer with Detail and Flow views; it is not\nincluded in the `millrace-ai` wheel and does not acquire runtime ownership\nlocks.\n\nWhen the packaged workspace baseline changes, use `millrace upgrade` first to\npreview the managed-file classifications, then `millrace upgrade --apply` to\napply safe baseline updates. This does not update the installed Python package;\nfor runtime-code fixes, update `millrace-ai` through the environment's package\nmanager first and verify with `millrace --version` or `millrace version`. If\ncompile inputs drift and the persisted plan is stale, runtime startup and\nconfig reload refuse to keep running on the stale plan.\n\nStage config supports all execution, planning, and learning stage names. For\nCodex-backed stages, `stages.\u003cstage\u003e.model_reasoning_effort` sets the\nper-stage Codex reasoning effort that compile, runner invocation artifacts, and\nrun inspection will surface.\n\nCanonical shipped modes today:\n\n- `default_codex`\n- `default_pi`\n\nLearning-enabled shipped modes:\n\n- `learning_codex`\n- `learning_pi`\n\nThe learning modes use the same execution and planning topology as the default\nmodes, add `learning.standard`, and freeze learning trigger rules into the\ncompiled plan.\n\nCompatibility alias:\n\n- `standard_plain -\u003e default_codex`\n\n## Read By Journey\n\nNeed the single dense system explainer first?\nStart with `docs/millrace-technical-overview.md`.\n\n### Start Here\n\n- `docs/runtime/README.md`\n- `docs/skills/millrace-ops-agent-manual/SKILL.md` if you are operating\n  Millrace as an agent\n\n### Run It\n\n- `docs/runtime/millrace-cli-reference.md`\n- `docs/runtime/millrace-runtime-architecture.md`\n- `docs/runtime/millrace-usage-governance.md`\n\n### Understand It\n\n- `docs/runtime/millrace-compiler-and-frozen-plans.md`\n- `docs/runtime/millrace-modes-and-loops.md`\n- `docs/runtime/millrace-arbiter-and-completion-behavior.md`\n- `docs/runtime/millrace-runner-architecture.md`\n\n### Extend It\n\n- `docs/runtime/millrace-entrypoint-mapping.md`\n- `docs/runtime/millrace-loop-authoring.md`\n- `docs/skills/millrace-loop-authoring/SKILL.md`\n- `docs/source-package-map.md`\n\n## Status\n\nMillrace ships as a maintained pre-1.0 runtime line. If you depend on exact\nbehavior, pin to a patch version and verify against the current CLI and docs\nrather than assuming every newer build is identical.\n\n## License\n\nSee `LICENSE`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftim-osterhus%2Fmillrace","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftim-osterhus%2Fmillrace","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftim-osterhus%2Fmillrace/lists"}