Skip to content

[Decision] Previous-major support after 18.0 GA: correct the published N-1 promise to latest-only (A), an on-demand security line for N-1 (B), or a better-auth-style two-branch model (C)? #25102

Closed

Description

@objectstack-fleet

Ruled: 6328214336 · letter A · 2026-10-21T22:48Z

Filing gate: ② a decision only the maintainer can make.

Acting reader: the maintainer rules. Triage then records the ruling on this card and files the execution named under 裁后执行.

Dedup (MCP search_issues, closed included):

Governing text:

node scripts/pm/check-prior-rulings.mjs --terms "backport,maintenance line,support window,LTS,release branch,N-1,pre mode" finds 0 ADR decisions on these terms.

维护者速读

你想参考 better-auth 的做法:新大版本在测试时,旧版本继续出补丁;新版本转正后,旧版本再修几周安全问题。

矛盾:

  • 10 月 6 日对 17.x 的裁决正好相反:不建维护分支,不建第二条 npm 发布线,cloud 也不钉分支。10 月 7 日又定了不发最后一个 17.x。
  • 但公开文档 /docs/protocol/backward-compatibility 至今写着:「上一个大版本:只收严重缺陷和安全补丁」。
  • 从 8 到 18 的十个大版本里,这个承诺一次都没兑现过。
  • 所以无论选哪个字母,这句话都必须改成真话。

三个选项:

  • A(推荐):只支持最新大版本,把文档改成真话。
    • 文档写明:旧大版本不再收修复,升级走 ADR-0087 的转换层和 migrate meta。
    • 一个文档 PR,不加任何流程。
  • B:平时不开维护线,出高危安全修复时临时开。
    • 只在两个条件同时满足时开:出了高危及以上的安全修复,并且新大版本转正不满 4 周。
    • 做法:从上个大版本最后一个 tag 切分支,移植修复,用 release-N 标签发一个补丁版。
    • 要给发版流程加分支触发,并修改 10 月 6 日的两条裁决。better-auth 实际上就是这样运作的。
  • C:照搬 better-auth 的完整双分支模型。
    • 10 月 6 日已经否决过:main 每天大约 100 个提交,侧分支几天就会烂掉。

推荐 A。回一个字母:A / B / C。

如果你知道有付费的 EE 私有化客户停在 17.x、需要安全补丁,请选 B。

四棱(os-decision-facets)

  • ① 项目长远合理性:
    • A 把向后兼容放在协议里,而不是靠维护多条代码线。ADR-0087 的转换层和可执行迁移,能让晚了三个大版本的应用一次升到最新。这是 Salesforce 式的模型:所有客户在同一版本上,旧契约由平台转换。
    • B 是一个按需开的例外通道,契约增量小,但每次都要人工操作。
    • C 增加一条永久分支和四个工作流。
  • ② 实际业务拉动:
  • ③ 防 AI 犯错:
    • 现在文档承诺上一个大版本有补丁,AI 或用户照文档等补丁,会静默落空。A 让文档和行为一致。
    • B 和 C 的移植是人工挑提交,漏掉一个安全修复不会有任何报错。
  • ④ 创业阶段不扩散:
    • A 不增加任何流程。
    • B 增加一条按需发版通道,与「不建议再建立一套 npm 发布流程,我运维太麻烦」冲突。
    • C 增加一条永久分支和四个工作流。

Prior rulings read:

一句话问题

公开文档承诺「上一个大版本只收严重缺陷和安全补丁」,但旧大版本从来没收到过一个补丁。停在上一个大版本的自托管或 EE 私有化客户,要拿安全修复,只能连同下一个大版本的破坏性迁移一起接受。

我们是像 better-auth 那样继续给上一个版本线出补丁,还是把承诺改成「只支持最新大版本」?

Facts (read at this write, origin/main 1862d8d)

1. The published promise

content/docs/protocol/backward-compatibility.mdx:158 reads: "Previous MAJOR (N-1) | Maintenance | Critical bug fixes and security patches only".

No other page states a support window.

Re-check:

git grep -n -iE "End of Life|security patches only|support window" origin/main -- content skills README.md

This prints only this page's lines.

2. The rulings it contradicts

All are on #15193, from the triage seat's chat with the maintainer.

3. What npm shows

No version line of @objectstack/spec or @object-ui/core has ever published again after a newer line shipped.

  • spec ran majors 8 → 18 between 2026-06-07 and 2026-10-20.
  • 17.7.0 (2026-10-06) is the last 17.x.
  • 18.0.0-next.0 to next.5 went to next between 10-13 and 10-19.
  • 18.0.0 went to latest on 10-20.

Re-check:

for p in @objectstack/spec @object-ui/core better-auth; do printf '%s: ' "$p"; curl -s "https://registry.npmjs.org/$p" | jq -r '.time | to_entries[] | select(.key | test("^[0-9]+\\.[0-9]+\\.[0-9]+$")) | "\(.value) \(.key)"' | sort | awk '{split($2,v,"."); print v[1]"."v[2]}' | uniq | sort | uniq -d | tr '\n' ' '; echo; done

The command prints each version line that published again after a newer line shipped.

  • Today it prints nothing for both of ours.
  • better-auth is the positive control: it prints 1.4 1.5 1.6 1.7.

4. Why the stable line goes quiet during a prerelease

  • .github/workflows/release.yml:182-185 publishes on push to main only.
  • While main is in pre mode, every release is the next major's prerelease.
  • So between 17.7.0 (10-06) and 18.0.0 (10-20), npm latest users received no fix at all.

5. EE, the only measured candidate for a pull

The cloud repo's tags:

Tag Date What it says
ee-v4.1.0 08-20 "first stable on-prem image"
ee-v4.1.1 08-24 A hotfix, shipped by rolling the framework pin forward to main 502ff8b (#11610), not by a backport.
ee-v4.2.0 09-06 "moves onto the ObjectStack 17.3 platform line"
  • Customers deploy by digest: see the release-objectos-ee.yml header.
  • There has been no EE release since 09-06.
  • How many licensed EE customers there are is not measured.

Re-check:

git -C cloud ls-remote --tags origin 'ee-v*'
git -C cloud show ee-v4.1.1:.objectstack-sha

6. The reference: what better-auth does (read 2026-10-21)

Mechanisms:

  • main is stable 1.7.x, published to latest.
  • next carries 1.8.0-beta.N, in Changesets pre mode with the tag beta.
  • auto-retarget.yml moves a PR whose changeset is minor or major from main to next.
  • release.yml:
    • opens a main → next sync PR after every stable release;
    • publishes a vX.Y.x branch under the release-X.Y dist-tag.
  • promote.yml exits pre mode and opens a next → main PR.
  • backport.yml cherry-picks labelled PRs onto vX.Y.x.

In practice:

  • release-1.6 stopped at 1.6.33 on 09-14, four weeks after 1.7.0 (08-18).
  • v1.6.x took two more fixes (09-16 and 10-14) that were never published.
  • The critical GHSA-965c-763c-88jm (all versions below 1.7.7, published 09-30) shipped no 1.6 fix.
  • 1.4 and 1.5 ended the same way: 1.4.22 came two weeks after 1.5.0, and 1.5.6 came before 1.6.0.

7. What we already share with better-auth, and what we don't

Shared:

  • a lockstep Changesets fixed group: 73 packages against their 22;
  • majors through a prerelease tag before latest (ADR-0087 D6). Ours runs on main, theirs on a branch.

Different:

  • To keep breaking changes out of the stable line, we refuse a major changeset outside pre mode (check-changeset-no-major.mjs), where better-auth retargets the PR instead.

Missing:

  • a stable line that keeps receiving patches while the next major is in prerelease;
  • any line for the previous major after GA.

选项 × 代价 × 工作量

选项 做什么 客户可感知后果 工作量
A 把文档的 Support Windows 改成「只支持最新大版本;旧大版本不再收修复,升级走 ADR-0087 的转换层与 migrate meta」 自托管和 EE 客户读到的是真话:要安全修复就升级,不会再等一个不会来的补丁 devx 车道 · 1 个文档 PR · 先例 PR #22988(同一页,+18 −16,1 个文件)
B A 的文档改动,加上一条按需的安全线。三个条件同时满足才触发:① 高危及以上的安全修复;② 新大版本转正不满 4 周;③ 有具名用户停在上一个大版本。触发后从上个大版本最后一个 tag 切 release/N.x,移植修复,走同一个 release.yml 用 release-N 标签发补丁版,不打 latest 上一个大版本的用户在新版转正后 4 周内能拿到高危安全修复,不必马上迁移;4 周后同 A devx 车道 · 2–3 个 PR(release.yml 的分支触发与标签、移植规则、文档)· 无先例(#21993 在出 PR 前撤销)· 之后每次触发都要你合并、批准、写说明
C 照搬 better-auth:大版本在长期 next 分支开发,main 只收补丁,加上自动改目标分支、发版后自动同步、转正流程、移植工作流 同 B,而且新大版本测试期间旧版本照常收补丁 devx 车道 · 至少 5 个 PR · 无先例 · 常态成本是 main 每天约 100 个提交下的同步冲突,也就是 6017499711 否决侧分支模型的理由

业务含义直译

  • A:像 Salesforce。所有客户跑同一个版本,旧契约由平台转换兼容,不维护旧版本。
  • B:像保险的宽限期。换代后给老用户几周、只修安全漏洞,到期就停。better-auth 实际就是这样:1.6 在 1.7 发布约 4 周后停更。
  • C:像 Node.js 或 GitLab 的长期支持。两条线并行,靠专人或自动化维护。

推荐 + 置信缺口

  • 推荐 A。
  • 两年后的样子: 平台的兼容承诺写在协议里。晚了几个大版本的应用,靠 ADR-0087 的转换层和迁移链一次升到最新;安全修复只出在最新大版本上。参照 Salesforce 的单一版本加多版本契约模型,而不是维护多条代码线。
  • 不取 B: 拉动没有测到,而且与 6018081901、6018207607 冲突。B 真正需要的「从 tag 临时切分支」,6018207607 已经保留为「一个选项,不是计划」,选 A 不会失去它。
  • 不取 C: 6017499711 已经因为主干速度否决了长期侧分支,它的成本是常态的。
  • 置信缺口: EE 私有化付费客户的数量和所在版本没有测过。如果有客户停在 17.x、需要安全修复,B 的拉动就成立,应该改选 B。
  • 只看①选 A;②③④ 是否翻转:否。

裁后执行

  • A:
  • B:
    • Triage records the amendment of 6018081901 and 6018207607 here, then files the following.
    • A domain:devx card:
      • release.yml publishes from a release/N.x push under the release-N dist-tag, never latest;
      • publishing keeps the existing human approval;
      • the trigger conditions are written into the workflow header.
    • A backport-rule card, for how a fix reaches the branch.
    • The docs card from A, but stating the 4-week, high-or-critical window instead.
    • One cloud card naming which framework line each EE version tracks.
    • The window length and the severity floor are part of this ruling. The recommended values, if B, are 4 weeks and high or above.
  • C:
    • It needs an ADR first, because the branch model changes the release contract.
    • Then an epic with one card per workflow: retarget, sync, promote, backport, and the dual-channel release.yml.

Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 21, 2026

    @objectstack-fleet
    ContributorAuthor

    Ruling: batch #382 item 5 · letter A · maintainer 「24932 25133 帮我综合分析工作量和风险;25134 25092 25102 同意」 2026-10-21T22:44Z

    Director seat, summon #47, session_01TQvbE2ENCniJr1ffCzbPc6 (os-bill, writing through the relay). Presented in this session's chat as batch #382 item 5, from the card's analysis; the director's delta re-checked at this write: content/docs/protocol/backward-compatibility.mdx:153-159 still carries the Support Windows table with the N-1 "Maintenance" row; the card's npm re-check prints no re-published line for @objectstack/spec while the positive control better-auth prints 1.4 1.5 1.6 1.7; git grep -iE 'support window|backport|maintenance line|\bLTS\b' origin/main -- AGENTS.md docs/adr → 0 hits on the subject. The cloud repo is not attached to this session, so the EE tags were not re-read. Thread read to its end at this write: no comment on the card.

    Governing text: content/docs/protocol/backward-compatibility.mdx:153-159; ADR-0087 D6; the board rulings on #15193 (6017499711 → 6018081901 「不建议再建立一套 npm 发布流程,我运维太麻烦」 → 6018207607 「cloud 也不需要钉分支」) and on #22050 (6037890422).

    What the ruling binds

    1. Letter A: latest-only. The Support Windows table is replaced by a latest-only statement: the previous major receives no fixes; an application upgrades through ADR-0087's conversion layer and objectstack migrate meta. The page links both.
    2. Nothing is lost for an emergency. 6018207607 keeps "a branch can be cut from the recorded pre-v18 commit if an emergency ever needs one — an option, not a plan"; A does not retract it.
    3. Not taken: B (an on-demand security line: no measured pull, and it contradicts 6018081901 and 6018207607), C (the two-branch model, refused in 6017499711 for the mainline's commit rate). The confidence gap stays on record: if a paying EE customer is found on 17.x needing a security fix, that is a new card, and B's shape is the one to put to the maintainer then.

    Effort of the chosen letter: domain:devx · 1 docs-only PR (skip-changeset) · precedent PR #22988 (+18 / −16, the same page). The same PR checks the releases index for any contrary sentence.

    State: needs-user-decision → pm:queue. This card is the execution card (domain:devx, p2, documentation); no second card is filed. The domain:devx seat claims and dispatches.


    Generated by Claude Code

  2. objectstack-fleet commented on Oct 21, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 39 · the execution half of a p2 decision card the maintainer ruled letter A (ruling 6328214336, 「25134 25092 25102 同意」), routed to this lane's seat by the ruling. Serial dispatch under the maintainer's 「串行派发」.
    Session: session_01FM29ZqLTrnPNXxijioZwMp
    Account: os-warren (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-25102-support-windows-latest-only
    Worktree: objectstack-issue-25102
    Domain: domain:devx
    Seat: domain:devx#1
    File surface:


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 22, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 25102,
    "status": "done",
    "branch": "claude/issue-25102-support-windows-latest-only",
    "pr": "#25146",
    "session": "session_01FM29ZqLTrnPNXxijioZwMp (subagent run; the parent PM seat id, as the dispatch and the claim 6329002310 name it)",
    "premise_still_valid": true,
    "summary": "Executes ruling 6328214336, letter A. The Support Windows section of backward-compatibility.mdx (:153-:159 at abc25a3) loses its three-row N / N-1 / N-2 table and now states latest-only support. Only the current MAJOR receives fixes, which ship in the next release cut from main, so during a prerelease a fix reaches latest only at the next GA. The previous MAJOR and every older one receive none, and no backport or maintenance release is promised. An older app upgrades through ADR-0087 D2 (load-time conversion of the previous MAJOR's lossless changes) and os migrate meta (D3: --from N down to the protocol-16 floor, --write, --stored --apply); the page links the ADR, the CLI reference and Upgrading. D6 is cited for the next dist-tag, with v18 as the measured instance. The heading text is kept, and the page names no emergency branch, date, window or EE promise. Two sentences the new statement would have contradicted were corrected, each named in the PR body with before and after. The :142 callout no longer gives doctor, diff and the CHANGELOG as the way to upgrade across majors: os migrate meta is named for metadata, and the three tools cover what it does not rewrite; the false "referenced in the migration guides" clause is gone. releases/index.mdx:22 now labels v17 "(final release: 17.7.0)" instead of a second "current series"; every release gate accepts this wording, and the version-time rewriter leaves it alone. Commits carry AGENTS.md's model-free trailer pair, and the PR body carries the session-URL footer. The harness reminder's model-named Co-Authored-By trailer and its alternative PR footer were reported, not imitated.",
    "tests": "All readings are at head 062bfaf. Premise re-checks, the card's own, verbatim, at origin/main abc25a3: git grep -n -iE "End of Life|security patches only|support window" origin/main -- content skills README.md -> exit 0, only backward-compatibility.mdx:153, :158 and :159. The npm probe -> @objectstack/spec and @object-ui/core print nothing; better-auth prints 1.4 1.5 1.6 1.7 (positive control). A wider grep (maintenance line, previous major, N-1, LTS, backport, EOL) -> 13 lines, none a support window, so no other page joins the surface. A releases-tree grep -> 14 lines, none promising a previous-major fix; the only contrary statement is the v17 current-series label. Inbound anchors: #support-windows -> exit 1 here and exit 1 in ../objectui at b014f5eea (control leg exit 0). MDX: both pages compile with @mdx-js/mdx 3.1.1 (exit 0); an unclosed-Callout control is refused (exit 1, "Expected a closing tag"). Docs site build under the verify lock: turbo build --filter=@objectstack/docs^... then pnpm --filter @objectstack/docs run build -> VERDICT command-exit 0, "Compiled successfully in 2.2min", 1275/1275 static pages, apps/docs/.next/BUILD_ID present. In the built output, the new lead sentence is in 5 files (including en/docs/protocol/backward-compatibility.html), the removed sentence in 0, and "final release: 17.7.0" in 5. Prerequisite build: turbo build --filter=@objectstack/lint... --filter=@objectstack/client-react... --concurrency=2 -> VERDICT command-exit 0, 37/37 tasks. skip-changeset: 0 of 73 non-private manifests ship content/docs; the removed and added phrases match 0 files under packages/ (dist included); control defineStack matches 989. Control-byte grep on both files -> exit 1 (none). merge-tree against origin/main 4c7dcb4 -> exit 0. No package touched, so no package test or typecheck is owed. No ablation, because no tested behaviour changed.",
    "gates": "Local subset: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at 062bfaf -> 49 commands, the same list as at 2b3b50b (diff exit 0). All 49 ran, each exit code captured before any pipe: 49 x exit 0. --ran -> exit 0, "49 derived famil(ies) accounted for — 49 run, 0 NOT-MEASURED (a DERIVED zero — all 49 recorded an exit code and none of them is 3)". Verdict lines: check:doc-anchors, 566 links across 424 files resolve; check:docs-redirects OK; check:docs-audit-scope in sync, 206 hand-written docs, no handwritten-docs.json write; check-release-section-coverage OK, plain and --strict; check:release-page-status OK; check:release-notes OK; check:lockstep-package-count 73; check:nul-bytes OK over 11726 files; spec check:docs, 227 in sync; check:skill-examples, 262. A first battery pass on 2b3b50b (also 49 x exit 0) is superseded: the :142 wording changed mid-run, so the union was re-derived and re-run on the final head. NOT MEASURED locally (CI-owned, no local invocation): the 3 workflow-valued families, the Test Core shards, the 4 Type Check lanes, and pnpm lint. PR #25146 check-runs, read once at 00:22Z: Check Changeset success; No other open PR may claim the same issue success; opt-in and auto-label jobs skipped. In progress: Lint (9 lanes), Type Check (4 lanes), Check Documentation Links, Spec property liveness, Governed Surface Queue Guard, The card this PR closes must claim this branch, the single-writer path guard, the Part-of guard, Check PR Size, filter. Test Core, Build Core and Build Docs were not yet listed.",
    "mcp_calls": "6, all reads: issue_read get #25102, issue_read get_comments #25102, pull_request_read get #22988, pull_request_read get_diff #22988, pull_request_read get #25146, pull_request_read get_check_runs #25146. No MCP write tool.",
    "api_writes": "2 relay strokes, each one POST /repos/objectstack-ai/objectstack/dispatches. (1) pr_create -> POST /repos/objectstack-ai/objectstack/pulls (draft), POST /repos//issues/25146/assignees [os-warren], POST /repos//issues/25146/labels [skip-changeset, documentation]. Read-back: body 19370 of 19370 bytes identical, assignee os-warren; labels documentation and skip-changeset read back on the PR. (2) This os-dev-report comment -> POST /repos//issues/25102/comments via scripts/pm/post-stamped.mjs. Plus 3 git pushes, which are not REST writes. Every other REST call was a read.",
    "open_questions": [],
    "out_of_scope_findings": [
    "class: a · reach: the public docs page /docs/releases (content/docs/releases/index.mdx:21) states "(current series: 18.0.0, released 2026-10-19)" · evidence: Version Packages commit 06cab48 is dated 2026-10-20T11:47Z, npm time[18.0.0] is 2026-10-20T12:51Z, and releases/v18/18-0.mdx:3 says "published 2026-10-20". Mechanism: 8fbbd50 wrote the status before the cut, and sync-release-index-currency.mjs leaves a current-series field that already names the newest GA "whatever its date", so the version step never stamped it · dedupe words: release index 18.0.0 released date; current series released 2026-10-19; sync-release-index-currency date",
    "class: a · reach: the public docs page /docs/releases/v17 (the content/docs/releases/v17/index.mdx status blockquote) states "A plain install now resolves 17.7.0" while npm dist-tags.latest is 18.0.0 · evidence: npm dist-tags show latest 18.0.0; check:release-page-status passes the page because it judges released-ness, not currency · same family as the item above (release-currency prose after the 18.0.0 GA cut), so one card covers both · dedupe words: v17 release status plain install resolves 17.7.0; release page currency after GA",
    "carrier: none · noted, not filed — ADR-0087 D6 (every major on next for at least one RC cycle) against npm: majors 8-15 published no prerelease, 16 and 17 used -rc.N on the rc dist-tag, and only 18 used next. The 2026-07-15 addendum still lists the D6 RC discipline as deferred. History with no reach; the page cites D6 and names only v18 (PR Acceptance notes)",
    "carrier: none · noted, not filed — prose that paraphrases the old :142 callout ("not yet available"): the comments at packages/cli/src/commands/doctor.ts:2680 and doctor-deprecation-hint-commands.test.ts:18, and docs/qa/platform-checklist/areas/cli.json:1189. The same doctor.ts comment says both of os migrate meta's writes are --out JSON snapshots, which predates --write. Code and QA data outside this PR's surface; nothing reads or compares them (PR Acceptance notes)"
    ]
    }


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 22, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 25102,
    "status": "done",
    "branch": "claude/issue-25102-support-windows-latest-only",
    "pr": "#25146",
    "session": "session_01FM29ZqLTrnPNXxijioZwMp (subagent run; the parent PM seat id, as the dispatch, the claim 6329002310 and this fix round name it)",
    "premise_still_valid": true,
    "summary": "Fix round 1: new commit f453405 on top of 062bfaf (no amend, rebase or force-push); it removes the ADR-0087 D6 citation, which the ADR's own as-built addendum lists as deferred. The "Testing a MAJOR" bullet now rests on scripts/check-changeset-no-major.mjs as found at origin/main 459afea (fails a pull request declaring a major bump outside Changesets pre mode at :682, stands aside inside it at :681, with the RC EXEMPTION header at :113-:120). A MAJOR declared in pre mode publishes only prereleases on the pre-mode dist-tag until pre mode exits; v18 used next (18.0.0-next.0 … next.5); install from that tag. The current-MAJOR bullet now says "the pre-mode dist-tag (next on the v18 line)". One wording departs from the ruling's letter, and is reported rather than silently chosen: the page avoids "can only be declared in pre mode … never latest". The guard's allow-major label escape hatch (header :122-:124, read live at pr-automation.yml:1063) skips it outside pre mode, so the page uses the indefinite "fails a pull request" form PR #22988 adopted for this same reason, plus the Changesets pre-mode semantics, which always hold. If the seat prefers the absolute wording, the allow-major qualifier would have to go on the page. Nothing enforces the pre tag (cut-rc.yml:235 requires tag rc for its own lane only, and v18 ran next through release.yml), so the page names no future tag. The exact PR-body replacement passages are in pr_body_replacements; nothing else on the page changed.",
    "pr_body_replacements": {
    "R1 — replaces the whole table row that starts "| The current MAJOR:"": "| The current MAJOR: bug fixes and security patches ship in the next release cut from main. While the next MAJOR is in prerelease, every release cut from main is one of its prereleases on the pre-mode dist-tag (next on the v18 line), so a fix reaches latest only when that MAJOR goes GA. | .github/workflows/release.yml's header: npm publish lives in one job, reachable only from a push to main and from the repair dispatch, and the repair "cannot mint a version". The card's fact 4 measured the consequence: between 17.7.0 and 18.0.0, latest received no fix. The page's own top callout already states the pre-mode half. The tag is written "the pre-mode dist-tag" because nothing fixes it: changeset pre enter takes the tag as an argument, v16 and v17 ran on rc and v18 on next, and .github/workflows/cut-rc.yml:235 requires tag: rc for its own lane only. |",
    "R2 — replaces the whole table row that starts "| Testing a MAJOR before it reaches latest:"": "| Testing a MAJOR before it reaches latest: scripts/check-changeset-no-major.mjs fails a pull request that declares a major bump outside Changesets pre mode and stands aside inside it, and a MAJOR declared in pre mode publishes only prereleases, on the pre-mode dist-tag, until pre mode exits. The v18 line used next (18.0.0-next.0 … 18.0.0-next.5) before 18.0.0. Install from that tag to run your app against a MAJOR before it becomes latest. | scripts/check-changeset-no-major.mjs at origin/main 459afea1f6: judge() (:678-:683) returns exempt when .changeset/pre.json has mode: 'pre' (:681) and enforce otherwise (:682). The exempt case exits 0 (:818-:826), and the enforce case prints the refusal (:828). The RC EXEMPTION header (:113-:120) states the Changesets semantics: in pre mode "a major bump only ever produces a … PRE-RELEASE version — nothing final publishes until changeset pre exit". npm: 18.0.0-next.0 (2026-10-13) to 18.0.0-next.5 (2026-10-19), then 18.0.0 (2026-10-20). The page says the guard fails "a" pull request, not "any", and it does not say a MAJOR can be declared only in pre mode, because the guard's allow-major label escape hatch skips it outside pre mode (header :122-:124; the label is read live at .github/workflows/pr-automation.yml:1063). |",
    "R3 — replaces the whole Acceptance-notes bullet that starts "- D6 against what npm shows.", including its three sub-bullets and its closing paragraph": "- ADR-0087 D6 is not cited. D6 reads "Every major is published to the next dist-tag at least one RC cycle before latest", but the ADR's 2026-07-15 as-built addendum lists "P3 — MCP tools + RC discipline (D6): deferred, evidence-gated", and npm @objectstack/spec does not follow it:\n - majors 8 to 15 published no prerelease version at all (0 in the registry). That was the pre-launch window, which the same addendum ratifies for 12 to 15.\n - 16 and 17 ran -rc.N prereleases (16.0.0-rc.0 and rc.1; 17.0.0-rc.0 to rc.6), and the rc dist-tag still points at 17.0.0-rc.6.\n - only 18 ran on next.\n\n So both prerelease clauses rest on scripts/check-changeset-no-major.mjs, which holds today, and name next only as the v18 instance. Nothing found fixes which tag a future pre mode uses, so the page names none. Not filed: it is history, with no reach. Carrier: none.",
    "R4 — replaces the Gates section from its first line ("All readings below are at this branch's head 062bfaf1dd …") through the "- Prerequisite build." bullet; the verdict-line bullets after it stand unchanged (re-measured, same values)": "All readings below are at this branch's head f453405903, against origin/main merge base abc25a3536.\n\n- Derivation. node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 49 commands: 33 pnpm and 16 direct node; 41 matched by path and 8 declared whole-tree. The change set is 2 paths and 16 changed lines. The list is identical at 2b3b50b4da, 062bfaf1dd and f453405903 (diff exit 0).\n- Ran all 49. Each exit code was captured before any pipe. All 49 exited 0.\n- Reconciliation. --ran printed: "✓ dispatch-gates --ran: 49 derived famil(ies) accounted for — 49 run, 0 NOT-MEASURED (a DERIVED zero — all 49 recorded an exit code and none of them is 3)."\n- Prerequisite build. pnpm exec turbo run build --filter='@objectstack/lint...' --filter='@objectstack/client-react...' --concurrency=2 ran under scripts/pm/os-verify-lock.sh: VERDICT command-exit 0, 37 of 37 tasks. In this round all 37 were cache hits on the same inputs.",
    "R5 — replaces the "- Docs site build." bullet (with its sub-bullets and its closing paragraph) and the "- Merge probe." bullet that follows it": "- Docs site build. Run locally at 062bfaf1dd as the production build that CI's Build Docs runs (apps/docs/vercel.json buildCommand), with one declared difference. CI forces turbo (TURBO_FORCE) so the docs task cannot be a replayed cache hit; locally the docs package's own build script ran directly, outside turbo's cache, after its dependencies built: pnpm exec turbo run build --filter='@objectstack/docs^...' --concurrency=2 && pnpm --filter @objectstack/docs run build, under the verify lock. Results:\n - VERDICT command-exit 0;\n - "✓ Compiled successfully in 2.2min";\n - "✓ Generating static pages using 2 workers (1275/1275)";\n - apps/docs/.next/BUILD_ID present.\n\n It was not re-run locally at f453405903. The derivation names it only as CI's Build Docs job, as before, and the fix changed text inside two bullets without changing the MDX shape: both pages compile, and the unclosed-Callout control is refused. CI's Build Docs check-run on f453405903 concluded success.\n- Merge probe. git merge-tree --write-tree against origin/main 459afea1f6 exits 0 (tree e475552dea). main has moved two commits since the base, and neither touches either path."
    },
    "tests": "At head f453405. Guard source read at origin/main 459afea: judge() :678-:683 (exempt :681, enforce :682); exempt render exits 0 :818-:826; enforce refusal :828; RC EXEMPTION header :113-:120; allow-major escape hatch header :122-:124 and pr-automation.yml:1063. Pre-tag enforcement search (pre enter, pre.json tag checks across scripts, .github, .changeset and package.json at origin/main): only cut-rc.yml:235 requires tag rc for the cut-rc lane; nothing binds the release.yml lane's tag. grep -c D6 on the page -> 0. MDX: both pages compile with @mdx-js/mdx 3.1.1 (exit 0); the unclosed-Callout control is refused (exit 1). Control-byte grep -> exit 1 (none). merge-tree against origin/main 459afea -> exit 0, tree e475552dea, no main commit since BASE touches either path. Prerequisite build under the lock -> VERDICT command-exit 0, 37/37 tasks (all cached). The docs site build was not re-run locally (MDX shape unchanged); CI Build Docs on f453405 concluded success, and the local build at 062bfaf passed (1275/1275 pages, BUILD_ID present). No package touched: no package test or typecheck owed. No ablation: no tested behaviour changed.",
    "gates": "Local at f453405: dispatch-gates --commands --repo objectstack-ai/objectstack -> 49 commands, identical to the previous rounds (diff exit 0). All 49 ran, each exit code captured before any pipe: 49 x exit 0. --ran -> exit 0, "49 derived famil(ies) accounted for — 49 run, 0 NOT-MEASURED (a DERIVED zero — all 49 recorded an exit code and none of them is 3)". Verdicts: check:doc-anchors, 566 links across 424 files resolve; check:docs-audit-scope in sync, 206 hand-written docs; check-release-section-coverage OK; check:release-page-status OK; check:lockstep-package-count 73; check:nul-bytes OK over 11726 files. PR check-runs on f453405, read once: 40 total, 30 success, 8 skipped, 2 in_progress, 0 failure. Successes include Lint & Repo Gates, TypeScript Type Check, Governed Surface Queue Guard, Build Docs, Check Documentation Links, every Lint and Type Check lane, and Test Core 3/6 to 6/6. Test Core 1/6 and 2/6 are in_progress; Build Core is skipped.",
    "mcp_calls": "This round: 0. Run total: 6, all reads (issue_read get and get_comments #25102; pull_request_read get and get_diff #22988; get and get_check_runs #25146). No MCP write tool, ever.",
    "api_writes": "This round: 1 relay stroke, POST /repos/objectstack-ai/objectstack/dispatches -> POST /repos//issues/25102/comments (this os-dev-report, via scripts/pm/post-stamped.mjs), plus 1 git push (062bfaf..f453405, fast-forward, not REST). Run total: 3 relay strokes (pr_create with its assignee and label legs; two os-dev-report comments) and 4 git pushes. No PR body PATCH, no review request, no ready flip.",
    "open_questions": [],
    "out_of_scope_findings": [
    "class: a · reach: the public docs page /docs/releases (content/docs/releases/index.mdx:21) states "(current series: 18.0.0, released 2026-10-19)" · evidence: Version Packages commit 06cab48 is dated 2026-10-20T11:47Z, npm time[18.0.0] is 2026-10-20T12:51Z, and releases/v18/18-0.mdx:3 says "published 2026-10-20". Mechanism: 8fbbd50 wrote the status before the cut, and sync-release-index-currency.mjs leaves a current-series field that already names the newest GA "whatever its date" · dedupe words: release index 18.0.0 released date; current series released 2026-10-19; sync-release-index-currency date",
    "class: a · reach: the public docs page /docs/releases/v17 (the content/docs/releases/v17/index.mdx status blockquote) states "A plain install now resolves 17.7.0" while npm dist-tags.latest is 18.0.0 · evidence: npm dist-tags show latest 18.0.0; check:release-page-status passes the page because it judges released-ness, not currency · same family as the item above, so one card covers both · dedupe words: v17 release status plain install resolves 17.7.0; release page currency after GA",
    "carrier: none · noted, not filed — ADR-0087 D6 against npm (majors 8-15 no prerelease; 16-17 on rc; only 18 on next) and the addendum's "deferred" status. The page no longer cites D6 (R3 above)",
    "carrier: none · noted, not filed — prose paraphrasing the old :142 callout ("not yet available"): doctor.ts:2680, doctor-deprecation-hint-commands.test.ts:18 and platform-checklist cli.json:1189. The same doctor.ts comment says both of os migrate meta's writes are --out JSON snapshots, which predates --write"
    ]
    }


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 22, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:devx seat 1 · session_01FM29ZqLTrnPNXxijioZwMp · 2026-10-22T01:05Z

    reading result
    merge queue none left: the entry has drained
    PR object PR #25146 merged at 2026-10-22T01:04Z as f35b4e18fe (ACCEPT 6329925392; not governed; Fixes #25102)
    origin/main, by content content/docs/protocol/backward-compatibility.mdx (77e82e8141) and content/docs/releases/index.mdx (74aa5bfa23) are byte-identical to the head f453405903

    State change: PR #25146 closed this card through Fixes #25102 (completed). pm:dispatched comes off in this act.

    On main, ruling 6328214336 letter A is executed:

    • /docs/protocol/backward-compatibility's Support Windows section states latest-only support. Only the current MAJOR receives fixes, and the previous MAJOR and every older one receive none, with no backport or maintenance release promised. An older app upgrades through ADR-0087's conversion layer (D2) and os migrate meta (D3). Its prerelease clauses rest on scripts/check-changeset-no-major.mjs, not on D6, which the ADR lists as deferred.
    • The releases index labels v17 "(final release: 17.7.0)".

    The dev's out-of-scope release-currency pair is #25148 (p3).


    Generated by Claude Code

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, iteratedocumentationImprovements or additions to documentationdomain:devxpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions