Python runtime engine for the Millrace v1 control plane
Project description
Millrace
Millrace is a local autonomous software-delivery runtime for long-running coding work. It runs governed execution and research loops inside a file-backed workspace with durable state, explicit recovery surfaces, per-run provenance, and publish controls.
It is built for unattended or semi-attended work that needs more than a chat session or a thin agent wrapper. You get one engine, one control plane, and multiple operator surfaces over the same on-disk truth: CLI, TUI, and agent-guided operation.
Install
python3 -m pip install millrace-ai
This installs the millrace command. Create a workspace with millrace init ...; millrace.toml and agents/ live inside that initialized workspace, not at the public repo root.
It gives you:
- a Python CLI and a Textual TUI, plus an agent-facing advisor surface
- a single runtime engine
- an execution plane for delivery work
- a research plane for idea intake, audit, and governed handoff
- durable runtime state, event logs, diagnostics, provenance, and publish surfaces inside the workspace
Read next:
OPERATOR_GUIDE.mdfor the human operator workflowADVISOR.mdfor the agent-facing operator promptdocs/RUNTIME_DEEP_DIVE.mdfor architecture and failure-model detail
Millrace ships real default model ids in its packaged config and model profiles. A fresh workspace starts from Codex/OpenAI defaults such as gpt-5.3-codex and gpt-5.2; they are not placeholder values. Execution still depends on local runner readiness, so treat doctor as the final check for codex availability and auth before start --once.
Why Millrace Exists
Interactive coding tools are good at short sessions. They are weak at long-running governed work that needs queue discipline, durable state, recoverable execution, research-to-delivery handoff, and publish controls.
Millrace exists to make those runtime concerns first-class instead of leaving them implicit in shell history, chat transcripts, or one-off wrapper scripts.
How Millrace Is Different
- Runtime, not wrapper: Millrace owns lifecycle, queue mutation, watch surfaces, status, events, and publish flow.
- File-backed truth: runs, queues, status, diagnostics, and provenance live in the workspace, not in opaque process memory.
- Governed autonomy: execution and research share one engine but keep distinct state, reporting, and handoff surfaces.
- Frozen per-run plans: each run resolves its effective mode and loop, then records the exact plan used for that run.
- Multiple operator surfaces: CLI, TUI, and agent-guided operation all sit over the same control plane.
Design Philosophy
- Local and inspectable: the workspace is the source of operational truth.
- Honest failure over hidden magic: blocked work, partial progress, and degraded state should stay legible.
- Explicit boundaries: lifecycle, runtime state, research, execution, and publish are separate product surfaces.
- Recoverability matters: long-running systems need durable ledgers, diagnostics, and restart-safe state.
Repo Layout
The public Millrace repo is package-first. Its main surfaces are:
millrace_engine/: the runtime package, CLI, control layer, and enginedocs/: longer-form reference material, including the runtime deep dive and TUI referencetests/: unit and integration testspyproject.toml: packaging metadata and console entrypointmillrace_engine/assets/: the packaged baseline bundle used bymillrace init
millrace.toml and agents/ are part of an initialized Millrace workspace. They are seeded by millrace init; they are not expected at the public repo root.
Initialized Workspace Layout
An initialized workspace created by millrace init /absolute/path/to/workspace contains:
millrace.toml: the active workspace configagents/: queues, runs, logs, prompts, state, and provenancedocs/: copied reference material that travels with the workspace
Core Runtime Model
- One CLI:
millrace --config millrace.toml ... - One module-equivalent CLI:
python3 -m millrace_engine --config millrace.toml ... - One TUI shell:
python3 -m millrace_engine.tui --config millrace.toml - One engine: the daemon owns lifecycle, watchers, mailbox commands, runtime state, and event emission.
- Two logical planes: execution work and research work share the same engine but keep separate status and reporting surfaces.
- File-backed truth: queues, runs, status, logs, diagnostics, and provenance live under
agents/. - Workspace-first assets: workspace files override packaged defaults when present; packaged assets are the fallback.
- Frozen per-run plans: before a standard execution run, Millrace resolves the selected mode and loop, applies workspace overrides, and freezes the effective plan under
agents/runs/<run_id>/.
Quick Start
Install the published package:
python3 -m pip install millrace-ai
Create and inspect a workspace:
millrace init /absolute/path/to/workspace
millrace --config /absolute/path/to/workspace/millrace.toml health --json
millrace --config /absolute/path/to/workspace/millrace.toml doctor
millrace --config /absolute/path/to/workspace/millrace.toml status --detail --json
python3 -m millrace_engine.tui --config /absolute/path/to/workspace/millrace.toml
After init, you can cd /absolute/path/to/workspace and use the shorter --config millrace.toml form.
Add work and execute one foreground cycle:
cd /absolute/path/to/workspace
millrace --config millrace.toml add-task "Example task"
millrace --config millrace.toml start --once
If you are developing Millrace itself from a source checkout instead of installing the package, use:
cd /absolute/path/to/millrace
python3 -m venv .venv
source .venv/bin/activate
python3 -m pip install -e '.[dev]'
Release verification is narrower than source-checkout contributor verification: release CI smoke-installs the built wheel into a clean virtualenv, runs millrace init against a freshly generated workspace, and then runs health --json on that workspace. Broader pytest coverage remains a source-checkout path with dev dependencies; it is not currently advertised as a wheel or sdist smoke gate.
TUI Shell
The TUI is the fastest way to operate an initialized workspace when you want a dense control panel instead of a stream of CLI calls.
Launch it with:
python3 -m millrace_engine.tui --config millrace.toml
What it provides:
- a startup health gate before the shell becomes interactive
- a dual-mode shell with summary-first
operatormode and detail-forwarddebugmode - one toggleable expanded stream mode that takes over the main content area while leaving the sidebar, status strip, and notices visible
- a persistent shell with sidebar navigation, a compact status strip, and widget-composed overview/queue/runs/research/logs/config/publish panels
- explicit lifecycle signaling across the sidebar daemon badge, top status strip, and notices rail
- guided task, idea, queue reorder, config edit, and publish confirmation flows
- lifecycle actions for
start --once,start --daemon,pause,resume, andstop - a command palette for common actions, including display-mode toggle and lifecycle controls
- built-in keyboard help (
?) and panel shortcuts (1through7) - the same runtime semantics as the CLI, including mailbox-safe daemon mutations and the same file-backed truth surfaces
Use the TUI for day-to-day observation and control. Use the CLI when you want scriptable, one-shot commands or JSON output.
The repo also ships a dedicated TUI reference in its docs/ directory for the full panel, control, and interaction map.
Expanded stream behavior to know:
- press
eto toggle the active panel into expanded mode andEscapeto return to the normal panel body - in
operatormode, expanded view renders a narrated activity feed from runtime events - in
debugmode, expanded view renders the raw structured event lines, close tologs --follow - if you scroll upward, live follow disengages until you jump back with
l
Start A Fresh Workspace
Use init when you want a new Millrace workspace without copying files by hand:
millrace init /absolute/path/to/workspace
millrace init --force /absolute/path/to/workspace
Important behavior:
- Without
--force, the destination must be absent or empty. - With
--force, Millrace overwrites manifest-tracked baseline files in place. It does not wipe the directory. - Workspace prompt and registry overlays can override packaged defaults after scaffolding.
- Missing workspace prompt files fall back to packaged assets when the resolver supports that family.
After scaffolding, run the workspace preflight before you rely on the runtime:
millrace --config /absolute/path/to/workspace/millrace.toml health --json
millrace --config /absolute/path/to/workspace/millrace.toml doctor
health confirms bootstrap/config/assets truth. doctor is the execution-readiness check that tells you whether required external runner CLIs such as codex are available before start --once.
The shipped model ids in that scaffold are real defaults, but doctor is still the command that tells you whether the current machine can actually execute them.
Daily Operator Flow
The rest of this section assumes you are operating inside an initialized workspace root that contains the active millrace.toml.
- Preflight the workspace:
millrace --config millrace.toml health --json
millrace --config millrace.toml doctor
Or launch the TUI and let the health gate run automatically:
python3 -m millrace_engine.tui --config millrace.toml
- Inspect current state:
millrace --config millrace.toml status --detail --json
millrace --config millrace.toml queue inspect --json
millrace --config millrace.toml research --json
millrace --config millrace.toml logs --tail 50 --json
In the TUI, the Overview, Queue, Research, Logs, and Runs panels expose the same runtime state without leaving the shell.
- Add work:
millrace --config millrace.toml add-task "Example task"
millrace --config millrace.toml add-idea /absolute/path/to/idea.md
add-task appends an execution task to the backlog. add-idea copies a source markdown file into agents/ideas/raw/ for research-side intake.
- Run the engine:
millrace --config millrace.toml start --once
millrace --config millrace.toml start --daemon
start --once is a foreground single pass, not a guaranteed full research-plus-execution roundtrip. If startup research sync creates new execution backlog while the execution queue was empty, that invocation stops after the research pass; run start --once a second time to execute the newly generated task.
The TUI exposes the same actions through the command palette and keyboard-driven panel flows.
- Inspect outcomes:
millrace --config millrace.toml logs --follow
millrace --config millrace.toml run-provenance <run_id> --json
millrace --config millrace.toml research history --json
The TUI keeps recent runs, filtered logs, and concise run-provenance drilldown in one place, including a run-detail modal from the Runs and Logs panels.
When you want the old foreground-feed feel without leaving the shell, use TUI expanded mode instead of opening a second terminal just to run logs --follow.
- Control a long-running daemon:
millrace --config millrace.toml pause
millrace --config millrace.toml resume
millrace --config millrace.toml stop
When the daemon is running, mutating commands route through the mailbox so one owner process stays in control of live state.
Publish And Staging
Millrace includes a staging and publish surface for preparing a release worktree:
millrace --config millrace.toml publish sync --json
millrace --config millrace.toml publish preflight --json
millrace --config millrace.toml publish commit --no-push --json
publish preflight is read-only. It reports the resolved staging repo, manifest source, git readiness, and changed paths without mutating git state.
Runtime Inputs
By default the daemon watches:
- backlog and autonomy marker files
- raw ideas under
agents/ideas/raw/ - mailbox commands under
agents/.runtime/commands/incoming/ - the config file
millrace.toml
These roots are configured under [watchers].
Remaining shell loop artifacts under agents/ are compatibility or reference material only. The supported operating surfaces are the Python CLI and the Textual TUI.
Verification
python3 -m compileall millrace_engine
PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 pytest -q tests
Use health --json as the first runtime preflight and status --detail --json, research --json, logs, and run-provenance as the main visibility surfaces once the engine is running.
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 millrace_ai-0.2.0.tar.gz.
File metadata
- Download URL: millrace_ai-0.2.0.tar.gz
- Upload date:
- Size: 711.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8bc2ac617fca32f9ce93f392045b61353b699e05738c73213347912f09d226c0
|
|
| MD5 |
65b9e44256b4c02a10f9556bfce072fa
|
|
| BLAKE2b-256 |
a242d8bae9b878f92708e5a18a2e40d6a1caaed2796492824bda2d5aae4a0d8d
|
Provenance
The following attestation bundles were made for millrace_ai-0.2.0.tar.gz:
Publisher:
publish-to-pypi.yml on tim-osterhus/millrace
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
millrace_ai-0.2.0.tar.gz -
Subject digest:
8bc2ac617fca32f9ce93f392045b61353b699e05738c73213347912f09d226c0 - Sigstore transparency entry: 1202810053
- Sigstore integration time:
-
Permalink:
tim-osterhus/millrace@06ef25f0fc7d71ab8f57c2b79b4ee7ebfbb5837f -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/tim-osterhus
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-to-pypi.yml@06ef25f0fc7d71ab8f57c2b79b4ee7ebfbb5837f -
Trigger Event:
push
-
Statement type:
File details
Details for the file millrace_ai-0.2.0-py3-none-any.whl.
File metadata
- Download URL: millrace_ai-0.2.0-py3-none-any.whl
- Upload date:
- Size: 792.0 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 |
6280bb20ff7981bb6ddb25d7ab5b90df3e885771f5154e5db0fd656dfc088477
|
|
| MD5 |
4b1bfa34a41290d1b9f13cf2f09a3457
|
|
| BLAKE2b-256 |
bca67abd67a52b52d12b90441a8443ceab697a05b6cc178586bf49cb8eb20708
|
Provenance
The following attestation bundles were made for millrace_ai-0.2.0-py3-none-any.whl:
Publisher:
publish-to-pypi.yml on tim-osterhus/millrace
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
millrace_ai-0.2.0-py3-none-any.whl -
Subject digest:
6280bb20ff7981bb6ddb25d7ab5b90df3e885771f5154e5db0fd656dfc088477 - Sigstore transparency entry: 1202810055
- Sigstore integration time:
-
Permalink:
tim-osterhus/millrace@06ef25f0fc7d71ab8f57c2b79b4ee7ebfbb5837f -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/tim-osterhus
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-to-pypi.yml@06ef25f0fc7d71ab8f57c2b79b4ee7ebfbb5837f -
Trigger Event:
push
-
Statement type: