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
11 changes: 11 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ The owner approved the bounded verifier recovery repair on 2026-09-21. Its
authority and acceptance are in `product/verifier-recovery.md`. Use the native
maintainer route; preserve downstream task and candidate identities.

The owner approved the GitHub Codex review follow-through on 2026-09-21. Its
authority and acceptance are in `product/github-codex-review-follow-through.md`.
Use the native maintainer route and preserve the existing local and GitHub
approval policies.

## Operating Mill

Mill turns approved repository-native product intent into a bounded, tested,
Expand Down Expand Up @@ -195,6 +200,12 @@ two-step plan/apply wrapper, never as implicit push authority.
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`.
- `propose.reviewPolicy.mode: github_codex_required` requires the named GitHub
Codex actor's completed summary on the exact PR head. If marking a draft ready
triggers review, execute and verify readiness only. Observe review completion,
then approve a new merge plan bound to the exact review and feedback snapshot.
Running, stale, malformed, unclassified, or P0/P1 feedback blocks. Never treat
readiness approval as merge approval.
- 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
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,24 @@ All notable changes follow Keep a Changelog and Semantic Versioning.

## [Unreleased]

## [0.9.0] - 2026-09-21

### Added

- Add a GitHub Codex review mode that requires exact-head completion, retains
hosted feedback, and binds that evidence into attended merge approval.
- Split draft readiness from merge when readiness starts hosted review.

### Fixed

- Recheck required hosted review and feedback during post-merge closure.
- Reject hosted-review drift between merge planning and execution.

### Changed

- Shorten the installation command and rewrite the README around the first
reviewed pull request, trust boundary, supported scope, and recovery path.

## [0.8.1] - 2026-09-21

### Fixed
Expand Down
753 changes: 185 additions & 568 deletions README.md

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions architecture/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,9 @@ exact human-authored task + product/scenario/policy digests
-> reviewed local candidate or one repair-and-revalidate cycle
-> exact actor/repository/remote proposal digest
-> expected-head push + immutable-marker draft PR
-> exact-head CI and optional GitHub-review observation
-> human readiness and merge
-> exact-head CI and configured GitHub-review observation
-> separately approved readiness when hosted review starts there
-> completed exact-head hosted review and separately approved merge
-> exact merge/tree/default-branch check readback and closure
```

Expand Down
21 changes: 17 additions & 4 deletions docs/approvals.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,30 @@ method and readiness action. `merge` and `squash` are the available request
methods; squash requires the existing `linear_tree_preserving` policy. The
operator is reauthenticated through the configured local `gh` session.

With `github_codex_required`, a draft can still be in `awaiting_ci` after its
checks pass because hosted review has not started. `pr merge-plan` may then
produce a readiness-only plan. Applying it marks the exact PR ready, verifies
that effect, and stops. Wait for GitHub Codex, run `pr observe`, address any
P0/P1 or unclassified feedback, and request a new merge plan. That second plan
includes the digest of the completed exact-head review and feedback snapshot.
Mill rereads the snapshot immediately before merge and rejects drift.

Do not reuse the readiness approval for merge. A `ready_verified` receipt is
evidence that the PR left draft state; it is not hosted-review completion or
merge authority.

A trusted chat integration must authenticate its operator and obtain their
approval of this exact displayed plan before invoking the CLI. The local
`attended_operator` receipt is not a signed chat event, an identity federation
service, or proof that an arbitrary message was human-authored. Keep this
capability outside all model-controlled builder/reviewer tool bundles.

Mill rechecks policy, native validation, full-diff review, current GitHub
review, feedback and CI before effects. GitHub's merge API compares the exact PR
head; it does not offer an atomic base-SHA comparison. Strict branch protection
and fresh base checks constrain that race, and exact merged-tree readback is
still required. Do not interpret an API success as verified lifecycle closure.
review, feedback and CI before effects and during post-merge closure. GitHub's
merge API compares the exact PR head; it does not offer an atomic base-SHA
comparison. Strict branch protection and fresh base checks constrain that race,
and exact merged-tree readback is still required. Do not interpret an API
success as verified lifecycle closure.

Draft planning, push and PR creation compare the locally reviewed merge-base
diff with GitHub's authoritative base SHA. An unpushed preparation commit on
Expand Down
22 changes: 22 additions & 0 deletions docs/releases/v0.9.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Mill 0.9.0

This source candidate adds an explicit GitHub Codex review policy. It recognizes
the hosted review summary only when it reports completion for the exact pull
request head, evaluates the named actor's current-head feedback, and binds that
review snapshot into merge approval.

Because GitHub Codex starts after a draft becomes ready, Mill now supports a
readiness-only attended plan for that policy. It verifies readiness and stops.
The operator must observe completed hosted review and approve a second exact
plan before merge. P0/P1 and unclassified feedback block under the approved
P0/P1 policy; standalone P2/P3 remains recorded and advisory. Post-merge
readback checks the same policy before closure.

The README now leads with a short exact installation command and one successful
path from repository inspection to a reviewed draft pull request. Detailed
policy, recovery, and release procedures remain in focused documents.

Publication and npm/GitHub channel pointers are established by the protected
workflow's final release evidence. This source record grants no new stack,
customer-compatibility, provider-behavior, deployment, or unattended-operation
claim.
9 changes: 6 additions & 3 deletions docs/repository-settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,12 @@ After the Wave 1 checks have run at least once, configure:
- maintainer bypass allowed only for emergencies and recorded as repair/audit
intake.

`CODEOWNERS` routes ownership but must not deadlock the sole maintainer. GitHub
Codex review is optional repository policy in v1; frozen local review and
required machine checks are portable and mandatory.
`CODEOWNERS` routes ownership but must not deadlock the sole maintainer. Frozen
local review and required machine checks remain mandatory. A downstream
repository can additionally select `github_required` for ordinary GitHub
approvals or `github_codex_required` for GitHub Codex completion and feedback.
The latter uses a separate readiness approval because the hosted review begins
after draft state ends. See [review policy](review-policy.md).

## Check names and workflow events

Expand Down
36 changes: 36 additions & 0 deletions docs/review-policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,42 @@ 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.

## GitHub review modes

`propose.reviewPolicy` has three modes:

- `local_only` uses Mill's required exact-candidate local review and does not
wait for a GitHub reviewer.
- `github_required` additionally requires an `APPROVED` review from every named
login on the exact PR head.
- `github_codex_required` additionally requires the GitHub Codex summary comment
from every named login to report `Completed` for the exact PR head. GitHub
Codex posts findings as review comments rather than an approving review, so
this mode treats its exact-head summary as completion evidence and evaluates
its current-head feedback separately.

GitHub reports the Codex App login with its bot suffix:

```yaml
reviewPolicy:
mode: github_codex_required
requiredReviewerLogins: ["chatgpt-codex-connector[bot]"]
```

Confirm the login from the target repository's API before freezing policy. Mill
compares it exactly.

For `github_codex_required`, a running, missing, malformed, or stale summary is
not completion. P0/P1 and unclassified feedback block when the frozen review
policy is `p0_p1`; standalone P2/P3 remains recorded and advisory. Mill binds
the complete required-actor review and feedback snapshot into the merge plan.
Any change before merge invalidates that approval.

GitHub Codex begins its hosted review after a draft is marked ready. With
attended merge enabled, Mill therefore uses two approvals: the first may only
mark an exact, green draft ready; after `pr observe` records completed review,
the second may authorize merge. The first approval cannot merge the PR.

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
Expand Down
4 changes: 2 additions & 2 deletions mill.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ propose:
pullRequestEvent: pull_request
postMergeEvent: push
reviewPolicy:
mode: local_only
requiredReviewerLogins: []
mode: github_codex_required
requiredReviewerLogins: ["chatgpt-codex-connector[bot]"]
allowedMergeMethods: [linear_tree_preserving]
approvalTtlSeconds: 900
pollTimeoutSeconds: 600
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.

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.8.1",
"version": "0.9.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 Down
39 changes: 39 additions & 0 deletions product/github-codex-review-follow-through.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# GitHub Codex review follow-through

Status: approved by David Ahmann on 2026-09-21 in the maintainer work session.
Route: native maintainer implementation, exact-candidate review, qualified
release, and downstream correction through the released version.

The T-021 preparation PR in Telryn received two P1 comments from GitHub Codex
after it was merged. Mill's configured `local_only` policy behaved as declared,
but the operator did not wait for or reconcile the hosted review. The local
review also missed those oracle and cleanup gaps.

Add a distinct GitHub Codex review policy without changing `local_only` or
`github_required` semantics. It must:

- require the Codex review summary to report completion for the exact current PR
head before merge;
- retain current-head GitHub Codex feedback and block P0/P1 while leaving
standalone P2/P3 advisory under an approved P0/P1 policy;
- keep a draft PR's readiness effect separate when marking it ready triggers a
new hosted review;
- bind the completed hosted-review observation into the merge plan and recheck
it immediately before the merge effect;
- reject running, stale, malformed, unclassified, or late blocking feedback;
- surface post-merge review drift rather than closing over it; and
- preserve existing review policies and historical delivery records.

Tests must cover completed, running and stale Codex summaries, clean and
blocking feedback, advisory feedback, draft readiness, review drift between plan
and merge, and post-merge blocking feedback.

Ship this as the next qualified Mill release, repin Telryn, and repair only the
two P1 gaps from Telryn PR #18 through a separately recorded correction. Do not
rewrite T-021's historical packet or receipt, implement either standalone P2,
expand the prototype, publish Telryn, or claim customer/provider qualification.

The owner also approved installation and README simplification in the same
release. Lead with one short, exact, lifecycle-script-disabled npm install and
the path to a reviewed draft PR. Keep the trust boundary and material limits in
the README; move detailed procedures behind focused documentation links.
17 changes: 15 additions & 2 deletions schemas/delivery-record.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,10 @@
"reviewPolicy": {
"type": "object",
"properties": {
"mode": { "type": "string", "enum": ["local_only", "github_required"] },
"mode": {
"type": "string",
"enum": ["local_only", "github_required", "github_codex_required"]
},
"requiredReviewerLogins": {
"type": "array",
"items": { "type": "string", "minLength": 1 }
Expand All @@ -122,7 +125,9 @@
"allOf": [
{
"if": {
"properties": { "mode": { "const": "github_required" } },
"properties": {
"mode": { "enum": ["github_required", "github_codex_required"] }
},
"required": ["mode"]
},
"then": {
Expand Down Expand Up @@ -219,6 +224,14 @@
"type": "string",
"pattern": "^sha256:[a-f0-9]{64}$"
},
"reviewEvidenceDigest": {
"type": "string",
"pattern": "^sha256:[a-f0-9]{64}$"
},
"reviewCompletionDigest": {
"type": "string",
"pattern": "^sha256:[a-f0-9]{64}$"
},
"method": { "type": "string", "enum": ["merge", "squash"] },
"markReady": { "type": "boolean" },
"expiresAt": {
Expand Down
8 changes: 6 additions & 2 deletions schemas/mill-config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@
"properties": {
"mode": {
"type": "string",
"enum": ["local_only", "github_required"]
"enum": ["local_only", "github_required", "github_codex_required"]
},
"requiredReviewerLogins": {
"type": "array",
Expand All @@ -215,7 +215,11 @@
"allOf": [
{
"if": {
"properties": { "mode": { "const": "github_required" } },
"properties": {
"mode": {
"enum": ["github_required", "github_codex_required"]
}
},
"required": ["mode"]
},
"then": {
Expand Down
15 changes: 10 additions & 5 deletions src/contracts/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -405,27 +405,30 @@ const repositoryMountDirectorySchema = z

const githubReviewPolicySchema = z
.strictObject({
mode: z.enum(["local_only", "github_required"]),
mode: z.enum(["local_only", "github_required", "github_codex_required"]),
requiredReviewerLogins: z.array(z.string().min(1)),
})
.superRefine((policy, context) => {
if (
policy.mode === "github_required" &&
policy.mode !== "local_only" &&
policy.requiredReviewerLogins.length === 0
) {
context.addIssue({
code: "custom",
path: ["requiredReviewerLogins"],
message:
"github_required review policy needs at least one reviewer login",
message: "remote review policy needs at least one reviewer login",
});
}
})
.meta({
allOf: [
{
if: {
properties: { mode: { const: "github_required" } },
properties: {
mode: {
enum: ["github_required", "github_codex_required"],
},
},
required: ["mode"],
},
then: {
Expand Down Expand Up @@ -1327,6 +1330,8 @@ export const mergeApprovalPlanSchema = z.strictObject({
actorLogin: z.string().min(1),
actorId: z.number().int().positive(),
policyDigest: digestSchema,
reviewEvidenceDigest: digestSchema.optional(),
reviewCompletionDigest: digestSchema.optional(),
method: z.enum(["merge", "squash"]),
markReady: z.boolean(),
expiresAt: z.iso.datetime(),
Expand Down
Loading