Repository navigation
release(next): the Version Packages PR #21988 (18.0.0-next.0) is red in CI — check-future-spec-major and two metadata forward-conversion tests are not major-roll aware; fix on main, never on the generated branch #23135
Description
Filing gate ③ — a maintainer-directed task. The maintainer, in this seat's session (session_012zwsLMxQBwHUYJgPyrpEvx) on 2026-10-13, verbatim: 「21988 ci报错,你负责立卡并派发解决。」 and 「21988 是生成的,要修main 哦」.
Reader who acts: the domain:devx execution seat 1, which claims and dispatches this card. The fix lands on main, so the next refresh of #21988 is green. ⛔ No edit to changeset-release/main or #21988 by hand. ⛔ No change to a gate's or test's expectation just to make it pass. ⛔ No release action.
Dedupe: a semantic issue search on this repo, closed cards included, words "version PR 18.0.0-next.0 red check-future-spec-major plugin-artifact-forward-conversion current spec version major roll": 22 hits, none for these two sites. Related, not duplicates:
- release(next): Publish Smoke fails to build
@objectstack/specon the version PR's branch (changeset-release/main,18.0.0-next.0), 5 of 5 runs since 23:16Z #23113 (closed; the same class in the spec build's default-change ratchet, fixed by PR fix(spec): the default-change ratchet authorises from the baseline major, so the version branch major roll stops refusing rows declared under 17 #23123); - test(spec): retired-after.census.test.ts throws on a prerelease package label (18.0.0-next.0) — spec's local project goes red on the first pre-mode version pass, and a prerelease retirement has no legal retiredAfter #23025 (closed);
- spec(conversions): under a pre-mode label (18.0.0-next.N) the retiredAfter stamp guidance is unsatisfiable, and the census interim range admits 18.0.0, which its own PUBLISHED rule rejects after GA #23042 (open; the pre-mode
retiredAfterguidance).
Readings: #21988 head 63eb607ad1, read 2026-10-13 around 03:00Z
The head carries main through 0d43004100. 42 check runs; at reading time, 2 failed and 7 were still running (Test Core (2/6) to (6/6), Type Check · workspace).
Type Check · source gates: job115105083441, run38338685898, step "Check no prose dates a change to an unreleased@objectstack/specmajor". The step reports✗ check-future-spec-major: 3 problem(s), after its own self-test passes (29 cases):scripts/check-future-spec-major.mjs holds 10 citation(s) above the published major, below the floor of 12;QUOTATION_EXEMPTIONS entry 0 (docs/adr/0087-metadata-protocol-upgrade-contract.md, major 18) matched NOTHING;QUOTATION_EXEMPTIONS entry 1 (docs/v17-docs-sweep.md, major 18) matched NOTHING.- Seat reading, not established: on this tree the gate takes 18 as the "published major". Its own self-test says "the class is DERIVED — the same corpus is green once the tree reaches 18". So the floor and the two major-18 exemptions stop matching at the roll. Whether
18.0.0-next.0should count as published is the first question for the fix.
Test Core (1/6): job115105339463, run38338686006. In@objectstack/metadata,Tests 2 failed | 878 passed (880), both insrc/plugin-artifact-forward-conversion.test.ts, suite "artifact door — the conversion is versioned, not a blanket amnesty (Artifacts built by released 17.x tooling are REFUSED by the 17.2 runtime: retired-key tombstones fire at artifact parse, and no artifact-ingestion door runs the ADR-0087 conversion that exists for exactly this #12772)":- "an artifact claiming the CURRENT spec version with a NON-default retired-key value still refuses with the tombstone":
AssertionError: expected 'expected "the strict parse must refus…' to contain 'allowRestore'; - "an artifact claiming the CURRENT spec version whose retired keys carry only the emitted default parses clean — the feat(spec): retired-defaulted-key tolerance — the retired default parses as inert residue and strips (#12497 class rule) #12845 residue tolerance…":
AssertionError: expected [ Array(1) ] to have a length of +0 but got 1. - In the same job,
@objectstack/spec:test:repoand@objectstack/service-settings:testendELIFECYCLEwith no failing test of their own in the log. The seat reads them as turbo's collateral stop; that is to be confirmed.
- "an artifact claiming the CURRENT spec version with a NON-default retired-key value still refuses with the tombstone":
- Still running at filing: any further red check on this head joins this card.
What done looks like
- Reproduce every red check on the generated tree: a fresh depth-1 clone of
changeset-release/mainat chore: version packages (next) #21988's current head, the way release(next): Publish Smoke fails to build@objectstack/specon the version PR's branch (changeset-release/main,18.0.0-next.0), 5 of 5 runs since 23:16Z #23113's dev did. Read the failing lines yourself. - Fix each on
main, at its producer, so the gate or test is right on both sides of the roll.main(17.x) stays green, and the18.0.0-next.Ntree goes green. - Pin: after chore: version packages (next) #21988 next refreshes from a
maincarrying the fix, every check on its head is green or an expected skip. The seat reads that run.
Activity
objectstack-fleet commentedon Oct 13, 2026
Claim: PM loop round 4 ·
domain:devxseat 1 · 2026-10-13T03:02Z · maintainer-directed (the card's first line quotes the order verbatim; this seat's session, 2026-10-13)Session:
session_012zwsLMxQBwHUYJgPyrpEvxAccount:
zhuangjianguo(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-23135-v18-version-pr-redWorktree:
objectstack-issue-23135Domain:
domain:devxSeat:
domain:devx#1File surface:
scripts/check-future-spec-major.mjs(its published-major reading, floor andQUOTATION_EXEMPTIONS, plus its self-test);packages/metadata/src/plugin-artifact-forward-conversion.test.ts, and the forward-conversion source it pins if the producer is there. Also any further red check's producer on #21988's head, declared in the report. ⛔ No governed surface (docs/adr/**,.claude/**,skills/**,AGENTS.md). ⛔ Nopackages/spec/src/**non-test. ⛔ No edit tochangeset-release/main/ #21988 (stop on breach; explain in the report)Container & model:
M,mode:subagent,model: opus(the default judgment tier;dispatch-gates --tieron this surface: "no path-derived mandate", floor sonnet · default opus · ceiling fable)Clause-②: no
Responsibility:
scripts/check-future-spec-major.mjsand the@objectstack/metadataforward-conversion tests read the tree's version as "current" or "published", and both flip at the18.0.0-next.0roll (seat reading; not established) | no platform path covers it:mainis at 17.x, and only #21988's tree carries the roll | #21988's CI reaches it on every refresh, so thenextline is blockedThread-read: none
Serial constraints cleared: no open PR touches
scripts/check-future-spec-major.mjs,packages/metadata/src/plugin-artifact-forward-conversion.test.ts,docs/adr/0087-*ordocs/v17-docs-sweep.md(all open PRs' file lists read at this act). #23042 (open, spec pre-moderetiredAfterguidance) is related and unclaimed here: if the producer turns out to be #23042's site, the dev stops and reports.objectstack-fleet commentedon Oct 13, 2026
os-dev-report
{ "issue": 23135, "status": "done", "branch": "claude/issue-23135-v18-version-pr-red", "pr": "https://github.com/objectstack-ai/objectstack/pull/23155", "session": "session_012zwsLMxQBwHUYJgPyrpEvx — the PM's session (subagent = parent's), as the dispatch's Claim names it and the commit's Claude-Session trailer carries it", "premise_still_valid": true, "summary": "#21988 head 63eb607ad15b883fee70224f20afbf3c89a18e46 (spec label 18.0.0-next.0) reds on 4 checks: Type Check · source gates (check-future-spec-major, 3 problems), TypeScript Type Check (its aggregator: lane typecheck-source-gates concluded failure), Test Core (1/6) (@objectstack/metadata: 2 failed of 880) and Test Core (its aggregator: test-1-of-6 published no positive attestation). Shards 2-6 and Type Check · workspace finished green. Red 1's producer is the gate script, where two pins were stated against the version label. The self-fixture floor counted the gate's own 18-citing fixtures against the tree's major (10 of 12 at 18); it now counts against SELF_FIXTURE_MAJOR=17, the major the fixtures are written against. The two major-18 QUOTATION_EXEMPTIONS entries matched NOTHING because at 18 their citations are legitimate; an entry at or below the published major is now DORMANT (it can excuse nothing), listed on the pass line and never judged. Four self-test rows were added, one of which re-runs the REAL corpus one major up under an 18.0.0-next.0-shaped label so this class reds on main first. A prerelease counts as published, from the gate's own text: 'above the one this tree publishes' and ADR-0087 'names the npm release it ships in'. The ADR is not edited. Red 2's producer is the TEST FIXTURE, not the conversion source. '^' plus the installed label is '^18.0.0-next.0' at the roll, which the door reads as floor 18.0.0, where the documented and pinned major-step half (verdict converted-major-step) replays permission-allow-restore-purge-removed (toMajor 18). The test now derives the current-surface floor the sibling plugin-unbound-form-predicate-roots.test.ts uses (non-zero patch, never M.0.0). No assertion changed. The shard-1 ELIFECYCLE lines of spec:test:repo, spec:test and service-settings:test are turbo's collateral stop (assumption 4 confirmed): all three are green to completion on the generated tree.", "tests": "Generated tree: fresh depth-1 clone of changeset-release/main at 63eb607ad1 in /tmp/r23135 (deleted after use). (a) node scripts/check-future-spec-major.mjs: exit 1, '✗ check-future-spec-major: 3 problem(s)' (the 3 CI lines; self-test 29 cases pass). pnpm --filter @objectstack/metadata exec vitest run --maxWorkers=2 src/plugin-artifact-forward-conversion.test.ts: 'Tests 2 failed | 4 passed (6)' with both CI assertion texts. (b) Same tree, this PR's two files copied in, blobs identical to the commit (gate dbe4fc5e0f, test a436ff248b): self-test '33 cases pass' with roll row '(0 at 18, 0 at 19.0.0-next.0)'; gate exit 0, 'no … citation names a major above 18', '3 live … 2 DORMANT … (major 18)'; metadata file 'Tests 6 passed (6)'. (c) main worktree at f7ec15171 (24dc0b32e plus merge of origin/main d206d08ca): self-test 33 pass, roll row '(0 at 17, 0 at 18.0.0-next.0)'; gate exit 0, 'above 17', '5 live'; metadata file 6/6; metadata package 'Test Files 61 passed (61) / Tests 880 passed (880)'; pnpm --filter @objectstack/metadata run typecheck (tsc --noEmit) exit 0, --listFiles includes the test file (61 test files). Collateral, generated tree, run to completion under the lock: service-settings 'Tests 755 passed (755)'; spec --project repo 'Test Files 57 passed (57) / Tests 997 passed (997)'; spec --project local 'Test Files 660 passed (660) / Tests 20021 passed | 1 todo (20022)'. Mechanism probe on the generated tree's built metadata-core (applyArtifactForwardConversions): '^18.0.0-next.0' → verdict converted-major-step, authoredFloor 18.0.0, notices [permission-allow-restore-purge-removed x2]; '^18.0.1' → authored-current, no notices. Ablation/mutation on main, all through node scripts/ablation-replace.mjs WRAP mode plus a shell EXIT/INT/TERM trap on absolute paths; every restore proven by blob == HEAD and git diff HEAD empty; no dist involved (a root script, and a test file vitest reads from src). Metadata: forcing '^18.0.0' into both pins (anchor x2 → x0, blob a436ff248b → 7b5528ffb1) reproduced both CI assertion texts verbatim ('Tests 2 failed | 4 passed (6)'). Gate M1, the label-relative floor count restored (anchor x1 → x0): self-test red on 3 rows, roll row '0 problem(s) at 17, 1 at 18.0.0-next.0 … holds 10 citation(s)'. Gate M2, dormancy line deleted: red on 2 rows, roll row '0 problem(s) at 17, 2 at 18.0.0-next.0'. Together M1 and M2 reproduce CI's 3 problems on main's real corpus. Gate union at f7ec15171 (= HEAD): see gates.", "gates": "Derived by node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at f7ec15171: 73 commands. Each was run with its exit code captured before any pipe. pnpm check:lean-entry-closure first exited 3 (PREREQUISITE NOT MET, no packages/objectql/dist); after building @objectstack/objectql it exited 0. --ran reconciliation: '73 derived famil(ies) accounted for — 72 run, 1 NOT-MEASURED (1 DERIVED from a recorded exit 3)', 0 UNRUN, and all 72 run exited 0, including check:future-spec-major, check:nul-bytes, check:cross-package-test-inputs, check:test-source-alias, check-position-name-fold-loaders, check:type-check-coverage and check:type-check-debt. NOT MEASURED: pnpm check:dual-build-cjs-loads, reason: PREREQUISITE NOT MET (whole-workspace dist absent, 73 packages unbuilt); declared narrowing, because the diff changes no built byte of any package. pnpm check:pm-dispatch-gates ran detached (nohup, tail --pid): exit 0, '1833 cases pass; 6 slow section(s) deferred' (fast tier). CI on PR head f7ec15171 at 04:23:55Z: in_progress (12 success, 10 skipped, 19 in_progress, 0 failure). origin/main has since moved 3 commits (121847a7d, 5d63c37c5, 719183f50); they are not merged and not measured here.", "line_budget": "226 changed lines (+202 / -24, 2 files) against the 3000 human-merge threshold: under. No skills/** and no governed surface touched.", "files_changed": [ "scripts/check-future-spec-major.mjs", "packages/metadata/src/plugin-artifact-forward-conversion.test.ts" ], "changeset": "none, label skip-changeset (applied; read back as size/m, tests, skip-changeset). Root package @objectstack/spec-monorepo is private. @objectstack/metadata files = dist, README.md, CHANGELOG.md. grep for currentSurfaceFloor in packages/metadata/dist: 0 files; positive control _parseAndRegisterArtifact: 6 files.", "deviations": [ "The reproduction clone lived at /tmp/r23135, not the scratchpad: the dispatch asked for a short path because of the tsx IPC socket limit. Deleted after use.", "npx tsc --noEmit --listFiles in packages/metadata (~15 s) ran outside os-verify-lock.sh.", "My first spec --project repo run on the clone printed no per-file output for ~16 min, so I stopped it by its recorded PID tree (my own processes only) and re-ran it with --reporter=verbose, which completed. The killed run had left two /tmp/build-schemas-* temp dirs symlinked into my clone; I removed them.", "The collateral suite runs (service-settings, spec repo, spec local) on the generated tree had this PR's two files present in the clone. Neither file is part of those suites' subject.", "Commit trailers use AGENTS.md's model-free pair (Claude-Session + 'Co-authored-by: Claude'), not the harness reminder's model-named Co-Authored-By. The PR footer uses AGENTS.md's session-URL form. The harness text yields to AGENTS.md.", "Sent one SendMessage status reply to the PM, as the probe asked. It is not a GitHub write." ], "mcp_calls": "0 — no MCP GitHub tool was called (reads via gh api REST; writes via scripts/pm relay)", "api_writes": "3 seat-side REST writes, each a POST /repos/objectstack-ai/objectstack/dispatches (the fleet-write relay, executed as objectstack-fleet[bot]), which issued 4 endpoints between them: (1) pr_create → POST /repos/objectstack-ai/objectstack/pulls (draft) + POST /repos/objectstack-ai/objectstack/issues/23155/assignees [zhuangjianguo]; (2) labels_add → POST /repos/objectstack-ai/objectstack/issues/23155/labels [skip-changeset]; (3) comment → POST /repos/objectstack-ai/objectstack/issues/23135/comments (this os-dev-report). Separately, git push x3 to claude/issue-23135-v18-version-pr-red (the empty-branch probe, the fix commit, the merge); these are not REST writes.", "open_questions": [], "out_of_scope_findings": [ "class: b · reach: public door `pnpm check:future-spec-major` (CI step in Type Check · source gates) on main. A tombstone citing major 18 for a change landing on main now goes RED and is prescribed 'Not shipped yet ⇒ the bare published major, which ADR-0087 guarantees is the carrier (a pre-GA retirement ships `minor`)', i.e. 17. Measured through the gate's own self-test row 'plain same-line citation above the major → RED' under a 17.4.0 manifest. But main is in Changesets pre mode: .changeset/pre.json says mode pre, tag next, entered by a87d8be29 'so v18 opens at 18.0.0-next.0', and 24 major changesets are queued. So that change first ships in 18.0.0-next.N, and ADR-0087's own test ('names the npm release it ships in') says 18. · Seam: spec:packages/spec/package.json version (17.7.0 under pre mode next) → runtime:scripts/check-future-spec-major.mjs readSpecMajor + its remedy text | consumer: none · This is a decision, not a fix: the same pre-mode family as #23042 (spec pre-mode retiredAfter guidance), so it should fold into that family rather than become a single-point card · dedupe words: pre mode next, future-spec-major, tombstone carrier, 18.0.0-next, published major prescription", "carrier: 承接者:无 · noted, not filed (PR Acceptance notes): the two QUOTATION_EXEMPTIONS entries (ADR-0087, v17-docs-sweep; major 18) become deletable once main itself carries 18.0.0-next.N or later, which happens after the maintainer lands the Version Packages PR. From then on the gate's pass line names them as DORMANT." ] }objectstack-fleet commentedon Oct 13, 2026
Review: ACCEPT · PR #23155 (draft, head
f7ec15171b) ·domain:devxseat 1 ·session_012zwsLMxQBwHUYJgPyrpEvx· 2026-10-13T04:27ZChecked on GitHub and on the branch, not on the report's say-so.
PR shape and scope
main, body line 1Fixes #23135, no other closing keyword in the body. Assigneezhuangjianguo; labelssize/m,tests,skip-changeset;mergeable: true.scripts/check-future-spec-major.mjs(+163 / −18);packages/metadata/src/plugin-artifact-forward-conversion.test.ts(+39 / −6).check-governed-merges --pr 23155), 226 lines. No ADR edit, nopackages/spec/src/**, and no edit tochangeset-release/mainor chore: version packages (next) #21988. That holds the maintainer's 「21988 是生成的,要修main 哦」.skip-changesetis right: one root script and one test file. The report shows the metadatadistcarries neither (currentSurfaceFloorhas 0 hits there).The four reds on #21988's head
63eb607ad1, as the report names themType Check · source gatesand its aggregatorTypeScript Type Check.Test Core (1/6)and its aggregatorTest Core.Type Check · workspacefinished green.ELIFECYCLElines ofspec:test:repoandservice-settings:testwere turbo's collateral stop. Both are green to completion on the generated tree (997 and 755 tests).The gate, read on the branch
f.major > SELF_FIXTURE_MAJOR(17), the major its fixtures are written against, instead of the tree's label. The anti-gutting guard holds across the roll: the new row "stripped of its fixtures is still RED once the tree reaches 18" pins it.QUOTATION_EXEMPTIONSentries withentry.major <= spec.majorbecome DORMANT: they are listed and not judged, and they excuse nothing. Onmain(17) the two major-18 entries stay live and judged. So nothing the gate refuses onmainis admitted; only the false "matched NOTHING" at the roll goes.18.0.0-next.0-shaped label, so this class reds onmainfirst.The test, read on the branch
currentSurfaceFloor()derivesmax(installed, retiredAfter of load-path-retired conversions)with patch + 1, which is the siblingplugin-unbound-form-predicate-roots.test.tsconvention. No assertion changed.metadata-coreshows the cause:^18.0.0-next.0gives verdictconverted-major-stepwith floor 18.0.0, which is the documented major-step half;^18.0.1givesauthored-current.Evidence (report)
63eb607ad1, with the CI texts.mainstays green: the gate, metadata 880/880, and typecheck.main's real corpus; forcing^18.0.0reproduces both metadata assertion texts. Every restore was proven.check:dual-build-cjs-loads, because no whole-workspace dist; the diff changes no built byte.mcp_calls: 0.CI on
f7ec15171b: 41 check runs at this review, none red, 11 still running. The seat lands the PR once every check is green or an expected skip. #23148's dogfood red onmainis the cli lane's, and this PR neither causes nor carries it.Pin (the card's item 3): after #21988 next refreshes from a
maincarrying this PR, every check on its head must be green or an expected skip. The seat reads that run.Out-of-scope findings
18.0.0-next.N(class b, the same pre-mode family): posted to spec(conversions): under a pre-mode label (18.0.0-next.N) the retiredAfter stamp guidance is unsatisfiable, and the census interim range admits 18.0.0, which its own PUBLISHED rule rejects after GA #23042, which is in flight on the spec lane, as a comment. Not filed as a single-point card.mainitself carries18.0.0-next.N: Acceptance notes.objectstack-fleet commentedon Oct 13, 2026
Maintainer order, this session, verbatim, and the reds hidden behind #21988's two roots ·
domain:devxseat 1 ·session_012zwsLMxQBwHUYJgPyrpEvx· 2026-10-13T05:09ZHow this seat will refresh. After PR #23155 lands, the seat dispatches
release.ymlatmainwithrefresh_version_pr: true.version-pr(release.yml:269-271).!inputs.refresh_version_pr(:848-850,:1344-1346), and the publish job needsrelease-integrity. So nothing is audited, published or queued at thereleaseenvironment.WORKFLOW_DISPATCH_ALLOWLIST(scripts/pm/fleet-write/ops.mjs) holds onlyshard-timings-refresh.yml, so this one dispatch goes from the seat's linked account on the order above.0 */6 * * *; recent ticks fired 20–30 min late) refreshes too, if it lands first.#21988 head
63eb607ad1, read at this act: 4 failed, 8 skipped, 32 green.scripts/pm/check-expected-skips.mjs's roster.publish-smoke / packed-tarballs) is green on every finished run since 02:57Z; one run is in progress.6138211879).Not measured on the v18 tree, because the reds stopped the jobs before they ran:
Type Check · source gates: steps 36–41 were skipped after step 35 (check:future-spec-major) failed:TemplateManifestSchema;llms.txt.Test Core (1/6): turbo stopped at@objectstack/metadata#test.spec,service-settingsandmetadataare proven green to completion on the generated tree (report6138211879).service-jobandservice-realtimecompleted green in CI.@objectstack/http-conformance,plugin-dev,plugin-pinyin-search,service-sms,knowledge-ragflow.A read-only probe is running those 6 gates and 5 packages now, on
63eb607ad1with PR #23155's two files overlaid. A red it finds is filed or fixed before the refresh. The refreshed head's own CI is the final reading.objectstack-fleet commentedon Oct 13, 2026
Landed: PR #23155 →
31a872d4e3(Fixes #23135) ·domain:devxseat 1 ·session_012zwsLMxQBwHUYJgPyrpEvx· 2026-10-13T05:39Zmain, both blobs equal the PR head:scripts/check-future-spec-major.mjsisdbe4fc5e0f;packages/metadata/src/plugin-artifact-forward-conversion.test.tsisa436ff248b.completedon the merge, andpm:dispatchedis removed with this record.release.ymlwithrefresh_version_pr: truefrom the linked account. Run38351525685succeeded (the bookkeeping lane only), and chore: version packages (next) #21988's head is now8826e954d5.63eb607ad1, with this PR's files overlaid, found step 37 (check-skills-token-ratchet) red at18.0.0-next.0. That is release(next): #21988 reds on the skills token ratchet at 18.0.0-next.0 (the prerelease version stamp adds 7 bytes to two SKILL.md files with 0 and 1 token of headroom) #23176. The maintainer ruled route A on it, and it is dispatched (claim6138995634). The probe's other readings are green: steps 35, 36 and 38–41, and the five Test Core packages that never started.maincarrying both this PR and release(next): #21988 reds on the skills token ratchet at 18.0.0-next.0 (the prerelease version stamp adds 7 bytes to two SKILL.md files with 0 and 1 token of headroom) #23176's fix reads every check green or an expected skip. The seat reads it on release(next): #21988 reds on the skills token ratchet at 18.0.0-next.0 (the prerelease version stamp adds 7 bytes to two SKILL.md files with 0 and 1 token of headroom) #23176's landing refresh.