Skip to content

fix(release): record confirmed branch rewrites with compare-and-swap - #352

Draft
lamemustafa wants to merge 18 commits into
masterfrom
tapish-codex/record-rewrite-discards
Draft

fix(release): record confirmed branch rewrites with compare-and-swap#352
lamemustafa wants to merge 18 commits into
masterfrom
tapish-codex/record-rewrite-discards

Conversation

@lamemustafa

@lamemustafa lamemustafa commented Sep 10, 2026

Copy link
Copy Markdown
Owner

Summary

Record generated release-branch rewrites through confirmed compare-and-swap receipts so the review gate can discover the exact discarded head. A concurrent advance prevents regeneration instead of silently replacing review history. Interrupted records without proof remain held.

Addresses #350 for future generated-branch rewrites; previously unnamed history remains outside this repair.

Root Cause / Decision Record

A separate head snapshot and unconditional ref update could disagree when another commit arrived between them. Inferring the created head from the current ref or a nearby timeline event could also attach the record to the wrong rewrite.

The wrapper intercepts the installed Release Please ref-update path and uses GraphQL updateRefs with beforeOid. It closes a record only from a confirmed before/after receipt. A newly created generated branch uses its confirmed creation head for the first conditional update. A retained generated branch without an open PR is explicitly refused before release creation: the ref CAS cannot atomically guarantee PR absence or create its review marker. Normal retained-branch reuse remains unresolved, so this is a safe draft fallback, not a merge-ready fix. Unknown outcomes retain an open record rather than guessing. No new state store or review-gate exemption is introduced.

Scope

  • Runtime: Release Please and review-gate tooling only; no extension runtime change.
  • Tests: marker identity, pagination and malformed responses; concurrent advances and missing markers; confirmed/unknown CAS; actual createRef-to-updateRef first-creation sequence; receipt-only closing and retained release outputs.
  • Docs/governance: narrow tooling guidance records the interrupted-run hold.
  • Explicitly out of scope: rewriting existing public commits, reconstructing unnamed historical heads, release tagging, Store submission or release readiness.

Pack Workflow Preflight

Preflight passed on the isolated branch; current master c5df53634ac8a1479779d53bdeb5c65507c5209f was integrated by a merge commit, preserving pushed head continuity.

  • pnpm workflow:preflight was run before editing/push, or the skip reason is documented.
  • This PR was opened from a Pack branch, not master.
  • I checked latest master Pack AGENTS guidance or recorded the stale-guidance warning.
  • PR body keeps the required Pack privacy/review/verification checklist visible.

Sanchika Adoption Gate

Not applicable: no Sanchika adoption.

  • If this PR consumes @sanchika/* packages or copied Sanchika guidance, I
    read sanchika/docs/adoption-pack.md in the coordinated parent worktree.
  • If this PR consumes Sanchika, it links ComplyEaze and Axal completion evidence
    and records the Sanchika commit or copied guidance used.
  • This PR does not import ../sanchika, sanchika/packages/*/src, or parent
    source paths.

Privacy And Data-Flow Impact

No extension permissions, portal data flow or sensitive storage change. Tooling uses its existing GitHub authorization and repository API boundary.

  • No new browser permissions.
  • No new host permissions.
  • No new network calls.
  • No analytics, telemetry, ads, or session replay.
  • No credential, OTP, CAPTCHA, cookie, token, GST file, or taxpayer-data capture.
  • Public copy and privacy declarations are updated if behaviour changed.

Sensitive Surface Review

The ref mutation is conditional on the recorded head; ambiguous mutation results cannot produce a confirmed rewrite record. Already-created release outputs remain available if subsequent manifest setup, PR regeneration or closing bookkeeping fails. Without an actual release, those failures remain terminal; every confirmed receipt gets a closing attempt.

  • Current tab / portal target binding is preserved or intentionally changed.
  • Download completion remains evidence-backed and fail-closed.
  • Ambiguous side-effect delivery cannot be reported as confirmed success.
  • Service-worker durability impact is understood and documented.
  • Real taxpayer data, local paths, raw URLs/referrers, and portal HTML are absent from the diff.

Chrome Web Store Impact

No Store scope or publication change. This is review-continuity tooling, not release or Store qualification.

  • This PR does not expand beyond the existing Chrome Web Store V0 listing unless every gate in docs/PUBLICATION_READINESS.md is checked.
  • Full fiscal year remains source-only and excluded from the next packaged Store build until its evidence gates are recorded.
  • Store copy, README status, Privacy QA, and reviewer instructions were reviewed if user-facing behavior changed.
  • CI ZIP creation, provenance, and protected publishing are treated as release evidence, not manual store-submission sign-off.
  • PR title uses Conventional Commits so Release Please can bump Pack after merge.

Verification

Candidate 4bf1130ae6d808d1e138d9a77c5567f2b3ce2850 passed all fourteen final local verification commands on a clean tree under Node 26.3.0 and pnpm 11.1.2: 176 files / 3344 tests, locked install/audit, prepare, formatting, lint, types, build, package and ZIP verification, preflight and diff checks. Independent source review confirms it is safe to publish as draft only. This candidate intentionally remains draft / HELD: the unsafe marker-free retained-branch CAS is removed, but normal reuse of a retained branch with no open release PR still needs a durable recording design. Existing GitHub ref CAS does not atomically bind PR absence or marker creation. The PR must not be merged while this functional blocker remains.

Release publication/provenance/Store commands below are not applicable: this change creates no release. No new browser permissions or extension data flow; the existing GitHub API boundary gains a conditional ref mutation.

  • pnpm install --frozen-lockfile
  • pnpm audit --audit-level high
  • pnpm exec wxt prepare
  • pnpm exec prettier --check .
  • pnpm exec eslint . --max-warnings 0
  • pnpm exec tsc --noEmit
  • pnpm exec vitest run
  • pnpm exec wxt build
  • node scripts/verify-extension-package.mjs .output/chrome-mv3
  • pnpm exec wxt zip
  • node scripts/verify-extension-zip.mjs
  • node scripts/write-release-provenance.mjs
  • node scripts/verify-github-release-assets.mjs --tag <tag> --zip <zip> --checksum <sha256> --provenance <json> when release assets exist
  • node scripts/publish-chrome-web-store.mjs --zip .output/<zip> --provenance .output/pack-release-provenance.v1.json --publisher-id <id> --dry-run true
  • git diff --check
  • pnpm review:gate -- --strict-head-review --wait-head-review-ms 180000 before merge/readiness claim; a missing Codex review blocks readiness:

Artifact Evidence

  • CI run: Verify extension passed on 4bf1130. Current-head Codex review reported no major issues. The strict gate still fails on the documented open retained-branch reuse finding, so the draft remains held.
  • ZIP artifact: local verification only; no release published.
  • ZIP SHA-256: 7327a439cb9f477139148f1d7976fe66ec744aa3e3af0ff5caa10be77caa0397 (local validation only).
  • Clean source/tag or head SHA: 4bf1130ae6d808d1e138d9a77c5567f2b3ce2850.

PR Review Follow-Up

All automated asks are dispositioned below. The retained-branch reuse findings remain open and held; this PR is not merge-ready. #350 retains the forward-design and historical continuity gaps.

  • GitHub Actions completed.
  • Autogenerated Codex/bot review comments inspected after checks completed for the latest head SHA.
  • Inline review threads are resolved, outdated, or answered with evidence.
  • No commits were pushed after the last required human/bot review without re-review.
  • Any follow-up PRs or issues are listed here instead of being left implicit.
Thread/comment Disposition Commit or evidence
r3976980652 fixed fa6d564: Open a trusted before-head marker before release creation or regeneration; open-record tests.
r3976980659 fixed fa6d564: Reject malformed matching-ref responses before mutation; malformed-head-list test.
r3976980664 fixed fa6d564: Regeneration/closing failures retain previously created release outputs; output-preservation regression.
r3985670649 fixed fa6d564: Validate each matching-ref entry and exact head before use; unreadable-entry regression.
r3985670653 fixed fa6d564: Paginate marker comments and fail on malformed pages; multi-page marker tests.
r3985785287 fixed fa6d564: Admit trusted workflow-authored markers only; forged-marker regression.
r3985785290 fixed fa6d564: Validate PR-match shape before regeneration; malformed-PR regression.
r3985785294 fixed fa6d564: Revalidate exact marker identity, then use its head as atomic updateRefs.beforeOid; ordinary/force-advance regressions.
r3993921863 fixed fa6d564: Match release PR by head and target base; wrong-base regression.
r3993921870 fixed fa6d564: Close using the confirmed CAS after-head, independent of any later ref advance; receipt regression.
r3995611897 fixed fa6d564: Replace generated updateRef with atomic updateRefs beforeOid CAS. A race is refused; confirmed receipts alone authorize closing.
r3995611898 rejected with evidence fa6d564: Timestamp/current-ref recovery cannot uniquely prove a rewrite when ordinary advances or unrelated force events intervene. Removed the inference; interrupted changed-head records explicitly remain held. Confirmed in-process receipts close only their actual before/after pair. No claim of automatic historical recovery; #350 retains that limitation.
r3995611901 fixed fa6d564: Retain exact opened record IDs and reject missing/changed records before regeneration; missing-marker regression.
r3996022358 fixed a07395a: without an actual created release, regeneration errors or failed record refresh are terminal; confirmed release outputs retain the asset-continuation behavior. Regression covers no-release failure, alongside existing created-release preservation.
r3996050449 fixed 4bf1130: captures regeneration errors, attempts every confirmed marker-backed receipt, then propagates the named failures when no actual release exists. Regression performs CAS, fails the later PR request and observes exact receipt closing before rejection.
r3996050453 held / linked #350 4bf1130: prior normal-reuse implementation is withdrawn because PR appearance can race its final absence check. The safe fallback refuses retained refs with no open PR before release creation. Functional reuse remains unresolved and blocks merging.
r3996085030 held / linked #350 4bf1130: removes marker-free retained-ref mutation. The current marker reader reads the current PR; ref CAS alone cannot atomically bind that PR context. A durable recording design is required before normal retained-branch reuse can be restored safely.
r3996085032 fixed 4bf1130: every confirmed receipt gets a closing attempt; no-release regeneration/closing failures propagate together with their named causes. Regression covers successful CAS followed by a later API failure and marker PATCH failure. Actual-release outputs remain available.

Screenshots

Not applicable: tooling-only change. Tests use synthetic repositories/heads and stubbed GitHub calls.

Final candidate full-suite output, final three non-empty lines verbatim:

   Duration  307.25s (tests 95%, import 5%, transform 1%)
    Isolate  176 workers spawned · ~98ms startup each (spawn + environment, per file)
             at least ~17.13s faster with isolate: false — reuses workers across files instead of one per file

Closes the loop #342 opened and #350 tracked. Release Please regenerates its
branch by force-pushing, GitHub records no `before_commit_id` for it, and the
discarded head is then unnameable: an ordinary push later rewritten away leaves
no timeline entry, and a head nobody reviewed is named by no review. The review
gate cannot prove a finding recorded only on that head was carried forward, so it
refuses -- correctly, and permanently. Confirmed live on #337 after #351 landed:

    conclusion=action_required
    summary=Review gate a rewrite did not record the head it discarded, and the
    newest recoverable review state predates that rewrite, so a finding recorded
    only on the discarded head cannot be ruled out.

The workflow performing the rewrite is ours, so it can record what GitHub does
not. `run-release-please.mjs` reads the release branch heads immediately before
the regeneration, while the head about to be discarded is still addressable, and
posts a marker naming both heads when one actually moved. The gate reads that
marker and treats the rewrite as identified.

This supplies a name, not permission. A head named by a marker is still searched
for durable state belonging to that pull request, and a marker pointing at a head
with no state leaves the gate exactly as unconvinced as before. That is the
distinction from #343, which exempted generated branches from the check outright
and was withdrawn for it.

Three boundaries, each tested:

- Only `github-actions[bot]` markers count. Anyone who can comment can write the
  text, so the author is the whole of its authority, and no human can post under
  that login.
- A branch created rather than rewritten, or one whose head did not move,
  discarded nothing and gets no marker.
- Two markers naming different discarded heads for one created head are two
  claims about one rewrite with no basis for preferring either, so the gate
  refuses instead of choosing.

The wrapper's "without contacting GitHub" test asserted a guarantee this feature
ends. Rather than delete it, it now stubs `fetch` and asserts exactly which calls
happen: two branch-head reads bracketing the regeneration, and no writes when
nothing was rewritten.

Mutation-tested; every one is caught:

    accept a rewrite record from any author      -> 1 test fails
    ignore recorded discards entirely            -> 1 test fails
    record a marker when the head did not move   -> 1 test fails
    accept conflicting rewrite records           -> 1 test fails

Does not retroactively unblock #337: its four rewrites already happened
unrecorded. That needs its branch re-created, or the corrections carried on a
fresh regeneration once this is live.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@lamemustafa
lamemustafa marked this pull request as ready for review September 10, 2026 08:03
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 10, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-12T11:56:53.583899Z 4bf1130 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1262bb8477

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/run-release-please.mjs Outdated
Comment thread scripts/run-release-please.mjs Outdated
Comment thread scripts/run-release-please.mjs Outdated
Dispositions all three findings from the Codex review of 1262bb8. Two of them
interlock, so this is a redesign of the recording rather than three patches.

P1, an interrupted run lost the discarded head permanently. Writing the record
after the force-push meant a cancellation in between destroyed the only remaining
name for that commit, and no later run could reconstruct it. Recording is now two
stages: the discarded head is written while it is still the branch head, and the
created head is added once the rewrite has produced one. A record stopped in
between names a discard with no replacement, identifies nothing, and is ignored by
the gate -- and the next run completes it from the branch head it finds, which is
exactly what that rewrite created, because nothing else rewrites the branch and it
has not run since.

P1, bookkeeping could strand a published release. The head snapshot ran after
`createReleases()`, so a failure there aborted the wrapper before it wrote its
outputs, and the workflow's prerelease-marking, asset-upload and asset-verify
steps never ran. Everything fallible now runs before `createReleases()`, where a
failure costs a re-run rather than a release without assets. The closing step must
run afterwards, so it no longer throws: it logs and leaves the record open. That
is only safe because of the fix above -- the open record is recoverable, and the
cost of not throwing is a refusal the gate was already making.

P2, a malformed head list was read as "no branches". An indeterminate response
would have let a rewrite proceed with nothing recording what it discarded, which
is the state this mechanism exists to prevent and which nothing downstream could
detect. It now throws before regeneration.

Fetching the pull request's comments twice -- once for rewrite records, once for
clean top-level review markers -- was a duplicate of a fact the pull request
states once, and each `gh` invocation spawns a process. Read once and shared. A
single run of the publisher tests went from exceeding a 120-second budget to
about 41 seconds, which also accounts for tests that had begun failing
intermittently in full-file runs while passing alone. Stated as the likely cause
rather than a proven one: no before/after timing was captured deliberately.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d3bc069214

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/run-release-please.mjs Outdated
Comment thread scripts/run-release-please.mjs Outdated
… read

Two findings on the previous head, both correct, and both the same class one level below the fix that prompted them.

A response that is an array can still carry an entry with no usable SHA. Skipping it made that branch look absent, and an absent branch is force-pushed with no record of the head it discarded -- the exact state this mechanism exists to prevent. An entry that cannot be read is the same claim as a response that cannot be read, so it is now the same refusal.

A release pull request outlives a hundred comments, and the marker just written is the newest one, so a first-page read is precisely what drops it. The record then cannot be closed, and every later run reads the same truncated page, leaving the force-push permanently unpaired.

Three call sites each had their own single-page request and their own array check. One reader now pages to exhaustion for all three, and throws rather than returning what it collected when it runs out -- a short answer here is indistinguishable from 'no such branch', and that reading is the failure.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bba8115a41

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/run-release-please.mjs Outdated
Comment thread scripts/run-release-please.mjs Outdated
Comment thread scripts/run-release-please.mjs
The marker parser told callers to check the comment's author themselves, and
named no way to do it. One of the two readers did, with its own constant and its
own login normaliser; the other did not, and that omission is a finding on this
pull request.

An instruction in a comment is not a mechanism. `isTrustedRewriteRecord` now
lives beside the parser it qualifies, so both readers ask the same question of a
comment, and a third reader has something to reach for rather than a note saying
it ought to.

The login normaliser moves with it, since the gate's review-author check wants
the same normalisation and was the only reason a second copy existed.
Three list reads in this script decide whether a force-push is recorded, and
each accepted an answer it should not have.

**A marker from anyone.** Records read back were parsed without asking who wrote
them. Anyone who can comment on a release pull request could have their comment
taken for this workflow's own open record -- and completing a record rewrites
the comment in place, so an unrelated comment would be overwritten, or an
uneditable one would abort the run before any release work began. The workflow
posts with `github.token`, so the recorder it trusts is the author it writes as.

**An unreadable pull request entry read as "no pull request".** The caller then
skips opening a record while the regeneration force-pushes the branch anyway.
An empty list and an entry that cannot be read are different answers; only the
first means there is nothing to record.

**A head snapshot too old to say what is being discarded.** The record is opened
before `createReleases()` so a failure there costs a re-run rather than a
published release with no assets, which leaves a gap: anything reaching the
branch between then and the force-push is discarded while the record still names
the older head, and the gate accepts that pair and never searches the head that
was lost. The record is now brought up to the branch's current head immediately
before the rewrite. If it cannot be, the rewrite does not happen -- throwing
would strand a published release without its assets, and a pull request that
waits for the next run is recoverable where a discarded head is not.

The refresh and the close walk the same path and differ only in what they write,
so they share it.
Each fails with its guard removed. The comment fixtures now carry an author,
which real ones always do -- that they did not is why the gap was invisible.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 261f140913

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/run-release-please.mjs Outdated
Comment thread scripts/run-release-please.mjs Outdated
…reated

**The lookup matched on head alone.** A generated branch can carry open pull
requests against more than one base, and only the one targeting this run's
branch is the release pull request being regenerated. Matched on head, the
record could be opened and closed on a different pull request while the
force-push rewrote this one, leaving the rewrite that mattered unrecorded.

**The close read the branch, not the rewrite.** The review gate looks a record
up by the head the force-push *created* -- it keys on the timeline event's
`commit_id`. An ordinary commit landing on the branch between the rewrite and
this read would have the record name a head no event mentions, and the gate
would treat the discard as unidentified: exactly as if nothing had recorded it.

I checked whether ancestry saved this, since an ordinary commit leaves the
created head as its ancestor. It does not: `loadRecordedRewriteDiscards` keys
the map by `marker.after` and the lookup is an exact SHA match, not a walk.

The close now reads the created head from the force-push event itself. When no
event names it, the record stays open -- which is how this module answers not
knowing everywhere else: the gate ignores an open record and the next run
completes it. Closing with an uncorroborated head would publish a claim about a
rewrite nothing backs.
Both fail when their guard is reverted: closing from the branch head fails the
two head cases, and dropping the base filter fails the lookup case.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 290757054c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/run-release-please.mjs Outdated
Comment thread scripts/run-release-please.mjs Outdated
Comment thread scripts/run-release-please.mjs Outdated
@lamemustafa
lamemustafa marked this pull request as draft September 12, 2026 10:58
@lamemustafa lamemustafa changed the title fix(release): record the head each regeneration discards fix(release): record confirmed branch rewrites with compare-and-swap Sep 12, 2026
@lamemustafa

Copy link
Copy Markdown
Owner Author

@codex review

Please review current head fa6d564. The update uses confirmed compare-and-swap receipts, preserves head continuity and refuses ambiguous interrupted recovery. The PR body includes all thirteen original finding dispositions and exact local verification.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fa6d5640a0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/run-release-please.mjs Outdated
@lamemustafa

Copy link
Copy Markdown
Owner Author

@codex review

Please review current head a07395a. The latest change fixes the no-release regeneration failure propagation finding while preserving outputs after an actual release. All original asks and this additional finding have explicit dispositions in the PR body.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a07395a2d8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/run-release-please.mjs Outdated
Comment on lines +272 to +275
const record = expected.get(branch);
const createdHead = createdBranches.get(branch);
if (!record && !createdHead) {
throw new Error(`Release Please tried to rewrite unrecorded generated branch ${branch}.`);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Allow CAS regeneration after the prior release PR closes

When a merged release PR's generated head branch is retained, the next master-push run finds the ref but no open PR, so openBranchRewriteRecords() omits it from expected; Release Please then reuses that standard generated branch for the next release PR, and this check rejects its update as unrecorded. Because .github/workflows/release.yml invokes this wrapper on every master push, repositories that do not automatically delete merged head branches become unable to create another release PR until someone manually deletes the stale branch; capture that ref for a CAS that does not claim continuity for the closed PR, rather than rejecting all reuse.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 2ec72e7. A retained generated ref with no open PR is captured only as a local exact-head snapshot. Its next update uses that head as the CAS precondition and emits no marker closing or closed-PR continuity claim. Refresh refuses head advances and newly appeared PRs; unrelated unrecorded refs remain unauthorized. Reuse, race and wrong-ref regressions pass. Full disposition is recorded in the PR body.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HELD in 4bf1130. The marker-free retained-branch CAS has been removed; the wrapper now refuses a retained generated ref without an open release PR before release creation. This removes the unrecorded rewrite path, but normal retained-branch reuse remains unresolved. The existing ref CAS cannot atomically bind PR absence or create its PR-scoped marker, and a repeated absence lookup would leave the same race. This PR remains draft and must not merge until a durable recording design closes that functional gap. The linked #350 and PR body record the hold; no historical recovery is claimed.

@lamemustafa

Copy link
Copy Markdown
Owner Author

@codex review

Please review current head 2ec72e7. Confirmed receipts are now closed in finally before later regeneration errors propagate; retained generated refs after a closed PR use only an exact observed-head CAS, without closed-PR continuity claims. The new lifecycle/race cases pass in the 37-test focused suite. All original and subsequent findings are dispositioned in the body, with final full verification still pending.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2ec72e72cc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/run-release-please.mjs Outdated
branch,
targetBranch,
});
if (pullRequestNumber !== null) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Bind retained-branch CAS to the absence of a PR

When a retained ref has no PR at this lookup but an automation or collaborator opens or reopens one before updateRefs, the exact-head CAS still succeeds and force-pushes that now-open PR. Fresh evidence beyond the closed-PR finding is that the new recordId: null path then creates no confirmed receipt at line 310, so the discarded head has no marker and review findings present only there can be lost. Couple the absence check to the rewrite, or detect and bind a PR appearing during this window before treating the CAS as marker-free.

AGENTS.md reference: AGENTS.md:L90-L92

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HELD in 4bf1130. The marker-free retained-branch CAS has been removed; the wrapper now refuses a retained generated ref without an open release PR before release creation. This removes the unrecorded rewrite path, but normal retained-branch reuse remains unresolved. The existing ref CAS cannot atomically bind PR absence or create its PR-scoped marker, and a repeated absence lookup would leave the same race. This PR remains draft and must not merge until a durable recording design closes that functional gap. The linked #350 and PR body record the hold; no historical recovery is claimed.

Comment thread scripts/run-release-please.mjs Outdated
@lamemustafa

Copy link
Copy Markdown
Owner Author

@codex review

Please inspect current head 4bf1130. This is explicitly a held draft: marker-free retained-branch rewrites are refused, so normal no-open-PR branch reuse remains unresolved and blocks merging. Receipt-closing failures now propagate when no release exists while all confirmed closes are attempted. The body contains all eighteen finding dispositions and final local evidence.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. More of your lovely PRs please.

Reviewed commit: 4bf1130ae6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant