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
7 changes: 4 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -289,9 +289,10 @@ needs its own source authority, environment-policy authorization, and provider
readback; never use a wildcard or bypass the reviewer gate. Main branch
protections remain unchanged.

The current public version, npm channel pointers, GitHub Latest record, support
tuple, and expiry belong in the current `docs/releases/vX.Y.Z.md` record and
provider readback. They are distribution facts, not authority to broaden
The current npm channel pointers, GitHub Latest record, support tuple and expiry
belong in the protected workflow's final release-evidence asset and provider
readback. New immutable `docs/releases/vX.Y.Z.md` records state only the source
candidate's scope. These are distribution facts, not authority to broaden
supported stacks or autonomy. The v0.1.5 verifier remains the workflow's
independently pinned policy; do not silently replace it with the newest version.

Expand Down
30 changes: 16 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@ 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.6.0` is the published public alpha and GitHub Latest release. npm's
`alpha` tag resolves to `0.6.0`; its `latest` tag still resolves to `0.4.0`. The
tagged `0.5.0` candidate failed before publication because its workflow received
malformed qualification input; its tag and failed run remain preserved evidence.
See the [v0.5.0 release record](docs/releases/v0.5.0.md). The `v0.1.5` genesis
release remains the historical trust root; the `v0.2.0` tag remains preserved
prepublication evidence.
Release channels and exact artifact evidence are facts of a particular
publication. Read the
[latest GitHub release](https://github.com/davidahmann/mill/releases/latest),
its attached `release-evidence-final.json`, and
`npm view @davidahmann/mill dist-tags --json` before selecting a version. GitHub
Latest and npm `latest` are separate provider pointers. The `v0.1.5` genesis
release remains the historical trust root; failed release candidates remain
preserved evidence.

## Why Mill

Expand Down Expand Up @@ -140,11 +141,13 @@ qualified web recipe.

## Install

Install the current public alpha at its exact version with lifecycle scripts
disabled:
Inspect the available channels, choose a released version, and pin that exact
version with lifecycle scripts disabled. Do not install a floating tag into an
existing repository.

```sh
npm install --save-dev --ignore-scripts @davidahmann/mill@0.6.0
npm view @davidahmann/mill dist-tags --json
npm install --save-dev --ignore-scripts @davidahmann/mill@<released-version>
npx --no-install millctl --version
```

Expand All @@ -161,11 +164,10 @@ PATH="$node_bin_dir:$PATH" "$node_bin_dir/npm" run build
node dist/cli.js --version
```

The `alpha` tag resolves to `0.6.0`; `latest` still resolves to `0.4.0`.
Downstream repositories should pin the exact version so a later release cannot
alter their delivery machinery implicitly. Updating an existing Mill
Downstream repositories should pin the exact selected 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
release evidence, and requalify the changed toolchain. There is no automatic
upgrade or proven general downgrade path for operational state.

### Policy starters for downstream repositories
Expand Down
17 changes: 12 additions & 5 deletions docs/release.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,11 +200,18 @@ publishes the normal GitHub Release.

### 5. Close the release

Record the workflow run, tag commit/tree, tarball digest/integrity, npm tarball
and provenance, GitHub Release URL and asset digest, qualification digest,
support tuple, and canary window. Reinstall the exact newly qualified version in
an empty directory with lifecycle scripts disabled and confirm its version and
help.
The protected workflow attaches `release-evidence-final.json` to the normal
GitHub Release after provider readback. It records the workflow runs, tag
commit/tree, tarball digest/integrity, npm tarball and provenance, GitHub
Release URL and asset digests, qualification digest, support tuple, and canary
window. That asset is the canonical provider closure. Reinstall the exact newly
qualified version in an empty directory with lifecycle scripts disabled and
confirm its version and help.

The immutable `docs/releases/vX.Y.Z.md` file records source scope before
tagging. Do not add a source-only follow-up merely to repeat provider facts
after publication. Link users to the release evidence and require an exact
version pin.

The release becomes the trust root for qualifying the next candidate. It does
not qualify a new stack, host tuple, worker profile, model identity, or forge.
Expand Down
21 changes: 21 additions & 0 deletions docs/releases/v0.6.1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Mill v0.6.1

`0.6.1` is a public-alpha maintenance-release candidate. It exercises the
protected npm OIDC path that publishes a newly qualified artifact directly to
`latest`. It also makes installation guidance release-stable: users inspect the
live release evidence, choose an exact version, and pin it in their repository.

## Candidate scope

The release does not alter Mill's supported recipe, delivery authority, worker
boundary, or public-alpha limits. It does not modify the published `0.6.0`
artifact or its npm tags. It does not create or use a bypass-2FA token.

## Prepublication record

This file is part of the immutable release candidate. It records intended scope
before tag creation and publication. The protected release workflow attaches
`release-evidence-final.json` to the public GitHub Release after it verifies the
preserved artifact, npm provenance, registry requalification, the `latest`
channel, and GitHub asset readback. That immutable asset is the canonical
provider closure for this release.
18 changes: 9 additions & 9 deletions docs/repository-settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,12 @@ admission change, not a protection bypass or an npm token grant. Future release
tags require their own explicit policy authorization; do not replace the exact
tag rules with a wildcard or an unrestricted environment.

## Current distribution channels

The current release record captures GitHub Latest, npm channel values, and the
named public release identity from provider readback. A later correction to an
existing channel uses the provider's supported maintainer authentication. Do not
create a bypass-2FA token for that purpose. A draft and public release can share
a tag, so recovery must use the public release identity rather than a tag-only
lookup. Channel labels do not expand Mill's qualified public-alpha support tuple
or authorize republishing.
## Distribution channels

The protected workflow attaches final release evidence with GitHub Latest, npm
channel values and public release identity after provider readback. A later
correction to an existing channel uses the provider's supported maintainer
authentication. Do not create a bypass-2FA token for that purpose. A draft and
public release can share a tag, so recovery must use the public release identity
rather than a tag-only lookup. Channel labels do not expand Mill's qualified
public-alpha support tuple or authorize republishing.
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.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@davidahmann/mill",
"version": "0.6.0",
"version": "0.6.1",
"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 Down
11 changes: 5 additions & 6 deletions product/PLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,11 @@ reference, confines a second repair to one fixture, limits the packed public API
to CLI and schemas, and validates release input encoding. It preserves the
v0.5.0 failed candidate as evidence and does not add a GitHub App, second
worker, general retry increase, daemon, MCP service, or public support claim.
Version `0.6.0` completed candidate qualification, protected OIDC publication,
registry requalification, and a normal GitHub Release on 2026-09-15. Its npm
`alpha` tag resolves to `0.6.0`; the existing `latest` tag remains `0.4.0`
because npm rejected the later tag change without a TOTP. Mill stores no bypass
token. Future fresh releases publish directly to `latest` through the protected
OIDC workflow.
The v0.6.0 release record retains its candidate qualification, protected OIDC
publication, registry requalification, normal GitHub Release and unchanged npm
channel state. Mill stores no bypass token. Future fresh releases publish
directly to `latest` through the protected OIDC workflow, whose final release
evidence is the canonical provider closure.

1. **Foundation:** repository constitution, exact-version CLI, compact schemas,
static source/repository inspection, native CI, and security/release design.
Expand Down
33 changes: 33 additions & 0 deletions product/impacts/RELEASE_V0_6_1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
schemaVersion: "2"
id: mill-release-v0.6.1
status: approved
approved_by: davidahmann
approval_source: >-
Attended Codex conversation on 2026-09-15: “Ok do what is needed until all is
green,” following explicit authorization for Mill release, npm publication,
GitHub Release creation, documentation updates, and provider readback.
source_base: 3ba27571af6447abf3100b2b35e673031e82fcb7
authority: product/release-v0.6.1.md
affected_invariants:
- INV-HUMAN-AUTHORITY
- INV-EXACT-EVIDENCE
- INV-DOWNSTREAM-INDEPENDENT
material_changes:
- Advances the package and CLI identity to v0.6.1.
- Exercises protected OIDC publication directly to npm latest with one
preserved qualified artifact.
- Keeps public installation guidance release-stable and assigns exact provider
facts to final release evidence.
affected_surfaces:
- package and CLI version identity
- public installation, release, repository-settings and operator guidance
- exact release authority, npm environment admission and public distribution
verification:
- native check, exact-candidate audit, clean PR review and required checks
- exact annotated-tag identity and two independent candidate builds
- independent policy, registry package, npm provenance/latest and GitHub asset
readback
exceptions:
- The attended maintainer may add the exact v0.6.1 npm-environment tag rule,
create and push the annotated tag, publish one preserved artifact, and
create the normal GitHub Release only as bound by the authority record.
39 changes: 39 additions & 0 deletions product/release-v0.6.1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# v0.6.1 attended release authority

## Authorization

David Ahmann authorized this release in the attended Codex conversation on
2026-09-15: “Ok do what is needed until all is green.” This follows the earlier
explicit authorization for release, npm publication, GitHub Release creation,
and documentation updates.

The authorization covers one fresh `v0.6.1` public-alpha release from the
reviewed source candidate: an exact GitHub `npm` environment tag rule, an
annotated tag, candidate and protected publish workflows, one preserved npm
artifact, a normal GitHub Release, and provider readback. The source change
prepares version-stable installation and closure documentation.

It does not authorize a wildcard, bypass-2FA token, weaker trusted publishing, a
change to an existing npm dist-tag, a republish, a change to an older tag or
release, or a broader support claim.

## Scope and stop conditions

The source candidate starts from reviewed `main` commit
`3ba27571af6447abf3100b2b35e673031e82fcb7`. Its package and CLI version are
`0.6.1`. The exact annotated tag must bind the reviewed resulting-main tree.

Stop before publication if the candidate tag, source tree, preserved artifact,
candidate run, qualification, npm provenance, registry readback, `latest`
channel, or GitHub asset identity differs. A failed candidate or uncertain
external effect requires a new reviewed version. It never permits retagging,
republishing, or updating the published `0.6.0` package.

## Required closure

The protected workflow must attach `release-evidence-final.json` to the normal
GitHub Release only after provider readback. It records the tag commit and tree,
candidate and publish runs, tarball digest and integrity, qualification digest,
npm provenance and channels, GitHub Release identity and asset digests, and the
exact support tuple. That release asset is the canonical closure; no later
source commit may rewrite the tagged candidate or duplicate provider facts.
59 changes: 59 additions & 0 deletions product/tasks/RELEASE_V0_6_1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
schemaVersion: "2"
task_id: mill-release-v0.6.1-source-preparation
status: closed
owner: davidahmann
base_commit: 3ba27571af6447abf3100b2b35e673031e82fcb7
execution_mode: approved_native_maintainer
authority: product/release-v0.6.1.md
impact_manifest: product/impacts/RELEASE_V0_6_1.yaml
objective: >-
Prepare the exact v0.6.1 public-alpha source candidate and release-stable
documentation for protected OIDC publication directly to npm latest.
allowed_paths:
- package.json
- package-lock.json
- src/version.ts
- scripts/release-workflow-policy.mjs
- test/release-workflow.test.ts
- README.md
- AGENTS.md
- docs/release.md
- docs/repository-settings.md
- docs/releases/v0.6.1.md
- product/PLAN.md
- product/release-v0.6.1.md
- product/impacts/RELEASE_V0_6_1.yaml
- product/tasks/RELEASE_V0_6_1.yaml
authority_preparation_paths:
- product/**
- docs/releases/**
acceptance_items:
- R061-01 package and CLI identify v0.6.1
- R061-02 public installation guidance requires a live provider check and an
explicit exact version pin rather than a hard-coded current version
- R061-03 the release runbook, repository settings and operator contract name
final release evidence as the canonical provider closure
- R061-04 native check, exact-candidate audit, complete review and required PR
checks pass
- R061-05 only the release authority may add the exact tag rule, tag, publish
one preserved artifact and create the normal GitHub Release
validation_commands:
- npm run check
- node dist/cli.js --json --cwd . audit
- MILL_RELEASE_TAG=v0.6.1 node scripts/verify-release-tag.mjs
required_reviews:
- required PR checks and GitHub review feedback on the complete committed Mill
release-preparation diff
constraints:
- single attended maintainer writer
- exact v0.6.1 environment-tag admission only; no wildcard or bypass
- preserve all historical tags, npm versions, releases and evidence
stop_conditions:
- ambiguous tag, tree, artifact, candidate-run, provenance or provider effect
- unavailable independent verification or recurring P0/P1 release finding
closure:
status: source_candidate_prepared
provider_closure: >-
The protected release workflow must attach final evidence after its own
provider readback. No post-release source update may alter the tagged
candidate or duplicate those provider facts.
15 changes: 14 additions & 1 deletion scripts/release-workflow-policy.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -139,15 +139,28 @@ export function releasePublicationFailures(jobs) {
"publish: GitHub release must be a plainly labelled normal public-alpha release",
);
}
const finalEvidenceUpload =
'gh release upload "$RELEASE_TAG" "$RUNNER_TEMP/release-evidence-final.json"';
const finalRelease = 'gh release edit "$RELEASE_TAG" --draft=false';
if (
typeof finalize?.run !== "string" ||
!finalize.run.includes('gh release edit "$RELEASE_TAG" --draft=false') ||
!finalize.run.includes(finalRelease) ||
finalize.run.includes("--prerelease")
) {
failures.push(
"publish: final GitHub release must remain a normal public-alpha release",
);
}
if (
typeof finalize?.run !== "string" ||
!finalize.run.includes(finalEvidenceUpload) ||
finalize.run.indexOf(finalEvidenceUpload) >
finalize.run.indexOf(finalRelease)
) {
failures.push(
"publish: final release evidence must be attached before publication",
);
}
return failures;
}

Expand Down
2 changes: 1 addition & 1 deletion src/version.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export const MILL_PACKAGE = "@davidahmann/mill";
export const MILL_VERSION = "0.6.0";
export const MILL_VERSION = "0.6.1";
export const RESULT_SCHEMA_VERSION = "1";
15 changes: 15 additions & 0 deletions test/release-workflow.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,21 @@ describe("release verifier preparation policy", () => {
);
},
);
it("rejects a public release that omits final release evidence", async () => {
const workflow = await fixture();
const finalize = workflow.jobs.publish?.steps.find(
(entry) =>
entry.name === "Read back GitHub Release and finalize evidence",
);
if (!finalize?.run) throw new Error("missing release finalization fixture");
finalize.run = finalize.run.replace(
'gh release upload "$RELEASE_TAG" "$RUNNER_TEMP/release-evidence-final.json"',
"true",
);
await expect(check(workflow)).rejects.toThrow(
"final release evidence must be attached before publication",
);
});
it.each(["alpha", "missing-readback"])(
"rejects a %s npm latest publication contract",
async (mutation) => {
Expand Down