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
24 changes: 23 additions & 1 deletion .github/workflows/codex-autofix-review-comments.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ jobs:
];
const scopedResolveCommand = "@codex resolve actionable Codex review findings for this pull request and current head";
const resolvedDispositionMarker = "<!-- codex-thread-disposition:resolved -->";
const noChangeMarker = "<!-- codex-thread-result:no-change -->";

if (
review.user?.type !== "Bot" ||
Expand All @@ -100,6 +101,11 @@ jobs:
const owner = context.repo.owner;
const repo = context.repo.repo;
const issue_number = pr.number;
const headRepository = pr.head.repo?.full_name;
if (!headRepository) {
core.setFailed("Codex auto-resolve cannot identify the pull request head repository; refusing to route a repair request.");
return;
}
const labels = new Set(
(pr.labels || [])
.map((label) => (typeof label === "string" ? label : label?.name))
Expand Down Expand Up @@ -273,7 +279,7 @@ jobs:
`<!-- codex-autoresolve-head:${pr.head.sha} -->`,
`<!-- codex-autoresolve-source-review:${review.id} -->`,
`<!-- codex-autoresolve-route:${routeReasons.join(",")} -->`,
`${scopedResolveCommand} using the repository instructions. This is the pull request's single automatic repair pass: do not perform a fresh review, create new standalone findings, or request another review. Work only the existing unresolved Codex threads on the current head. Always fix P0 and P1 findings. For P2 and lower findings, fix only clear, scoped, low-risk issues; otherwise disposition them with a concise reason. After fixing or dispositioning a thread, reply in that thread with ${resolvedDispositionMarker} as the first line, followed by a concise summary; that marker authorizes the workflow to close that exact thread. If human input or new authorization is required, do not use the marker and leave the thread open with the blocker. Finish only after every actionable thread is fixed or dispositioned and closed, or explicitly left open for a human decision. Do not update the branch from main, address unrelated reviews, broaden scope, or create more than one scoped fix commit. Do not use external APIs, paid services, credentials, dependency changes, or broad refactors unless explicitly authorized. Add targeted tests where behavior changes and run the narrowest relevant validation.`,
`${scopedResolveCommand} using the repository instructions. This is the pull request's single automatic repair pass: do not perform a fresh review, create new standalone findings, or request another review. Work only the existing unresolved Codex threads on the current head. The only repository destination is ${headRepository}, and the only branch destination is the pull request head branch ${pr.head.ref} at starting commit ${pr.head.sha}; never publish fixes to a detached or synthetic work branch and never create a stacked pull request. Use the authenticated GitHub connector to commit each approved fix to ${headRepository}:${pr.head.ref}, then verify that the pull request head contains the published commit before reporting success. Always fix P0 and P1 findings. For P2 and lower findings, fix only clear, scoped, low-risk issues; otherwise disposition them with a concise reason. For a fixed thread, reply with ${resolvedDispositionMarker} as the first line and <!-- codex-thread-result:fixed-head:<40-character pushed commit SHA> --> as the second line. For a no-code disposition, use ${resolvedDispositionMarker} followed by ${noChangeMarker}. These result markers authorize the workflow to close that exact thread only after it verifies a fixed commit is the pull request head; a local-only commit is not a fix. If publication or verification fails, do not use either result marker, do not claim success, and leave the thread open with the blocker. If human input or new authorization is required, do the same. Finish only after every actionable thread is fixed or dispositioned and closed, or explicitly left open for a human decision. Do not update the branch from main, address unrelated reviews, broaden scope, or create more than one scoped fix commit. Do not use external APIs, paid services, credentials, dependency changes, or broad refactors unless explicitly authorized. Add targeted tests where behavior changes and run the narrowest relevant validation.`,
].join("\n\n");

try {
Expand Down Expand Up @@ -328,6 +334,8 @@ jobs:
"chatgpt-codex-connector[bot]",
]);
const resolvedDispositionMarker = "<!-- codex-thread-disposition:resolved -->";
const fixedHeadPattern = /^<!-- codex-thread-result:fixed-head:([0-9a-f]{40}) -->$/m;
const noChangeMarker = "<!-- codex-thread-result:no-change -->";

if (
reviewComment.user?.type !== "Bot" ||
Expand All @@ -351,6 +359,20 @@ jobs:
return;
}

const fixedHeadMatch = replyBody.match(fixedHeadPattern);
const isNoChangeDisposition = replyBody.includes(noChangeMarker);
if (Boolean(fixedHeadMatch) === isNoChangeDisposition) {
core.setFailed("Codex disposition must declare exactly one result: a verified fixed head or no code change.");
return;
}

if (fixedHeadMatch && pr.head.sha !== fixedHeadMatch[1]) {
core.setFailed(
`Codex reported fixed commit ${fixedHeadMatch[1]}, but the pull request head is ${pr.head.sha}; leaving the thread open.`,
);
return;
}

const owner = context.repo.owner;
const repo = context.repo.repo;
const issue_number = pr.number;
Expand Down
6 changes: 3 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -791,7 +791,7 @@ When explicitly asked to fix or resolve review findings:
- After fixing a P0 or P1 finding, reply with the fix summary and resolve the review conversation when supported by GitHub permissions/tooling.
- After fixing an approved P2 or lower finding, reply with the fix summary and resolve the review conversation when supported.
- After deciding not to fix a P2 or lower finding, reply with the reason, note whether it is deferred or not actionable, and resolve the review conversation when supported.
- For every fixed or fully dispositioned thread, start the thread reply with `<!-- codex-thread-disposition:resolved -->`. The workflow uses this trusted marker to close that exact thread.
- For every fixed or fully dispositioned thread, start the thread reply with `<!-- codex-thread-disposition:resolved -->`. On the next line, use `<!-- codex-thread-result:fixed-head:<40-character pushed commit SHA> -->` for a code fix or `<!-- codex-thread-result:no-change -->` for a no-code disposition. The workflow closes the thread only when exactly one result is declared and a reported fixed commit is the pull request head.
- Do not use the marker when human input or new authorization is required; explain the blocker and leave that thread open.
- Do not leave a review conversation open after it has been fixed or fully dispositioned. If direct resolution is unavailable, the marker reply is the required fallback and the workflow performs the closure.

Expand All @@ -809,7 +809,7 @@ Automatic Codex review is review-only by default. This repository includes `.git
- Pin the supported Node 24-based `actions/github-script` release to its reviewed immutable commit SHA.
- Post the `@codex` resolve request with a real (non-bot) user identity — a fine-grained PAT held in the `CODEX_TRIGGER_TOKEN` secret. The Codex connector ignores commands authored by `github-actions[bot]`, so a bot-authored request is silently dropped. The token needs `pull-requests: write` (issue-comment) access and no more.
- The workflow must treat unmarked review-thread replies as inert. A trusted Codex reply beginning with `<!-- codex-thread-disposition:resolved -->` may only resolve the exact containing thread, and a non-reply Codex review comment must never be turned into a new repair request.
- The workflow must ask Codex to resolve only existing actionable Codex review findings for the triggering pull request and current head using these repository instructions; the resolve task must not perform a new review or create new findings.
- The workflow must ask Codex to resolve only existing actionable Codex review findings for the triggering pull request and current head using these repository instructions; the resolve task must not perform a new review or create new findings. It must name the exact repository and PR head branch, require fixes to be published there through the authenticated GitHub connector, forbid detached `work` branches and stacked pull requests, and treat a local-only commit as a visible failure.
- The workflow may request one automatic repair pass per pull request lifetime. Later heads require an explicit human request.
- Only trust a pull-request deduplication marker when it was posted by the trigger-token account (the same identity that posts the request), resolved at runtime rather than hard-coded.
- Permission failures while reading or creating pull-request comments must fail the workflow visibly, not return a successful soft-skip.
Expand All @@ -820,7 +820,7 @@ Automatic Codex review is review-only by default. This repository includes `.git

### Primary PR command

`@codex resolve actionable Codex review findings for this pull request and current head using the repository instructions. This is the pull request's single automatic repair pass: do not perform a fresh review, create new standalone findings, or request another review. Work only the existing unresolved Codex threads on the current head. Always fix P0 and P1 findings. For P2 and lower findings, fix only clear, scoped, low-risk issues; otherwise disposition them with a concise reason. After fixing or dispositioning a thread, reply in that thread with <!-- codex-thread-disposition:resolved --> as the first line, followed by a concise summary; that marker authorizes the workflow to close that exact thread. If human input or new authorization is required, do not use the marker and leave the thread open with the blocker. Finish only after every actionable thread is fixed or dispositioned and closed, or explicitly left open for a human decision. Do not update the branch from main, address unrelated reviews, broaden scope, or create more than one scoped fix commit. Do not use external APIs, paid services, credentials, dependency changes, or broad refactors unless explicitly authorized. Add targeted tests where behavior changes and run the narrowest relevant validation.`
`@codex resolve actionable Codex review findings for this pull request and current head using the repository instructions. This is the pull request's single automatic repair pass: do not perform a fresh review, create new standalone findings, or request another review. Work only the existing unresolved Codex threads on the current head. The workflow will provide the only allowed repository, pull-request head branch, and starting commit. Publish every approved fix to that exact head branch through the authenticated GitHub connector; never use a detached or synthetic work branch and never create a stacked pull request. Verify the pull-request head contains the pushed commit before reporting success. Always fix P0 and P1 findings. For P2 and lower findings, fix only clear, scoped, low-risk issues; otherwise disposition them with a concise reason. For a fixed thread, reply with <!-- codex-thread-disposition:resolved --> followed by <!-- codex-thread-result:fixed-head:<40-character pushed commit SHA> -->. For a no-code disposition, use <!-- codex-thread-disposition:resolved --> followed by <!-- codex-thread-result:no-change -->. A local-only commit is not a fix. If publication or verification fails, use neither result marker, do not claim success, and leave the thread open with the blocker. Finish only after every actionable thread is fixed or dispositioned and closed, or explicitly left open for a human decision. Do not update the branch from main, address unrelated reviews, broaden scope, or create more than one scoped fix commit. Do not use external APIs, paid services, credentials, dependency changes, or broad refactors unless explicitly authorized. Add targeted tests where behavior changes and run the narrowest relevant validation.`

## Codex Cloud environment

Expand Down
2 changes: 2 additions & 0 deletions docs/branch-review-ledger.md
Original file line number Diff line number Diff line change
Expand Up @@ -243,4 +243,6 @@ Records before 2026-07-28 were written by hand and had drifted: 146 lines carrie
| 2026-07-30 | PR-1473 | a2b2820c13a47425cfc0ea751e57ee35e9bd1105 | PR #1473 full diff vs origin/main | PASS after review repair: governance refusal and error-state contracts are consistent | outstanding-issues guard passed; docs links 1412 passed; docs index passed; Prettier passed; git diff --check |
| 2026-07-30 | pr/1483 | a84fa60eebdbe7a00193c268b401f7abd3cc554e | docs: reopen issue 105 after withdrawn verification | approved after PR 1473 sync; issue 105 remains correctly open | issue/ledger; docs inventory/links/scripts; Prettier; diff-check |
| 2026-07-30 | pr/1476 | 0fd5a3cdba612d30cfd75ea997177f6e29c34bd3 | docs: record ESLint 10 ecosystem blocker | approved after PR 1483 sync; ESLint blocker and issue 105 correction preserved | issue/ledger; docs inventory/links/scripts; Prettier; diff-check |
| 2026-07-30 | PR #1477 | 26d713922006c1af8187994edfa76669dc14cd46 | PR #1477 fork-safe Codex autofix routing | Fixed fork routing to the PR head repository, added fail-closed metadata handling, reconciled current main, and found no remaining actionable defects. | check:codex-autofix-workflow; check:github-actions; check:pr-policy; check:outstanding-issues; check:branch-review-ledger; docs:check-inventory; docs:check-links; docs:check-scripts; typecheck; focused Vitest 53 passed; Prettier |
| 2026-07-30 | pr/1465 | 4e34d97bb9eb5122b9d8f8e54c42793c727f5085 | issues: record fresh #133 evidence | approved; duplicate-ID race and Prettier prerequisite accurately recorded | issue/ledger; docs inventory/links; Prettier; diff-check |
| 2026-07-30 | PR #1477 | 20f795da2d9d0adafa6cb3117429ab3665129c0d | PR #1477 fork-safe Codex autofix routing | Refreshed onto current main after #1465; issue and ledger reconciliation remained clean and no new actionable defects were introduced. | check:outstanding-issues; check:branch-review-ledger; check:codex-autofix-workflow; focused Vitest 53 passed |
2 changes: 1 addition & 1 deletion docs/codex-review-protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Use this protocol for every Codex review, audit, bug hunt, PR review, release-re
- Exception: append the completed review record to `docs/branch-review-ledger.md` so throttling state persists.
- If the user clearly asks to fix confirmed findings, make the smallest safe change and verify with local, static, or mocked checks first.
- During an automatic resolve task, work only existing unresolved Codex threads. Do not start a new review, add standalone findings, or request another review.
- After fixing or fully dispositioning a thread, start the reply with `<!-- codex-thread-disposition:resolved -->`; the workflow will close that exact thread. Do not use the marker when human input or new authorization is required, and leave that blocked thread open with a concise reason.
- After fixing or fully dispositioning a thread, start the reply with `<!-- codex-thread-disposition:resolved -->`, then declare exactly one result: `<!-- codex-thread-result:fixed-head:<40-character pushed commit SHA> -->` for a published fix or `<!-- codex-thread-result:no-change -->` for a no-code disposition. The workflow closes a fixed thread only when the reported commit is the pull-request head. A local-only commit is not a fix; when publication, verification, human input, or new authorization blocks completion, use no result marker and leave the thread open with a concise reason.
- Ask before any OpenAI, Supabase, GitHub/GitLab, hosted CI, or provider-backed workflow.
- After any completed branch/PR review, append to `docs/branch-review-ledger.md` with `npm run ledger:append -- --ref <x> --head <full-sha> --scope <s> --outcome <o> --checks <c>`. Record the full 40-character SHA; `see PR head` and abbreviations make the record unmatchable and cause the review to run again. The ledger is append-only: never edit or delete an existing record; append a correction or superseding record (`--supersede`) instead. This ledger append is allowed even during a pure review. Do not hand-write the markdown row — hand-written rows are what produced the mojibake, wrong-width, and duplicate records the 2026-07-28 hygiene pass had to repair. Do not push a tip whose sole delta is a babysit ledger append; after merging `origin/main` into a branch that touched the ledger, run `npm run ledger:dedupe` when exact twins appear.

Expand Down
Loading
Loading