Repository navigation
test(spec): the retired-after census reads a prerelease package label on its release triple - #23041
Merged
objectstack-fleet[bot] merged 2 commits intoOct 12, 2026
Conversation
… on its release triple Changesets pre mode writes `18.0.0-next.0` into packages/spec/package.json on the Version Packages PR. The census parsed the label with the same strict x.y.z reader it uses for census versions and stamps, so three of its five cases threw `not a stable x.y.z version` and spec's local test project went red. The census now compares against the label's release triple (`18.0.0-next.N` reads as `18.0.0`), the reading the artifact door gives the runtime label. Census versions and retiredAfter stamps stay strict stable x.y.z, and a label that is neither x.y.z nor x.y.z-PRERELEASE still throws. A unit pin covers the rule. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019G5ZnRrTMiwcHG6iZM19zf
…nsus-prerelease-label
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 12, 2026
objectstack-fleet
Bot
deleted the
claude/issue-23025-census-prerelease-label
branch
October 12, 2026 13:42
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 #23025
Clause-②: no
The rule
The retired-after census (
packages/spec/src/conversions/retired-after.census.test.ts) now reads@objectstack/spec's package label on its release triple:x.y.zis its own release triple;x.y.z-PRERELEASEdrops the suffix, so18.0.0-next.Ncompares as18.0.0;Every comparison against the label uses that triple: the census is never ahead of it, every
retiredAfteris at or below it, and the release-pending range for unpublished stamps ends at it. Only the label gets this reading. A census version and aretiredAfterstamp stay strict stablex.y.z(triple()is unchanged), so a prerelease written into the census or onto an entry still throws.Why the release triple: it is how the artifact door already reads the runtime label (
parseVersioninpackages/metadata-core/src/artifact-forward-conversion.tscomparesx.y.ztriples and tolerates a suffix; PR #23023, now onmain, keeps that reader). On a stable label the triple is the label, so no assertion changes meaning there.Pins, in the same file:
the package label is read on its release triple(new block, 4 cases): a stable label is its own triple;18.0.0-next.0,18.0.0-next.12and18.1.0-rc.1read as their release triples and compare at, never above, the release; nine malformed labels still throw, each naming the label;triple()andcmp()still throw on a prerelease, so the reading stays the label's alone.18.0.0-next.0throughscripts/ablation-replace.mjs(below).What this PR does not settle (part 2 of triage's direction)
The legal
retiredAfterfor a retirement landing under18.0.0-next.Nwas routed to #23001's window rule. PR #23023 has landed and #23001 is closed, but neither states a stamp rule for a retirement under a prerelease label. Its dev's report says the door's new major-step half "does not read retiredAfter for step-18 entries". Its module docblock describes the prerelease while the label "still names the last release of M-1". This PR takes no position on the question.What the census admits today, read off this diff: under a prerelease label the release-pending range is
[last censused release, release triple], today[17.4.0, 18.0.0]. So it admits both candidate stamps, the last 17.x release and18.0.0. Two facts for whoever decides it:18.0.0-next.Nships retired in18.0.0, so the census will then require the stable release before18.0.0. A stamp of18.0.0would pass now and go red at that refresh..claude/skills/spec-property-retirement/SKILL.mdand theretiredAftertype doc (packages/spec/src/conversions/types.ts) tell an author to stamp the current package label. Under pre mode that label is18.0.0-next.N, which tsc's${number}.${number}.${number}type and this census both refuse, so the author has to guess.If the rule becomes "below the release triple under a prerelease label", the census change is one comparison in this file. #23001 is not addressed here.
Reproduction, at base
3071d3e989eba400e->73244d5e.Error: not a stable x.y.z version: '18.0.0-next.0', thrown bytriple()in the three cases that compare against the label.9eba400e== HEAD,git diff HEADempty.Sweep: every read of the package label in
packages/spectests and scriptsgit grepoverpackages/spec/src/**/*.test.ts,packages/spec/scripts/**and the vitest configs, forpackage.jsonreads,.versionreads,version.split('.'),parseIntof a version, strictx.y.zregex literals andsemverimports (none). Each hit, and what it does under18.0.0-next.0:18.0.0-next.0src/conversions/retired-after.census.test.tsx.y.zregex intriple()src/kernel/protocol-version.test.ts:24-:42split('.')[0];includes('-')PROTOCOL_MAJOR18, so the equality branch passesscripts/build-schemas-check-mode.test.ts:996(repoproject)Number.parseInt(label, 10)18.0.0labelscripts/openapi-self-consistency.test.ts:303info.versionscripts/lib/upgrade-guide-docs.ts:55(releaseStatus, frombuild-upgrade-guide.ts:194)MAJOR.MINOR.PATCH[-PRE]regexprereleasescripts/build-schemas.ts:300,:767x-spec-version;parseIntmajorscripts/build-openapi.ts:30info.versionscripts/build-spec-changes.ts:101toVersionscripts/analyze-bundle-size.ts:176scripts/build-retired-after-census.ts:92parseStableover packument versions, not the labelNo shipped parser. Every hit is a test or a script, and
packages/spec'sfiles[]ships neither (measured below), so the change stays tests-only.The measured half: the whole spec
localproject under18.0.0-next.0, on the fixed tree, is green (below). Since this diff touches only the census file, that run is also every otherlocaltest's base reading: the census was the only red. The spec filesmainbrought in since add no label read (re-swept after the merge).Verification, at head
ee6874ff9(the fix withorigin/main0ede0f8abmerged in)17.7.0:pnpm --filter @objectstack/spec exec vitest run --project local src/conversions/retired-after.census.test.tsgives Test Files 1 passed, Tests 9 passed (9).18.0.0-next.0, the same command wrapped byscripts/ablation-replace.mjsas in the reproduction: the mutation landed (anchor 1 -> 0, blob9eba400e->73244d5e), and Tests 9 passed (9). Restore: blob9eba400e== HEAD,git diff HEADempty. With the reproduction this is the reverse verification: the same command at base gives 3 failed | 2 passed.[17.4.0, 17.7.0]on the real label,[17.4.0, 18.0.0]on the prerelease label.localproject under18.0.0-next.0, through the same tool, at7c75f2c49(the fix before the merge): Test Files 650 passed | 1 skipped (651), Tests 19470 passed | 1 skipped | 1 todo. Restored, blob == HEAD.vitest list --project localconfirmssrc/kernel/protocol-version.test.tsandscripts/openapi-self-consistency.test.tsare in that project.pnpm --filter @objectstack/spec build: exit 0.pnpm --filter @objectstack/spec typecheck: exit 0. Itscheck:test-typecheckcompilestsconfig.test.json. That program lists the census test (tsc --listFilesOnly: 2368 files), andtest-typecheck-debt.jsonhas no row for it.localproject on the real label at the merged head is left to CI. The diff againstmainis this one file, run on both labels at that head above.skip-changeset):npm pack --dry-runlists 2080 files, none of them*.test.ts; positive controlsrc/kernel/manifest.zod.tsis listed.releaseTriplehas 0 hits indist/; positive controlretiredAfteris found indist/shared/index.js.pnpm lint:eslint --no-inline-config --format jsonover the one touched file reports 1 file, 0 errors, 0 warnings. The file is inside the config's population (--print-configresolves 4 rules for it, and no ignored notice is reported). The config enables no type-aware linting (noparserOptions.projectorprojectService), so the diff cannot move a verdict on an untouched file.Gates, at head
ee6874ff9node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderives 75. 74 were run, each exit captured before any pipe, and 72 exited 0.--ranreconciliation: 75 derived, 72 run, 2 NOT-MEASURED, 1 UNRUN.check:dual-build-cjs-loadsandcheck:lean-entry-closureexited 3 (PREREQUISITE NOT MET: no built output for 83 packages, and for objectql). This diff changes no build input.check:type-check-debt, which the dispatch marks NOT MEASURED.check:doc-formula-expressionsfirst exited 3 (@objectstack/formulaunbuilt). After@objectstack/formulaand@objectstack/lintwere built, it exited 0.Acceptance notes
scripts/build-schemas-check-mode.test.ts(therepoproject's only label reader) is NOT MEASURED under the prerelease label. One attempt was cut by a foreground timeout mid-run, and a second never got the verify lock (exit 99). Its read isparseInt, which gives 18 for18.0.0-next.0and for18.0.0alike, so any red there is the 17 to 18 major move, not the prerelease suffix.!pendingbranch of the UNPUBLISHED rule (exact label) is not exercised by any current tree: the census trails at 17.4.0, so both labels take the pending branch. Under the release triple it requires the stamp to equal the triple, which is unreachable while the label is a prerelease (the census never records a prerelease tarball).Generated by Claude Code