Skip to content

Latest commit

 

History

31 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Mill

Mill is a local-first software factory that turns approved product intent into bounded, tested, locally reviewed draft pull requests.

It is designed for a founder or small team that wants coding-agent leverage without handing one agent an open-ended ticket, production credentials, and the power to judge its own work. Product truth stays in the repository. Codex writes inside a disposable worktree. Native tests and scenarios verify the committed candidate. A separate read-only pass reviews that exact commit. Only the attended shipper can use your GitHub identity. Draft-only is the default; repositories may explicitly enable a separately approved, exact-plan merge.

Mill 0.3.1 is the current qualified public alpha and the latest release on GitHub and npm. The release includes provenance, an SBOM, independent exact-artifact qualification, and verified registry and GitHub downloads. GitHub's Latest label does not expand the public-alpha support limits. See the release record for exact evidence and recovery history. The v0.1.5 genesis release remains the historical trust root; v0.2.0 was held before publication and its tag is preserved.

Why Mill

Coding is only one part of software delivery. The difficult failure modes live between a PRD and a merged change: ambiguous intent, changing architecture, weak acceptance tests, context drift, cumulative regressions, credential leakage, interrupted side effects, noisy review, and artifacts that cannot be reconstructed later.

Mill makes those boundaries explicit:

  • approved outcomes, invariants, scenarios, impacts, and tasks are versioned in Git;
  • each run is bound to an exact base, authority closure, worker profile, budget, candidate commit, validation result, and review result;
  • product code remains independently buildable and testable without Mill;
  • the builder cannot push, merge, deploy, or rewrite the oracle that certifies its own candidate;
  • GitHub mutations are separately planned, approved, journaled, and reconciled;
  • one complete review is repaired systemically instead of creating micro-PR churn;
  • longitudinal qualification proves that accepted behavior survives a sequence of dependent changes, not just one isolated demo;
  • releases preserve and publish one independently reproduced tarball rather than rebuilding at publication time.

This is the differentiator: Mill is not another chat UI or general coding harness. It is the small, inspectable delivery control plane around the coding agent you already use.

What it can do

For its one qualified shape, Mill can:

  1. inspect a PRD, source manifest, structured product proposal, and repository without executing repository code;
  2. freeze an approved product contract, stable invariants, scenarios, and per-change impact;
  3. create a repository from the bundled web recipe or plan a compatible adoption without overwriting existing truth;
  4. prepare exact npm dependencies as a separate attended network effect;
  5. run one approved task through Codex build, OCI validation, exact-candidate review, and one bounded repair generation;
  6. plan and open one draft GitHub PR through the operator's own gh session;
  7. observe exact-head CI and review, optionally execute a separately approved attended merge, then verify resulting-main closure;
  8. back up, restore, purge, reconcile, cancel, detach, and export a redacted support bundle through explicit commands;
  9. audit the exact repository candidate and validate a public-alpha qualification record;
  10. derive bounded, source-revision-bound TypeScript repository evidence from a clean Git root without executing its code;
  11. compile an operator-supplied follow-up change request and approved impacts into dependency-checked task packets and an outcome plan.
  12. project a durable run into a versioned, read-only continuation packet that names the next attended safe action without taking it;
  13. report the built-in builder's trusted-host boundary and reject an unqualified request for isolated execution rather than silently claiming containment.

Mill does not autonomously research the web or invent a product specification in this alpha. The operator supplies the structured proposal that Mill assesses and freezes.

Supported shape

The first recipe is intentionally exact:

  • Node.js 24.18.1 and npm 11.16.0 inside the verifier image;
  • TypeScript 6.0.3;
  • Next.js 16.3.4 and React 19.2.8;
  • Playwright 1.62.1;
  • GitHub as the only forge;
  • Codex CLI with the operator's existing login;
  • Docker-compatible OCI verification;
  • macOS arm64 as the first candidate host tuple.

Mill itself is developed with Node.js 24.20.0 and npm 11.19.0. Exact support is published in release qualification evidence, not inferred from nearby versions. The 0.3.0 host tuple was exercised on September 5, 2026 and expires on October 5, 2026 at 15:35:52 UTC; its attached qualification lists every exact version and digest. All other stacks, operating systems, architectures, forges, models, and worker harnesses are experimental or unsupported until independently qualified. Experimental native Node ESM/npm adoption is separate from this qualified web recipe.

Install

Install the qualified public alpha at its exact version with lifecycle scripts disabled:

npm install --save-dev --ignore-scripts @davidahmann/mill@0.3.1
npx --no-install millctl --version

To develop Mill itself from a clean source checkout:

git clone https://github.com/davidahmann/mill.git
cd mill
asdf install
node_bin_dir=$(dirname "$(asdf which node)")
PATH="$node_bin_dir:$PATH" "$node_bin_dir/npm" ci --ignore-scripts
PATH="$node_bin_dir:$PATH" "$node_bin_dir/npm" run check
PATH="$node_bin_dir:$PATH" "$node_bin_dir/npm" run build
node dist/cli.js --version

The alpha and latest npm tags both resolve to 0.3.1. Downstream repositories should still pin the exact version so a later release cannot alter their delivery machinery implicitly. Updating an existing Mill installation is deliberate: preserve state and repository snapshots, inspect the release notes, and requalify the changed toolchain. There is no automatic upgrade or proven general downgrade path for operational state.

Quick start

Start with read-only readiness. These commands do not execute repository code:

npx --no-install millctl doctor --mode inspect
npx --no-install millctl inspect --prd product/PRD.md
npx --no-install millctl adopt --scan-only

Discover a TypeScript repository

The remaining examples use millctl as shorthand for the installed executable; use npx --no-install millctl when it is installed locally. Supply your actual PRD and approved authority paths; installing the CLI does not create them.

Static discovery is a separate read-only operation. It requires a clean Git repository root and rejects sensitive paths, symbolic links, unsafe Git configuration, and incomplete source traversal. It parses local TypeScript and JavaScript imports only after each regular file's physical bytes match its blob in the captured HEAD tree. The same check protects parsed package metadata. It reports source locations, inventories test files, and gives conservative importer leads for named paths. Nonliteral module loads and option-bearing test commands remain explicit unknowns. It never installs dependencies, runs the target's code, or claims executed coverage or delivery authority.

millctl --json discover /absolute/path/to/repository --changed src/service.ts

The first increment is a deterministic TypeScript extractor, not arbitrary-stack support, a graph database, a watcher, or an AI-generated knowledge graph. Read product/brownfield-discovery.md and docs/canaries/brownfield-discovery.md for the exact boundary and real-fixture evidence.

For a source-backed specification, supply the PRD, source manifest, and structured proposal:

millctl --json plan specification \
  --prd product/PRD.md \
  --sources product/sources.yaml \
  --proposal product/proposal.yaml

Review the returned contradictions, assumptions, questions, and exact proposal digest. Approval freezes that proposal; it does not grant repository writes.

Create a repository

Preview the exact file plan first, then apply the same plan attended:

millctl --json new my-product --dry-run \
  --prd product/PRD.md --sources product/sources.yaml \
  --proposal product/proposal.yaml --approve-product sha256:<product> \
  --repository-id <uuid> --approved-by <identity> \
  --approved-at <iso-time> --author-name <name> --author-email <email>

millctl --json new my-product --apply --attended \
  --prd product/PRD.md --sources product/sources.yaml \
  --proposal product/proposal.yaml --approve-product sha256:<product> \
  --approve-plan sha256:<integration-plan> --repository-id <uuid> \
  --approved-by <identity> --approved-at <iso-time> \
  --author-name <name> --author-email <email>

Greenfield apply stages and runs the complete native recipe gate before the target becomes a Git repository. It never replaces an existing path.

Adopt a compatible repository

Use the same two-step boundary with adopt --plan and then adopt --apply --attended. Adoption supports only the exact recipe-compatible Node/Next.js shape. It keeps the operator checkout unchanged, writes an isolated branch, and blocks on conflicting product truth, drifted native oracle files, unsafe Git state, symlinks, credential-like files, or incompatible versions.

Prepare dependencies separately because it is the only recipe step that needs registry network access:

millctl --json dependencies prepare --attended

Later verification has no network and receives read-only source.

Deliver one approved task

The downstream repository owns mill.yaml, product/contract.yaml, quality/scenarios.yaml, an approved impact manifest, and a version 2 task. Qualify the unchanged base, then use the returned digest once:

millctl --json qualify --baseline --task product/tasks/TASK.yaml
millctl --json run --task product/tasks/TASK.yaml \
  --approve sha256:<baseline-approval> --attended
millctl --json verify --task product/tasks/TASK.yaml --run <run-id>
millctl --json review --task product/tasks/TASK.yaml --run <run-id>

The shorter resumable path is:

millctl --json start --prd product/PRD.md --attended

millctl start selects exactly one approved ready outcome or resumes its sole existing lifecycle. It checks authority before dependency or model spend.

Open a reviewed draft PR

Raise trustCeiling to propose only after configuring the exact GitHub repository node ID, branch, allowed operator and merger, checks, review policy, and approval TTL in mill.yaml.

millctl --json pr plan --task product/tasks/TASK.yaml --run <run-id>
millctl --json pr open --task product/tasks/TASK.yaml --run <run-id> \
  --approve sha256:<delivery-plan> --attended
millctl --json pr observe --task product/tasks/TASK.yaml --run <run-id>
# By default, a human marks ready and merges in GitHub.
millctl --json pr finalize --task product/tasks/TASK.yaml --run <run-id>

Or use millctl ship --draft twice: first to return the proposal, then with its exact digest and --attended to perform it. Draft delivery never implicitly authorizes readiness or merge.

Approve a merge from your work surface

With propose.attendedMerge: true, producer-bound required checks, strict up-to-date protection enforced for administrators, and no bypass-role grants, the attending operator can inspect and approve:

millctl --json pr merge-plan --task product/tasks/TASK.yaml --run <run-id> --method squash
millctl --json pr merge --task product/tasks/TASK.yaml --run <run-id> \
  --approve sha256:<merge-plan> --attended
millctl --json pr finalize --task product/tasks/TASK.yaml --run <run-id>

The plan binds PR/head/base, exact tree, actor, method, policy and expiry. A chat host can submit the operator's approval through this CLI; Mill does not authenticate arbitrary chat messages or let the builder approve its own work. See attended approvals and recovery.

Mill checks classic branch-protection enforcement and exact check-producer bindings. The operator must separately inspect bypass-role/ruleset grants; do not infer a complete permissions audit from a successful merge preflight.

Compile follow-up work and adopt native brownfield commands

plan tasks --request product/change.yaml deterministically compiles an operator-supplied PRD/plan/bug/review change request and approved impact manifests into version-2 tasks and a dependency-checked outcome plan. Its separate --apply --approve sha256:<plan> --attended step writes an isolated worktree. It does not infer approval or acceptance tests from prose. See planning.

adopt-native --config adoption.yaml offers experimental Node ESM/npm adoption that adds only mill.yaml and mill.lock, preserving existing code and native scripts. Apply requires the exact digest and attendance; dependency preparation, baseline qualification and task execution remain separate. See brownfield scope and qualification.

Pull-request and resulting-main checks

The source implementation keeps propose.requiredChecks as the complete gate for the exact pull-request head. Optional propose.postMergeRequiredChecks selects a nonempty subset of those names for resulting-main readback only; omitting it retains the full requiredChecks list for both phases. New delivery plans approval-bind and persist both effective lists. Missing or pending required checks prevent completion; skipped or failed required checks fail the phase that requires them.

In this repository, dependency-review runs only for pull requests, while validate and codeql also run on pushes to main. The maintainer-prepared mill.yaml requires all three at the exact PR head and explicitly selects [validate, codeql] for resulting-main readback.

New delivery records identify the policy source as configured or implicit_default. A historical record with a full defaulted list and no provenance can bind the configured subset once only if its exact reviewed candidate proves omission of the optional policy and authoritative merge readback establishes every other delivery identity. That compatibility path cannot relax a new delivery. See repository settings and the migration record for the conditions and outstanding live evidence for delivery 01801a1b-58f9-480f-8cee-54ea2bbeabb2. Human readiness, merge authority, and exact candidate/tree checks remain required.

Trust model

Mill separates four principals:

Principal May do Cannot do
Builder Edit approved paths in a disposable worktree Push, merge, deploy, change authority or oracles
Verifier Run declared commands in bounded no-network OCI Write candidate source or use forge credentials
Reviewer Read the exact committed candidate Execute or edit code
Attended shipper Push/open a draft; separately approved opt-in readiness/merge Change the candidate, self-approve, bypass protection, or deploy

Codex uses your existing Codex CLI session and therefore your own provider billing. GitHub operations use your existing gh session. Another maintainer can clone Mill and use their own Codex and GitHub accounts after the downstream repo explicitly allows their identity. Mill stores neither credential.

The Codex worker runs on the trusted host with a workspace-write sandbox. This is not containment against hostile code, host files, keychains, processes, or network access. Native candidate verification is the stronger boundary: a pre-pulled digest-pinned OCI image, no network, read-only source/root, dropped capabilities, deadlines, bounded output and resources, and explicit cleanup. Do not use this alpha with hostile repositories or sensitive source.

millctl isolation --request trusted-host reports the exact built-in boundary. millctl isolation --request isolated fails closed because no isolated builder adapter has been qualified; run and resume accept the same --isolation option and will not silently fall back. See the reliability boundary.

Recovery

Every run has durable state and an append-only event history. If a controller is interrupted, inspect before acting:

millctl --json status --run <run-id>
millctl --json continuation --run <run-id>
millctl --json resume --task product/tasks/TASK.yaml --run <run-id>
millctl --json cancel --run <run-id>
millctl --json pr reconcile --task product/tasks/TASK.yaml --run <run-id>

Mill never signals a process solely from a stored PID and never retries an uncertain external effect without authoritative readback. Use explicit local recovery for state and diagnostics:

millctl --json state backup
millctl --json state restore --from /absolute/path/returned-backup.sqlite3
millctl --json state purge --confirm <repository-uuid>
millctl --json support-bundle --run <run-id>
millctl --json detach plan

status remains compact: it does not reveal the worktree, raw worker context, validation/review data, logs, private commit trailers, or credentials. Its continuation projection binds task/base/candidate/configuration identities, observed interruption/effect uncertainty, measured resource fields, and the next attended action without performing it. It reports provider-measured input, output, and cache-input tokens when present, partial fields when a completed call omitted them, and unavailable currency cost rather than an estimate.

An unresolved push, PR, readiness or merge blocks repair, new delivery and state purge/restore even if the enclosing run says blocked or cancelled. Cancellation records intent without discarding the receipt. Use pr merge-reconcile for readiness/merge; a confirmed merge then requires pr finalize and green main checks before cleanup. See approval recovery.

Before any remote attempt, stale review scope can use review --task product/tasks/TASK.yaml --run <run-id> --refresh --base <exact-provider-commit> --attended. This preserves the candidate and remaining review budget, invalidates the unexecuted delivery plan and does not move frozen Git refs. Plan delivery again after the fresh review passes.

For generated authority, state reconcile-plans verifies the exact committed files. A failed plan can instead be explicitly discontinued with state abandon-plan --approve <original-plan-digest> --attended, after preserving partial output in a clean commit on its recorded branch. Abandonment retains evidence and does not certify successful apply. See plan recovery.

Restore validates the database before atomic replacement and quarantines newer unreferenced worktrees. Detach is plan-only; the operator performs the reviewed removal. A generated/adopted repo must continue to build and test natively after Mill is removed.

Run purge from a surviving original checkout, never a worktree scheduled for deletion. Preserve an external state backup and committed candidate branches first. The known purge-from-a-deletable-worktree P2 can leave cleanup incomplete; it does not grant permission to discard unresolved effects or foreign files.

Audit and qualification

millctl audit is a bounded, read-only milestone check for Mill's selected recipe and release path. It requires a clean exact Git candidate and reports product, code, UX, accessibility, security, dependency, architecture, operations, and release checks in a schema-valid JSON envelope. These checks are labelled assurance: structural: they inspect contracts and hooks, not executed security, accessibility or business behavior. Native command results, realistic scenarios and release canaries are separate evidence.

millctl --json --cwd . audit
millctl --json --cwd . qualify public-alpha \
  --file /absolute/path/qualification.json

Public-alpha qualification requires at least five dependent accepted changes, item-level new-behavior and preservation evidence, a rejected and recovered seeded-fault branch, a current exact support tuple, every required packed and integration canary, and all nine audits. A later success cannot conceal an earlier unresolved preservation failure.

Every qualified release also requires two independent clean builds from the exact annotated tag, canonical content equality, a preserved tarball, SBOM, trusted npm OIDC publication, provenance, registry reinstallation, and GitHub Release readback. See the release runbook.

Troubleshooting

  • WRONG_MILL_VERSION: run the exact package version in mill.lock; Mill does not silently delegate to another version.
  • BASE_REF_DRIFT or context drift: stop, review the new repository state, and requalify. Never reuse the old approval digest.
  • missing OCI image: pull the exact digest explicitly outside Mill, then rerun readiness. Mill never pulls implicitly.
  • provider login failure: run codex login as the operator; do not pass a token through the task or repository.
  • GitHub identity or destination mismatch: correct mill.yaml or log in with the explicitly allowed gh identity. Do not weaken the binding.
  • effect_unknown: run read-only reconciliation. Do not retry push or PR creation until absence or success is authoritative.
  • active-run conflict: resume or safely terminalize the existing run; do not start a second writer.

Use GitHub Issues for reproducible defects and private vulnerability reporting for security issues. Support is best-effort with no SLA.

Limitations

  • local and attended only;
  • one repository, outcome, and writer at a time;
  • one exact web recipe and compatible adoption shape;
  • operator-supplied structured proposal, not autonomous planning research;
  • Codex and GitHub through the operator's existing sessions;
  • no hostile-host containment for the coding agent;
  • no daemon, hosted control plane, scheduler, fleet, or parallel agents;
  • no automatic readiness, merge, deployment, repository provisioning, or issue synchronization;
  • no general migration engine, automatic upgrade/rollback, or automatic detach;
  • no self-improvement loop or model-authored acceptance authority.

For system detail, read the product requirements, architecture, development guide, workflow, and agent operating contract.

About

Local-first software factory for new and existing codebases. Turns approved product intent into tested, reviewed PRs, with repo-native evidence and explicit human approval for delivery and merge.

Topics

Resources

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages