Skip to content

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

Closed

Description

@objectstack-fleet

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:

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).

  1. Type Check · source gates: job 115105083441, run 38338685898, step "Check no prose dates a change to an unreleased @objectstack/spec major". 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.0 should count as published is the first question for the fix.
  2. Test Core (1/6): job 115105339463, run 38338686006. In @objectstack/metadata, Tests 2 failed | 878 passed (880), both in src/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:repo and @objectstack/service-settings:test end ELIFECYCLE with no failing test of their own in the log. The seat reads them as turbo's collateral stop; that is to be confirmed.
  3. Still running at filing: any further red check on this head joins this card.

What done looks like

  1. Reproduce every red check on the generated tree: a fresh depth-1 clone of changeset-release/main at chore: version packages (next) #21988's current head, the way release(next): Publish Smoke fails to build @objectstack/spec on 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.
  2. 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 the 18.0.0-next.N tree goes green.
  3. Pin: after chore: version packages (next) #21988 next refreshes from a main carrying the fix, every check on its head is green or an expected skip. The seat reads that run.

Activity

  1. added
    bugSomething isn't working
    priority:p1High: required for production / M2
    area:devpathThe road — create, dev, verify, publish/install, connect an agent, iterate
    on Oct 13, 2026
  2. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 4 · domain:devx seat 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_012zwsLMxQBwHUYJgPyrpEvx
    Account: zhuangjianguo (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-23135-v18-version-pr-red
    Worktree: objectstack-issue-23135
    Domain: domain:devx
    Seat: domain:devx#1
    File surface: scripts/check-future-spec-major.mjs (its published-major reading, floor and QUOTATION_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). ⛔ No packages/spec/src/** non-test. ⛔ No edit to changeset-release/main / #21988 (stop on breach; explain in the report)
    Container & model: M, mode:subagent, model: opus (the default judgment tier; dispatch-gates --tier on this surface: "no path-derived mandate", floor sonnet · default opus · ceiling fable)
    Clause-②: no
    Responsibility: scripts/check-future-spec-major.mjs and the @objectstack/metadata forward-conversion tests read the tree's version as "current" or "published", and both flip at the 18.0.0-next.0 roll (seat reading; not established) | no platform path covers it: main is at 17.x, and only #21988's tree carries the roll | #21988's CI reaches it on every refresh, so the next line is blocked
    Thread-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-* or docs/v17-docs-sweep.md (all open PRs' file lists read at this act). #23042 (open, spec pre-mode retiredAfter guidance) is related and unclaimed here: if the producer turns out to be #23042's site, the dev stops and reports.

  3. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    ContributorAuthor

    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."
      ]
    }
  4. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    ContributorAuthor

    Review: ACCEPT · PR #23155 (draft, head f7ec15171b) · domain:devx seat 1 · session_012zwsLMxQBwHUYJgPyrpEvx · 2026-10-13T04:27Z

    Checked on GitHub and on the branch, not on the report's say-so.

    PR shape and scope

    • Open, draft, base main, body line 1 Fixes #23135, no other closing keyword in the body. Assignee zhuangjianguo; labels size/m, tests, skip-changeset; mergeable: true.
    • Two files:
      • scripts/check-future-spec-major.mjs (+163 / −18);
      • packages/metadata/src/plugin-artifact-forward-conversion.test.ts (+39 / −6).
    • Not governed (check-governed-merges --pr 23155), 226 lines. No ADR edit, no packages/spec/src/**, and no edit to changeset-release/main or chore: version packages (next) #21988. That holds the maintainer's 「21988 是生成的,要修main 哦」.
    • skip-changeset is right: one root script and one test file. The report shows the metadata dist carries neither (currentSurfaceFloor has 0 hits there).

    The four reds on #21988's head 63eb607ad1, as the report names them

    • Type Check · source gates and its aggregator TypeScript Type Check.
    • Test Core (1/6) and its aggregator Test Core.
    • Shards 2–6 and Type Check · workspace finished green.
    • The shard-1 ELIFECYCLE lines of spec:test:repo and service-settings:test were turbo's collateral stop. Both are green to completion on the generated tree (997 and 755 tests).

    The gate, read on the branch

    • The self-fixture floor counts 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_EXEMPTIONS entries with entry.major <= spec.major become DORMANT: they are listed and not judged, and they excuse nothing. On main (17) the two major-18 entries stay live and judged. So nothing the gate refuses on main is admitted; only the false "matched NOTHING" at the roll goes.
    • Four self-test rows, with the floor going from 29 to 33. One re-runs the real corpus one major up under an 18.0.0-next.0-shaped label, so this class reds on main first.
    • That a prerelease counts as published is argued from the gate's header ("above the one this tree publishes") and from ADR-0087 ("names the npm release it ships in"), as the dispatch asked.

    The test, read on the branch

    • currentSurfaceFloor() derives max(installed, retiredAfter of load-path-retired conversions) with patch + 1, which is the sibling plugin-unbound-form-predicate-roots.test.ts convention. No assertion changed.
    • The report's mechanism probe on the generated tree's built metadata-core shows the cause:
      • ^18.0.0-next.0 gives verdict converted-major-step with floor 18.0.0, which is the documented major-step half;
      • ^18.0.1 gives authored-current.
    • So the old fixture, not the conversion source, was what moved with the label.

    Evidence (report)

    • (a) Both reds reproduced on a depth-1 clone of 63eb607ad1, with the CI texts.
    • (b) Both green there with the patch: the gate passes (33 cases), and the metadata file is 6/6.
    • (c) main stays green: the gate, metadata 880/880, and typecheck.
    • Mutations M1 and M2 together reproduce CI's 3 problems on main's real corpus; forcing ^18.0.0 reproduces both metadata assertion texts. Every restore was proven.
    • Gates: 73 derived, 72 run, all exit 0. NOT MEASURED: 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 on main is the cli lane's, and this PR neither causes nor carries it.

    Pin (the card's item 3): after #21988 next refreshes from a main carrying this PR, every check on its head must be green or an expected skip. The seat reads that run.

    Out-of-scope findings

  5. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    ContributorAuthor

    Maintainer order, this session, verbatim, and the reds hidden behind #21988's two roots · domain:devx seat 1 · session_012zwsLMxQBwHUYJgPyrpEvx · 2026-10-13T05:09Z

    • Order: 「release 分支 是手动刷新的 ,你改完了可以手动帮我刷」. The question before it: 「21988 还有其他 red 你也看了吗」.

    How this seat will refresh. After PR #23155 lands, the seat dispatches release.yml at main with refresh_version_pr: true.

    • That input runs only the bookkeeping lane version-pr (release.yml:269-271).
    • The integrity lane and the publish-repair lane both require !inputs.refresh_version_pr (:848-850, :1344-1346), and the publish job needs release-integrity. So nothing is audited, published or queued at the release environment.
    • The relay's WORKFLOW_DISPATCH_ALLOWLIST (scripts/pm/fleet-write/ops.mjs) holds only shard-timings-refresh.yml, so this one dispatch goes from the seat's linked account on the order above.
    • The 6-hourly tick (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.

    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:
      • the ratchet-remedy convention;
      • the skills token ratchet;
      • the react-blocks contract sync;
      • template manifests against TemplateManifestSchema;
      • the spec pin citations;
      • llms.txt.
    • Test Core (1/6): turbo stopped at @objectstack/metadata#test.
      • spec, service-settings and metadata are proven green to completion on the generated tree (report 6138211879).
      • service-job and service-realtime completed green in CI.
      • Never ran: @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 63eb607ad1 with 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.

  6. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed: PR #23155 → 31a872d4e3 (Fixes #23135) · domain:devx seat 1 · session_012zwsLMxQBwHUYJgPyrpEvx · 2026-10-13T05:39Z

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

Metadata

Metadata

Assignees

Labels

area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratebugSomething isn't workingdomain:devxpriority:p1High: required for production / M2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions