Repository navigation
fix(release): leave a current-series field written ahead of its GA cut for that GA's own version run - #25488
Merged
Conversation
…t for that GA's own version run sync-release-index-currency read a `current series:` field naming a version newer than its major's newest GA heading as stale, and rewrote it backwards to the older GA under the run's date on every version pass that was not that GA's own (a prerelease cut, a refresh with nothing new, a lower version's GA run). Such a field is early, not stale: only its GA's own version run can date it, and that run already re-dates it. The rewriter now leaves it byte-identical on every run, judged per major with a numeric triple compare, and prints why. The verdict holds that field out as a deferral instead of a finding, so `pnpm run version` keeps passing on cut-rc and version-pr until the GA; the gate itself still reports the field. A field behind the newest GA is still stamped forward. Control J pins both directions, end to end on checkout-shaped repositories. Claude-Session: https://claude.ai/code/session_01GUr4Vb6HcvEh7N4qrqhPyk Co-authored-by: Claude <noreply@anthropic.com>
…ead as ahead, and keep the notice case a reported failure Claude-Session: https://claude.ai/code/session_01GUr4Vb6HcvEh7N4qrqhPyk Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Requested by Elon · project thread
Fixes #25408
Clause-②: no
Metadata-protocol: none
A code PR on one file,
scripts/sync-release-index-currency.mjs(+261 / -20). It touches nocontent/docs/releases/**file, no workflow, no package and no.claude/**.What changed
The rewriter treated any
current series:field that did not name its major's newest GA as stale, and stamped it to that GA with the run's date. A field written by hand ahead of a GA cut names a NEWER version than the newest GA. So every version pass that was not that GA's own moved it backwards, under a date that belongs to neither release. Such passes are an rc cut, a run with nothing new, and a lower version's GA run.Now:
aheadOfNewestGa(named, newest)is true when the field names a newer version of the same major. It is a numeric triple compare, so 17.10.0 is ahead of 17.9.0. A different major is never ahead, because no run of this major can make that field true. A version that is notx.y.zthrows, because either default would bring back a defect.rewriteStatusFieldreturns null for such a field on every run, with the GA-run flag set or not. So a lower version's GA run (an 18.0.1 patch) also leaves an 18.1.0 field alone.currencyVerdict({ indexText, changelogText })returns{ findings, deferred }. It is the gate's ownindexCurrencyFindingsfor every major, except a major whose field is ahead of the cut, which becomes a deferral instead of a finding.currencyFindingsis now itsfindings, andsyncIndexreturnsdeferredas well.main()prints one line per deferral and exits 0. On the measured shape the line reads: "v18: (current series: 18.1.0, released 2026-10-21) left as written — 18.1.0 is newer than v18's newest GA in packages/spec/CHANGELOG.md (18.0.0), so the field was written ahead of the 18.1.0 cut. Only 18.1.0's own version run can date it, and it will; rewriting it now would move it back to 18.0.0 under a date that belongs to neither release. If 18.1.0 will not ship, correct the field by hand. check-release-section-coverage reports it until then." The "nothing rewritten" line no longer claims that every entry names the newest GA when a deferral exists.A field BEHIND the newest GA is stamped forward exactly as before. The GA's own version run still re-dates the field (the path #25407 added), now starting from the pre-written version.
Why exit 0 and not a stop
The dispatch allowed either, "whichever the existing exit ladder supports". The ladder's exit 1 is the loud stop for shapes that need a hand-written sentence: a contradicted "final release:" or a missing parenthetical. It fails
pnpm run version. That would fail everycut-rc.ymlcut ("Version the workspace", line 473) and everyversion-prrefresh (release.yml lines 561 and 939) from the day a field is pre-written until its GA. No sentence improves that state, and the GA's own run resolves it. So the field is deferred and the run says why.The deferral is per major. A refused shape on another major in the same index still reaches the verdict and stops the run (pinned in Control J).
The gate is unchanged and still reports the field: advisory on
mainwithout--strict, and red under--strictinrelease-coverage-patrol.yml. Turning on--strictanywhere else is a workflow edit and outside this card.Proof
Throwaway repositories, before and after. Each repository holds
scripts/, the spec CHANGELOG (newest GA 18.0.0) and the release index fromorigin/main0b8dbea. The v18 field was changed to(current series: 18.1.0, released 2026-10-21)and committed asHEAD. Then the CHANGELOG was changed as each pass would change it, andnode scripts/sync-release-index-currency.mjswas run on 2026-10-23:origin/main0b8dbea→ (current series: 18.0.0, released 2026-10-23), exit 0git diffempty## 18.1.0-rc.0added (an rc cut)→ (current series: 18.0.0, released 2026-10-23), exit 0git diffempty## 18.1.0added (18.1.0's own version run)→ (current series: 18.1.0, released 2026-10-23) — re-dated: …, exit 0Self-test (
pnpm check:release-index-currency-sync, exit 0): "OK self-test: 75 cases pass", up from 58. The new battery Control J has 17 cases and is floored; the roster floor moves from 9 to 10. It pins:x.y.zis refused.indexCurrencyFindingsstill reports the field, while the verdict carries it as one deferral and no finding. A refused "final release:" on v16 in the same index still reaches the verdict.syncIndexon checkout-shaped git repositories, on the measured 18.1.0 shape: no write and the file byte-identical with nothing pending and on an18.1.0-rc.0cut; re-dated on disk on 18.1.0's own run.Ablations. Each was applied to the committed head, the self-test re-run, and the file restored (
git hash-objectidentical):x.y.zLive tree:
node scripts/sync-release-index-currency.mjsprints "every in-scope entry in content/docs/releases/index.mdx (v16, v17, v18) already names the newest GA release of its major … nothing rewritten", exit 0, and the tree stays clean.Gates
At
6d07608(base0b8dbea),node scripts/pm/dispatch-gates.mjs --commandsderived 33 commands for the one path. Each ran with its exit code captured before any pipe, and all 33 exited 0.--ranreconciles: "✓ dispatch-gates --ran: 33 derived famil(ies) accounted for — 33 run, 0 NOT-MEASURED (a DERIVED zero — all 33 recorded an exit code and none of them is 3)". The script-specific families among them includecheck:release-index-currency-sync,check-scripts-symbol-anchors,check-self-test-wiredandcheck-self-test-workflow-commands(each in both modes),check:entry-guard,check:nul-bytesandcheck:pm-dispatch-gates.pnpm exec eslint scripts/sync-release-index-currency.mjsexits 0.The branch then merged
origin/mainea33919. None of the incoming commits touches this script, the gate it imports,git-env.mjsorinvoked-as.mjs, and the v18 field onmainstill reads(current series: 18.0.0, released 2026-10-20). At the merged head9697865the self-test (75 cases), the live run and the three-shape measurement above were run again with the same results. The pre-pushcheck:commit-card-trailerspassed on both pushes.node scripts/pm/check-governed-merges.mjs --branch claude/project-thread-zhlg06: "0 of 1 path(s) hit the register (7 surfaces govern objectstack). ✅ NOT governed", 281 changed lines (≤ 3000).No package source moves, so no package
testortypecheckis owed. CI ownstest:repo, Test Core, the type-check lanes andpnpm lint; this PR's check-runs answer them.skip-changeset. The file lives in the private root package ("private": true), andscripts/is in no published package'sfiles[]. The label rides the create.Acceptance notes
final release:field written ahead of its cut is not deferred. It is a refused shape and still stops the run, as before. No such field is in the corpus, and it is outside this card.check-release-section-coverage --stricton PRs is a workflow edit (Tier H) and outside this card.os-dev.mdforbids HTML comments in GitHub text. Same shape as fix(release): re-date a pre-written current-series field on its GA's own version run #25407; reported as a deviation.claude/project-thread-zhlg06. The claim (comment6368342248) records it as the identity.Generated by Claude Code