Repository navigation
fix(spec): the default-change ratchet authorises from the baseline major, so the version branch major roll stops refusing rows declared under 17 - #23123
Merged
Conversation
…major `authoriseDefaultChanges` admitted DEFAULT_CHANGES_BY_MAJOR rows at this build's major only, on the premise that by the time a major rolls the baseline already carries the new value. Two baselines break that premise: the version pass rolls `package.json` inside the branch under test, and a shallow checkout's re-anchored baseline (`baseRev`) lags by design. On the `18.0.0-next.0` version branch both held - a major-17 baseline, a major-18 build - so the ten default changes main had declared under 17 were refused as undeclared and `gen:schema` exited 1 in the release-candidate smoke. The window now runs from the baseline tree's own protocol major (read out of git at the baseline rev, as its defaults are) up to this build's, with each major's rows chained in ascending order: contiguity and the chain-tip rule hold across the roll, rows older than the baseline's major still authorise nothing, and an unreadable baseline major falls back to this build's major alone, announced. The widened window is printed whenever it spans more than one major. Claude-Session: https://claude.ai/code/session_012zwsLMxQBwHUYJgPyrpEvx Co-authored-by: Claude <noreply@anthropic.com>
Contributor
📓 Docs Drift CheckNothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 0 changed package(s)), so this run has no opinion about the docs. What this run could not see
Coarse fallback — 0 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
This was referenced Oct 13, 2026
This was referenced Oct 13, 2026
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.
Fixes #23113
Clause-②: no
Unblocks #21988, the Version Packages PR for
18.0.0-next.0. The release branch is not edited, and neither the smoke nor any workflow is touched.The failing line
I read it from the job log of run
38323903662, job115058075855(Packed-tarball smoke (release candidate), step 10Build). The tree ischangeset-release/mainat9a73a93f1, with@objectstack/spec@18.0.0-next.0:packages/spec/scripts/build-schemas.ts:3352on9a73a93f1: the default-change refusal, with its message at:3317.ERROR … exited (1)lines at 1639–1641. The rest of the task's output is flushed after turbo reports the failure, so reading only from[System]to turbo's error line shows no error.Root cause
authoriseDefaultChanges(packages/spec/scripts/lib/authorable-defaults.ts:392) admittedDEFAULT_CHANGES_BY_MAJORrows only atCURRENT_MAJOR, which isNumber.parseIntofpackage.json's version (build-schemas.ts:767).merge-base HEAD origin/maincannot answer. The gate re-anchors onbaseRev85c6d76ec42a, at spec17.4.0. That anchor is allowed to lag.85c6d76ec42aare all declared under17:inscripts/lib/default-changes.ts.38247570907(12:12Z), built17.8.0(HEAD is now at d00f5f2 chore: version packages). It re-anchored on the same85c6d76ec42aand printed📌 9 declared default change(s) accepted (#4666).38248923046(12:25Z), built18.0.0-next.0(d85ff7c chore: version packages (next)), on the samemainsha4267484fe5.ui/UserActionsConfig:editInline, landed on main in between.Number.parseInt('18.0.0-next.0', 10)is18, which is correct. The input that changed is the major itself.The fix
The authorising window now runs from the baseline tree's own protocol major up to this build's major (
authorisingMajors):readProtocolMajorAtRevreads it frompackage.jsonat the baseline rev, the same rev the baseline defaults are read from. The in-tree baseline is this tree, so it uses this build's major.main(baseline 17, build 17) the window is[17], the same as before this change.Where the change lands:
packages/spec/scripts/lib/authorable-defaults.ts,packages/spec/scripts/build-schemas.ts,packages/spec/scripts/lib/default-changes.ts(header comment only) andpackages/spec/scripts/authorable-defaults.test.ts.gen:schemascript's own library underscripts/lib/, which falls inside the declared surface ("the spec build's gen:* scripts").packages/spec/src/**file is touched.build-openapi.tsneeded no change: the spec build passes through it in proof (b).Proofs
All runs went through
scripts/pm/os-verify-lock.sh.(a) The failure reproduces on
9a73a93f1, unmodified.git clone --depth=1 --branch changeset-release/main, the same shape as the smoke's checkout (HEAD9a73a93f1c56, shallow).pnpm --filter @objectstack/spec run build.VERDICT command-exit 1. The run re-anchors (shallow history … anchors on 85c6d76ec42a), then prints❌ 10 authorable key(s) changed the DEFAULT…with the same ten keys andBaseline: upstream 85c6d76ec42a.(b) The same tree passes with this fix applied locally, uncommitted.
git diff 21c86444e 7f04259ceapplied withgit applyto the same clone. The tree shows fourMpaths and HEAD is still9a73a93f1.pnpm --filter @objectstack/spec run buildgivesVERDICT command-exit 0. It prints:ℹ️ authorable-defaults/ baseline (upstream 85c6d76ec42a) was read at protocol major 17, and this build is major 18, so DEFAULT_CHANGES_BY_MAJOR rows at majors 17–18 authorise📌 10 declared default change(s) acceptedgen:openapi, tsup and DTS,check-dts-emitted(38/38),check-dts-references, and the dev-prereqs stamp, all passing.Buildstep (turbo run build --filter=!@objectstack/docs, run here at--concurrency=2) givesTasks: 73 successful, 73 total,VERDICT command-exit 0.(c)
mainstill builds@objectstack/specgreen, on this branch (7f04259ce, offmain21c86444e).pnpm --filter @objectstack/spec run buildgivesVERDICT command-exit 0, with🔒 authorable-defaults/ verified against upstream 21c86444ec6e — 1121 default(s) unchanged. The window is a single major, so the notice is not printed.git statusis clean afterwards.Ablation (the fix was committed first; done with
scripts/ablation-replace.mjs):for (const major of authorisingMajors(majors))replaced byfor (const major of [majors.current]). The mutation landed: anchor 1 → 0, blob68f3f7ea8795→b2f5507f9afb.authorable-defaults.test.tsgives3 failed | 33 passed (36). The three failures are the rolled-major acceptance, the cross-roll chain and the cross-roll chain-tip tests. The red direction was expected.blob == HEAD (68f3f7ea8795),git diff HEADempty.Tests and gates (all at
7f04259ce)pnpm --filter @objectstack/spec exec vitest run --project local scripts/authorable-defaults.test.ts: 36 passed: the 27 existing tests (their 10authoriseDefaultChangescalls now pass the majors object), plus 9 new tests covering the window, the roll andreadProtocolMajorAtRev.localsuite:Test Files 659 passed (659),Tests 19996 passed | 1 todo.pnpm --filter @objectstack/spec run typecheck: exit 0. That coverstsc --noEmit,check:scripts-typecheckandcheck:test-typecheck.tsc -p tsconfig.scripts.json --listFileslists all four changed files.node scripts/pm/dispatch-gates.mjs --rananswers✓ 62 derived famil(ies) accounted for — 62 run, 0 NOT-MEASURED.check-plugin-teardown-shape --self-test: its pinned fixture commit was absent from the shallow clone. That one commit was fetched.check:dual-build-cjs-loadsandcheck:lean-entry-closure: no packagedist/. The repo was built first (73 tasks).--no-inline-config --format jsonon the four files reports 4 results, 0 errors, 0 warnings, and no file is ignored.eslint.config.mjsnever enables type-aware linting (noparserOptions.project), so this diff cannot move a verdict on any untouched file. The repo-widepnpm lintis CI's to run.Changeset:
skip-changesetThe diff is confined to
packages/spec/scripts/**, which is not inpackages/spec'sfiles[]. After the build, the shipped pathsdist,json-schema,liveness,prompts,llms.txt,README.md,CHANGELOG.md,api-surfaceandsrc/**/*.zod.tswere grepped:authorisingMajors,readProtocolMajorAtRev,DefaultChangeMajorsandauthoriseDefaultChangeshave 0 hits.defineStack, hits 86 files indist.The change decides the gate's verdict and its console output. It changes no emitted artifact, and the tracked artifacts are unchanged after the build.
Pin
The next Publish Smoke after the fix lands is green on the release branch. The release refresh carries this fix onto
changeset-release/main, and the seat reads that run after landing. Locally, the smoke steps afterBuild(pack, fresh install, auth and CRUD) were not run, so they are NOT MEASURED here.Acceptance notes
mainitself would be at major 18 whilebaseRevstill names85c6d76ec42a(17.4.0). Every depth-1 build ofpackages/specwould then re-anchor and reach the same refusal. The fix covers that case by the same mechanism.tsxfails withEADDRINUSE. A repro clone under the agent scratchpad hit this duringpnpm install'sprepare. A shorter path cleared it. No public door is affected.Generated by Claude Code