Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ updates:
groups:
development:
dependency-type: development
update-types:
- minor
- patch
ignore:
- dependency-name: "@types/node"
update-types:
Expand Down
12 changes: 11 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# AGENTS.md: operating Mill safely

Version: 2.5
Version: 2.6

Status: normative

Expand All @@ -16,6 +16,11 @@ restrictions solely for the approved attended merge workflow. Builder and
reviewer forge exclusions remain in force. Historical bootstrap exceptions
remain closed. All release effects require their own verified identities.

The owner approved the review/delivery follow-through on 2026-09-21. Its scope
and checks are in `product/review-delivery-follow-through.md`. Use the native
maintainer path for these Mill control changes; it does not grant a builder
permission to modify its own frozen controls.

## Operating Mill

Mill turns approved repository-native product intent into a bounded, tested,
Expand Down Expand Up @@ -181,6 +186,11 @@ two-step plan/apply wrapper, never as implicit push authority.
one systemic repair generation; do not churn one PR per comment. A task may
use two generations only through its explicit `fixture_only` experiment; each
repaired candidate requires fresh validation and review.
- A repository may approve top-level `review: { blocking: p0_p1 }` before run
admission. The controller records the classification against frozen config.
Preserve every finding; only P0/P1 require repair under that policy. Legacy
reviews retain their original blocking rules. Required GitHub approval remains
separate. See `docs/review-policy.md`.
- Before any remote attempt, stale full-diff scope may use attended
`review --refresh --base <exact-provider-commit>`. Preserve candidate, native
validation, prior receipts, deadline and remaining review budget; do not move
Expand Down
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,21 @@ All notable changes follow Keep a Changelog and Semantic Versioning.

## [Unreleased]

## [0.8.0] - 2026-09-21

### Added

- Optional frozen P0/P1 review policy with retained advisory findings across
review, repair, draft delivery, merge and outcome reporting.
- Packaged exact-candidate maintainer review and receipt checking.
- Dependency policy validation for Mill and the downstream starter.

### Fixed

- Redact private review and repair payloads from support event output.
- Exclude scratch worktrees from local tests and lint.
- Correct starter Dependabot grouping syntax and keep routine majors separate.

## [0.7.2] - 2026-09-19

### Fixed
Expand Down
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,14 +158,14 @@ existing repository.

```sh
npm view @davidahmann/mill dist-tags --json
npm install --save-dev --save-exact --ignore-scripts @davidahmann/mill@0.7.2
npm install --save-dev --save-exact --ignore-scripts @davidahmann/mill@0.8.0
npx --no-install millctl --version
```

The example selects this source candidate's version, `0.7.2`. Use it after the
The example selects this source candidate's version, `0.8.0`. Use it after the
linked release's final evidence confirms publication; an unpublished source
candidate is not an installable release. See the
[v0.7.2 scope](docs/releases/v0.7.2.md) and
[v0.8.0 scope](docs/releases/v0.8.0.md) and
[planning evidence rules](docs/planning.md#what-passing-evidence-means).

To develop Mill itself from a clean source checkout:
Expand Down Expand Up @@ -261,6 +261,12 @@ Mill never treats these commands as approval to mark ready, merge, deploy, or
release. See the [glossary](docs/glossary.md) before creating or reviewing
authority files.

Repositories may approve `review: { blocking: p0_p1 }` in `mill.yaml` before
admitting a run. Mill retains every finding; P0/P1 block and standalone P2/P3
remain advisory. Existing receiptless reviews keep their previous rules. See
[review policy and preparation](docs/review-policy.md). Changes outside admitted
runs use the [maintainer review route](docs/maintainer-review.md).

## Expert reference

### Discover a TypeScript repository
Expand Down
4 changes: 4 additions & 0 deletions WORKFLOW.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ bookkeeping, closure, tests, or docs into micro-PRs.
integration approvals.
5. Audits, clean-room qualification, genesis distribution, and public alpha.

For native maintainer changes outside an admitted run, use the packaged
[local review script](docs/maintainer-review.md). It records exact-candidate
validation and independent review without claiming runtime delivery authority.

For each wave:

1. Freeze one task brief with scope, exclusions, commands, acceptance items,
Expand Down
10 changes: 10 additions & 0 deletions architecture/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -467,3 +467,13 @@ The release workflow is not a daemon, deployment service, or autonomous release
authority. Tagging, publication, and GitHub Release creation remain distinct
maintainer-authorized effects. Support attaches only to the non-expired exact
tuple and recipe in final evidence.

## Review policy evidence

The optional top-level `review.blocking: p0_p1` setting is frozen in the run's
configuration digest. A controller-owned review gate partitions the unchanged
finding IDs into blocking and advisory sets. The worker cannot supply that
receipt. State, delivery, refresh, merge and outcome readers validate the
partition and config identity. A missing receipt preserves legacy behavior.
Delivery records also retain the remote-feedback policy; required GitHub
approval is evaluated separately. See [the policy](../docs/review-policy.md).
7 changes: 7 additions & 0 deletions docs/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -350,3 +350,10 @@ Before medium/high-risk code, answer:
Run one architecture/threat pass before medium/high-risk implementation and one
complete exact-candidate review after validation. Batch all actionable findings
into one systemic repair. Recurring same-subsystem P1 findings return to design.

Use [review policy and preparation](review-policy.md) to select blocking
severity before admission and qualify the test infrastructure on the base.
Native maintainer changes use the
[standalone review route](maintainer-review.md). Dependabot grouping is checked
by `npm run check:dependabot`; the checker covers Mill's bounded update policy
and the shipped starter, not GitHub's full schema.
71 changes: 71 additions & 0 deletions docs/maintainer-review.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Local review for maintainer and dependency changes

Use this route for a committed change that has no admitted Mill task, including
Dependabot updates. It runs the validation command you select, then invokes a
fresh Codex reviewer in read-only mode. P0/P1 findings block; P2/P3 findings
stay in the receipt as advisory. The operator still decides whether the selected
validation covers the change.

Run from a clean repository root, with dependencies already prepared. Supply
full commit IDs. The base must be an ancestor of the candidate, and the
candidate must be the current HEAD. Store the receipt outside the repository.

Git replacement refs, grafts, hidden index flags and repository/environment
overrides that can change the inspected bytes are rejected. Local and worktree
Git configuration must use supported static settings; executable helpers,
includes and transforming attributes are unsupported. The receipt also binds Git
control-file digests, so configuration drift requires a new review. The
validation and reviewer processes disable replacement objects and grafts.

```sh
node /path/to/mill/scripts/maintainer-review.mjs run \
--base <full-base-commit> --head <full-candidate-commit> \
--validation '["npm","run","check"]' \
--receipt /private/review-evidence/candidate.json

node /path/to/mill/scripts/maintainer-review.mjs check \
--base <full-base-commit> --head <full-candidate-commit> \
--receipt /private/review-evidence/candidate.json
```

For an installed package, the script is at
`node_modules/@davidahmann/mill/scripts/maintainer-review.mjs`. Keep the same
script version for recording and checking a receipt. A changed script, base,
candidate, tree, or dirty checkout requires fresh evidence. The checker does not
fetch the provider base; the operator must supply its current exact commit.

The validation argument is an argv array, not a shell expression. It executes
with the operator's environment and authority. Choose the repository's native
checks, and do not put secrets in command arguments. Each command has a
30-minute timeout and a bounded output buffer. Failed or excessive output blocks
evidence creation; rerun the command directly to diagnose it. The receipt stores
a digest of validation stdout, not raw logs.

Codex uses its existing local login. Its process receives no standard GitHub or
npm token environment variables. Strict configuration and the read-only sandbox
reduce accidental mutation; they do not isolate a hostile host or remove
credentials stored elsewhere on that host. This route is for trusted maintainer
checkouts. It performs no push, PR, merge or release operation.

## Keeping review rounds bounded

Each receipt preserves the full finding list, candidate identity, subsystem and
blocking/advisory disposition. Keep earlier receipts when the candidate changes.
Review all P0/P1 findings together and make one coherent repair, then validate
and review the new exact candidate. If P0/P1 findings recur in the same
subsystem, stop and revisit its design and acceptance coverage before another
repair. The operator compares the receipts; the script does not infer semantic
equivalence or automatically decide that a subsystem has converged.

## What the receipt establishes

The checker detects missing fields, malformed findings, candidate drift and
inconsistent dispositions. It does not authenticate the author of a receipt: a
user with filesystem access can manufacture or edit local evidence. It is
neither an admitted Mill run receipt nor a trusted CI producer attestation.

Use it as an attended pre-push check for maintainer changes. Dependabot has
already pushed its branch, so review its exact candidate before merge. An
optional local hook can invoke the checker but can be bypassed. Enforcing this
policy on GitHub requires a separately trusted required-check producer; this
script does not install one or claim that ordinary Git pushes are intercepted.
16 changes: 16 additions & 0 deletions docs/releases/v0.8.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Mill 0.8.0

This source candidate adds an optional, frozen P0/P1 review policy. Advisory
findings remain recorded through delivery and outcome reporting. Existing
receiptless reviews keep their previous blocking rules.

The package includes a standalone maintainer review script for changes outside
admitted runs. It records local validation and independent exact-candidate
review; it is not a trusted CI attestation or permission to push or merge.
Documentation explains preparation probes using the existing baseline command
lane and the operator's responsibility to stop recurring P1 repair loops.

Dependency policy checks cover Mill and its shipped starter. Publication, npm
`latest`, GitHub Latest and exact qualification are established by the protected
workflow's final release evidence, not this source record. No new stack or
customer-compatibility claim is made.
63 changes: 63 additions & 0 deletions docs/review-policy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Review policy and preparation

Approve review policy before admitting the task. To make standalone P2/P3
findings advisory, add this top-level setting to `mill.yaml`:

```yaml
review:
blocking: p0_p1
```

The setting applies at build and propose trust ceilings. Mill binds it to the
run's configuration digest. After the read-only reviewer returns its report, the
controller records which finding IDs block. It preserves the complete report and
checks that classification at review completion, repair, review refresh,
delivery, merge and outcome projection. An advisory-only report has outcome
status `advisories`; it is not described as an empty or clean report.

Without the setting, local review still blocks every finding. Existing reviews
without a classification receipt keep that rule, even after upgrading Mill.
Required GitHub feedback keeps its legacy P0/P1/P2 blocking rule unless the new
policy was frozen for that delivery. Unclassified feedback blocks. An explicit
required GitHub approval remains required; advisory findings do not turn a
rejection or missing approval into approval.

Changing policy does not repair an existing blocked run. Preserve its evidence
and use a separately approved admission when its configuration, deadline or
budget no longer permits continuation. Do not edit a stored receipt, reset a
budget, or relabel a concrete P1 failure as advisory to ship it.

## Qualify test infrastructure before model work

Use the existing version-2 `baselineCommandIds` lane for preparation probes.
Declare the commands and their control paths in `mill.yaml`, then select them
for baseline qualification. Keep preservation checks in that selection. New
behavior checks remain in the task's candidate `commandIds`; an unimplemented
feature need not pass before the builder starts.

Preparation probes should exercise the actual verifier image and the same
client/transport used by the acceptance tests. For an HTTP fixture, prove that
hostile headers reach the listener, redirects follow the declared rules, and SDK
URL handling matches the test's assumptions. For file snapshots, prove that
fault injection fires and cleanup runs after failure. A failed baseline returns
no approval digest and cannot authorize a builder run.

Before freezing an oracle, map each acceptance requirement to its assertion and
include representative wrong implementations or injected faults that it must
reject. Mill checks declared evidence references; it cannot infer whether an
assertion captures the intended behavior. Test authors and independent reviewers
own that judgment.

## Keep one repair batch

The private review-completion event retains the full report and classification.
Repair receives blocking findings; advisory findings remain evidence. The
existing repair budget still applies. If P0/P1 findings recur in the same
subsystem, return to design and acceptance coverage before spending another
repair. That subsystem judgment belongs to the operator; Mill enforces the
repair budget but does not infer semantic recurrence.

For changes outside an admitted run, use the
[maintainer review script](maintainer-review.md). Keep earlier receipts so the
reviewer can distinguish a repeated defect from a new one. Ordinary Git pushes
are not intercepted by Mill.
6 changes: 6 additions & 0 deletions docs/run-outcome.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,9 @@ The second synthetic webhook replay in
uses a separate frozen provider transition and workflow/configuration matrix.
Its deterministic worker and OCI adapters exercise Mill's lifecycle mechanics;
they do not contact a provider or establish customer compatibility.

Under the approved P0/P1 review policy, `review.status: advisories` means the
review gate passed with retained P2/P3 findings. `clean` means no findings were
reported. Counts include every finding. Receiptless legacy reviews keep their
original blocking rules; a newer checkout does not reinterpret them. See
[review policy](review-policy.md).
8 changes: 7 additions & 1 deletion eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@ import tseslint from "typescript-eslint";

export default tseslint.config(
{
ignores: ["coverage/**", "dist/**", "node_modules/**", "recipes/**"],
ignores: [
"coverage/**",
"dist/**",
"node_modules/**",
"recipes/**",
".mill-scratch/**",
],
},
eslint.configs.recommended,
...tseslint.configs.strictTypeChecked,
Expand Down
2 changes: 2 additions & 0 deletions mill.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
schemaVersion: "1"
repositoryId: 889e67bd-0768-4f73-9e18-286f2fb8b5f3
trustCeiling: propose
review:
blocking: p0_p1
reporting:
ledgerPath: quality/development-evidence-ledger.yaml
sensitivePaths: [".env", ".npmrc", ".mill/**"]
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 6 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@davidahmann/mill",
"version": "0.7.2",
"version": "0.8.0",
"description": "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.",
"license": "Apache-2.0",
"author": "David Ahmann",
Expand All @@ -14,7 +14,8 @@
"recipes/",
"schemas/",
"README.md",
"LICENSE"
"LICENSE",
"scripts/maintainer-review.mjs"
],
"exports": {
"./schemas/*.json": "./schemas/*.json"
Expand All @@ -41,8 +42,9 @@
"test": "vitest run --configLoader native",
"test:coverage": "vitest run --configLoader native --coverage",
"test:package": "npm run clean && npm run build && node scripts/test-package.mjs",
"check": "npm run format:check && npm run lint && npm run typecheck && npm run docs:check && npm run check:workflows && npm run schemas:check && npm run test:coverage && npm run test:package",
"prepack": "npm run clean && npm run build"
"check": "npm run format:check && npm run lint && npm run typecheck && npm run docs:check && npm run check:workflows && npm run check:dependabot && npm run schemas:check && npm run test:coverage && npm run test:package",
"prepack": "npm run clean && npm run build",
"check:dependabot": "node scripts/check-dependabot.mjs"
},
"dependencies": {
"commander": "15.0.0",
Expand Down
7 changes: 7 additions & 0 deletions policy-starters/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,10 @@ to branch protection through the target repository's own reviewed settings.
Add `node scripts/check-docs.mjs` to the target repository's native validation
script. The starter detects local-link and stock-phrase mistakes; pair it with a
review of the changed prose and the technical source that supports each claim.

Routine development updates are grouped only for minor and patch versions. Keep
qualification-sensitive upgrades, such as compiler or runtime majors and the
downstream Mill pin, deliberate. The verified Dependabot DCO exception is not an
exemption from reviewing manifests, lockfiles and affected behavior. Mill's
standalone maintainer review script can record that exact-candidate review
before merge; it does not install a required GitHub check.
4 changes: 2 additions & 2 deletions policy-starters/node-npm/.github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ updates:
development-minor-and-patch:
dependency-type: development
update-types:
- version-update:semver-minor
- version-update:semver-patch
- minor
- patch
open-pull-requests-limit: 5
- package-ecosystem: github-actions
directory: /
Expand Down
Loading