Goal / problem
PR #45 churned for 7 rounds trying to specify a race-safe auto-merge sequence in prompt prose — which can't be made bulletproof. The fix: put the safe merge in a validated script, and give it a trustworthy reviewed-SHA to bind to. This issue builds that mechanism; #45 then enables auto-merge by simply calling it.
Acceptance criteria
1. codex-review.sh records the reviewed head SHA durably
- The harness already fetches the PR head it reviews. Make it emit that SHA into the posted review comment as a parseable marker (e.g. a line
Reviewed-head: <full-sha> in the comment header it already prefixes). So any later actor knows exactly which commit Codex reviewed. No other behavior change; stays read-only/comments-only/verbatim (the marker is part of Faber's header, clearly distinct from Codex's verbatim body).
2. New scripts/merge-pr.sh <PR#> — the safe in-session merge harness
- Read-only until the final merge. Steps:
- Preflight:
command -v gh; numeric <PR#>; unset GH_REPO; derive repo from the cwd's remote (gh repo view --json nameWithOwner), pass explicit --repo "$repo" to every gh call (mirror codex-review.sh).
- Read the reviewed SHA from the latest
codex-review.sh comment on the PR (parse the Reviewed-head: marker). If none found → refuse (non-zero): "no Codex review found; run codex-review.sh first."
- Confirm the PR's current head == reviewed SHA. If not → refuse: "head changed since review (→); re-review before merging." (This is the race guard.)
- Confirm CI is green on the current head (
gh pr checks / statusCheckRollup). If not → refuse.
- Merge atomically pinned to the reviewed head:
gh pr merge <PR#> --repo "$repo" --squash --match-head-commit "<reviewed-sha>". (The --match-head-commit is belt-and-suspenders on top of step 3.)
- It does not judge review pass/fail or risk — that's Faber's call (Faber invokes it only for a clean review + low-risk PR; high-risk → human). The script enforces the mechanical safety: SHA-pin, repo-scope, CI-green.
#!/usr/bin/env bash, set -euo pipefail, shellcheck-clean, executable, -m? (no model needed). Add to ci/required-files.txt + README.md Layout.
3. Verify end-to-end
- shellcheck-clean; structure check passes (incl.
merge-pr.sh). Demonstrate (capture in PR, do NOT actually merge an unrelated PR): the refuse paths fire correctly (no review → refuse; simulate head mismatch → refuse; CI-not-green → refuse). The happy-path merge can be reasoned through / dry-run.
Scope
Likely files
scripts/codex-review.sh, scripts/merge-pr.sh (new), ci/required-files.txt, README.md, reviewer/codex-review.md (note the Reviewed-head marker)
Test expectations
- CI green (shellcheck + structure). Refuse-path evidence in the PR.
Out of scope
Goal / problem
PR #45 churned for 7 rounds trying to specify a race-safe auto-merge sequence in prompt prose — which can't be made bulletproof. The fix: put the safe merge in a validated script, and give it a trustworthy reviewed-SHA to bind to. This issue builds that mechanism; #45 then enables auto-merge by simply calling it.
Acceptance criteria
1.
codex-review.shrecords the reviewed head SHA durablyReviewed-head: <full-sha>in the comment header it already prefixes). So any later actor knows exactly which commit Codex reviewed. No other behavior change; stays read-only/comments-only/verbatim (the marker is part of Faber's header, clearly distinct from Codex's verbatim body).2. New
scripts/merge-pr.sh <PR#>— the safe in-session merge harnesscommand -v gh; numeric<PR#>;unset GH_REPO; deriverepofrom the cwd's remote (gh repo view --json nameWithOwner), pass explicit--repo "$repo"to everyghcall (mirrorcodex-review.sh).codex-review.shcomment on the PR (parse theReviewed-head:marker). If none found → refuse (non-zero): "no Codex review found; run codex-review.sh first."gh pr checks/ statusCheckRollup). If not → refuse.gh pr merge <PR#> --repo "$repo" --squash --match-head-commit "<reviewed-sha>". (The--match-head-commitis belt-and-suspenders on top of step 3.)#!/usr/bin/env bash,set -euo pipefail, shellcheck-clean, executable,-m? (no model needed). Add toci/required-files.txt+README.mdLayout.3. Verify end-to-end
merge-pr.sh). Demonstrate (capture in PR, do NOT actually merge an unrelated PR): the refuse paths fire correctly (no review → refuse; simulate head mismatch → refuse; CI-not-green → refuse). The happy-path merge can be reasoned through / dry-run.Scope
merge-pr.sh's header as not-yet-supported; don't build it here.Likely files
scripts/codex-review.sh,scripts/merge-pr.sh(new),ci/required-files.txt,README.md,reviewer/codex-review.md(note the Reviewed-head marker)Test expectations
Out of scope