Skip to content
Draft
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
42 changes: 26 additions & 16 deletions .github/CODEX.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ two ordered desired-state files:
- `codex.plan` for production;
- `codex-unstable.plan` for preview.

Each plan row names a topic ref, its exact reviewed source SHA, the source
Each plan row names a topic ref, its exact admitted source SHA, the source
boundary used to replay it, and one prerequisite. The controller retains each
reviewed source object at `refs/heads/codex-pins/<sha>`. A mutable topic ref
admitted source object at `refs/heads/codex-pins/<sha>`. A mutable topic ref
may advance later; that does not change a published generation until another
reviewed plan transition pins the new head.
approved plan transition pins the new head.

`codex.config` is the realized ledger. Version 3 records the plan blob,
source pins, generated topic tips, and lane output tips produced by the last
Expand All @@ -31,31 +31,41 @@ active topics belong in `codex`.

| Change | Human review | Bot action | Plan effect |
| --- | --- | --- | --- |
| Add | Review the topic PR against its lane | Pin the approved head and open a plan PR | Append one topic with its uniquely inferred prerequisite |
| Alter | Review the updated topic PR against its lane | Pin the approved head and open a plan PR | Replace only that topic's source SHA and source boundary |
| Add | Review the topic PR against its lane | Pin its current head and open a plan PR | Append one topic with its uniquely inferred prerequisite |
| Alter | Keep the topic PR approved against its lane | Pin its current head and open a plan PR | Replace only that topic's source SHA and source boundary |
| Remove | Review the generated plan PR | Open a plan PR from the explicit workflow dispatch | Delete one plan row |
| Reorder | Review the generated plan PR | Open a plan PR from the explicit workflow dispatch | Move one existing row; keep its SHA, boundary, and prerequisite |

An add or alter has one human decision: the topic PR. The pull request is
review-only because the output-lane rulesets reject ordinary updates. When an
approval is submitted, a scheduled scanner on the trusted default branch
notices the exact approved head and runs the plan producer. Operators can
dispatch the same scan immediately when waiting five minutes is undesirable.
That trusted run:
notices the approved topic and freezes its current head before running the
plan producer. Operators can dispatch the same scan immediately when waiting
five minutes is undesirable. That trusted run:

1. rechecks that the PR is open, same-repository, non-draft, aimed at the
matching lane, and overall `APPROVED`;
2. requires an effective approval at the exact current head SHA;
2. requires an effective approval from a different repository writer;
3. asks the dedicated plan App to create immutable pins and a
`codex-plan/*` branch;
4. opens a one-row plan PR against `meta`; and
5. runs the trusted admission check, which rechecks the topic approval and
gives the mechanical plan approval.

The plan PR auto-merges with rebase after its required check passes. If the
topic head changes before that happens, the exact-head check fails. A new
approval produces a new pin and a new plan transition. Once the plan merges,
the immutable pin remains authoritative even if the source branch moves.
An approval remains effective across later topic updates unless it is
dismissed or the reviewer supersedes it with a request for changes. The plan PR
auto-merges with rebase after its required check passes. If the topic head
changes before that happens, the pinned-head check fails; the next scan can
reuse the effective approval and create a new pin and plan transition. Once
the plan merges, the immutable pin remains authoritative even if the source
branch moves.

After publication, the publisher closes a review-only topic PR only when its
head still matches both the approved plan and the published source pin. A
rebased topic may not appear verbatim in the generated lane, so GitHub shows
that PR as closed rather than merged. Staging alone never closes a PR, and a
closure failure cannot undo an otherwise successful publication. A later
change to the same topic needs another topic PR.

Remove and reorder are policy decisions rather than projections of a reviewed
topic head. Run **Actions > Refresh codex > Run workflow** with
Expand Down Expand Up @@ -100,7 +110,7 @@ For a local diagnostic of the same projection:
Meta/codex propose-plan --remote origin \
--lane codex-unstable \
--topic tb/codex/my-topic-unstable \
--source-tip <full-approved-sha> \
--source-tip <full-current-sha> \
--review-pr <topic-pr-number> \
--action auto --no-push
```
Expand Down Expand Up @@ -137,8 +147,8 @@ then run a fresh rebuild. For a pinned merge-shaped source, the controller
uses its reviewed `source-base` as the exact old root and preserves the DAG
across a moved generated base only when the two changed-path sets are
disjoint. An overlapping base move or a graph with different reviewed roots
fails closed; restack and obtain a new exact-head review instead of flattening
or guessing.
fails closed; restack the approved topic and pin its new head instead of
flattening or guessing.

## Required automation topic

Expand Down
120 changes: 114 additions & 6 deletions .github/workflows/codex-branch.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5905,7 +5905,9 @@ has_qualifying_current_review () {
repository=$4
pull_number=$5
candidates=$6
awk -F '\t' -v author="$author" -v head="$head" '
require_exact_head=${7:-true}
awk -F '\t' -v author="$author" -v head="$head" \
-v exact="$require_exact_head" '
NF == 4 && $2 ~ /^(APPROVED|CHANGES_REQUESTED|DISMISSED)$/ {
state[$1] = $2
commit[$1] = $3
Expand All @@ -5915,7 +5917,7 @@ has_qualifying_current_review () {
for (reviewer in state)
if (reviewer != author &&
state[reviewer] == "APPROVED" &&
commit[reviewer] == head)
(exact == "false" || commit[reviewer] == head))
print reviewer "\t" association[reviewer]
}
' "$reviews" >"$candidates" || return 1
Expand All @@ -5937,9 +5939,10 @@ has_qualifying_current_review () {
[(.author.login // "-"), .state,
(.commit.oid // "-")] | @tsv' \
>"$candidates-writers" 2>/dev/null || return 1
awk -F '\t' -v author="$author" -v head="$head" '
awk -F '\t' -v author="$author" -v head="$head" \
-v exact="$require_exact_head" '
NF == 3 && $1 != author && $2 == "APPROVED" &&
$3 == head { approved++ }
(exact == "false" || $3 == head) { approved++ }
END { exit !approved }
' "$candidates-writers"
}
Expand Down Expand Up @@ -6013,8 +6016,8 @@ validate_topic_review () {
die "could not inspect reviews for topic pull request #$pull_number"
has_qualifying_current_review "$tmp_dir/topic-reviews" "$author" \
"$source_tip" "$repository" "$pull_number" \
"$tmp_dir/topic-review-candidates" ||
die "topic pull request #$pull_number has no current approval for $source_tip"
"$tmp_dir/topic-review-candidates" false ||
die "topic pull request #$pull_number has no qualifying approval"
say "validated reviewed topic pull request #$pull_number at $source_tip"
}

Expand Down Expand Up @@ -9566,6 +9569,101 @@ stage_and_wait_for_ci () {
fi
}

close_published_topic_review () (
controller=$1
updates=$2
plan_commit=$3
seen=$4
review=$(plan_trailer_optional "$plan_commit" Codex-Plan-Review \
"Codex-Plan-Review") || return 1
test -n "$review" || return 0
case "$review" in
*[!0-9]*) return 1 ;;
esac
action=$(plan_trailer_one "$plan_commit" Codex-Plan-Action \
"Codex-Plan-Action") || return 1
case "$action" in
add|alter) ;;
*) return 0 ;;
esac
lane=$(plan_trailer_one "$plan_commit" Codex-Plan-Lane \
"Codex-Plan-Lane") || return 1
case "$lane" in
codex|codex-unstable) ;;
*) return 1 ;;
esac
topic=$(plan_trailer_one "$plan_commit" Codex-Plan-Topic \
"Codex-Plan-Topic") || return 1
topic=${topic#refs/heads/}
source_tip=$(plan_trailer_one "$plan_commit" Codex-Plan-Source-Tip \
"Codex-Plan-Source-Tip") || return 1
published_meta=$(awk -F '\t' \
'$1 == "refs/heads/meta" { print $3 }' "$updates") || return 1
published_output=$(awk -F '\t' -v ref="refs/heads/$lane" \
'$1 == ref { print $3 }' "$updates") || return 1
test -n "$published_meta" && test -n "$published_output" || return 1
make_tmp_dir
review_state=$tmp_dir/published-topic-review
mkdir -p "$review_state" || return 1
git show "$published_meta:$lane.plan" >"$review_state/plan" || return 1
git show "$published_meta:$meta_config_path" \
>"$review_state/config" || return 1
planned_tip=$(git config --no-includes --file "$review_state/plan" \
--get "branch.$topic.source-tip" || :)
test "$planned_tip" = "$source_tip" || return 0
ledger_tip=$(git config --no-includes --file "$review_state/config" \
--get "branch.$topic.source-tip" || :)
ledger_output=$(git config --no-includes --file "$review_state/config" \
--get "$lane.output-tip" || :)
generated_tip=$(git config --no-includes --file "$review_state/config" \
--get "branch.$topic.codex-tip" || :)
test "$ledger_tip" = "$source_tip" &&
test "$ledger_output" = "$published_output" &&
test -n "$generated_tip" || return 1
git merge-base --is-ancestor "$generated_tip" \
"$published_output" || return 1
test "$(remote_head_oid origin refs/heads/meta)" = \
"$published_meta" || return 1
test "$(remote_head_oid origin "refs/heads/$lane")" = \
"$published_output" || return 1
test "$(remote_head_oid origin "refs/heads/$topic")" = \
"$source_tip" || return 0
if grep -F -x "$review" "$seen" >/dev/null
then
return 0
fi
printf '%s\n' "$review" >>"$seen" || return 1
gh api --hostname github.com "repos/openai/git/pulls/$review" \
--jq '[.state, (.draft | tostring), .base.ref,
(.head.repo.full_name // "-"), .head.ref, .head.sha] | @tsv' \
>"$review_state/pull-request" || return 1
IFS="$tab" read -r pull_state draft base head_repository \
head_ref head_sha <"$review_state/pull-request" || return 1
test "$pull_state" != closed || return 0
test "$pull_state" = open && test "$draft" = false &&
test "$base" = "$lane" && test "$head_repository" = openai/git &&
test "$head_ref" = "$topic" && test "$head_sha" = "$source_tip" ||
return 0
gh pr close "$review" --repo github.com/openai/git || return 1
say "Closed reviewed topic pull request #$review after publishing $lane."
)

close_published_topic_reviews () (
controller=$1
updates=$2
make_tmp_dir
review_history=$tmp_dir/published-topic-review-history
reviewed=$tmp_dir/published-topic-review-seen
: >"$reviewed" || return 1
git rev-list --first-parent --max-count=64 "$controller" -- \
codex.plan codex-unstable.plan >"$review_history" || return 1
while IFS= read -r plan_commit
do
close_published_topic_review "$controller" "$updates" \
"$plan_commit" "$reviewed" || return 1
done <"$review_history"
)

rebuild_codex_locally () {
prepare_local_candidate
verify_local_candidate "$local_candidate_dir"
Expand All @@ -9580,6 +9678,11 @@ rebuild_codex_locally () {
--updates "$local_candidate_dir/codex-updates" \
--require-automation
say "Published codex candidate $candidate from local preparation session $session."
if ! close_published_topic_reviews "$controller_oid" \
"$local_candidate_dir/codex-updates"
then
say "warning: publication succeeded, but its reviewed topic pull request could not be closed."
fi
say "Generated commits identify $bot_name <$bot_email>; the push uses your configured origin credentials."
}

Expand Down Expand Up @@ -9699,6 +9802,11 @@ publish_run () {
--inputs "$metadata/codex-inputs" \
--updates "$metadata/codex-updates" --require-automation
say "Published codex candidate $artifact_candidate from Actions run $run_id."
if ! close_published_topic_reviews "$run_controller" \
"$metadata/codex-updates"
then
say "warning: publication succeeded, but its reviewed topic pull request could not be closed."
fi
say "Generated commits identify $bot_name <$bot_email>; the push uses your configured origin credentials."
}

Expand Down
Loading