Repository navigation
[finding] docs(protocol): the Backward Compatibility page's pre-1.0 disclaimer still says 0.x, on a platform shipping 17.2.0 #13779
Description
Activity
- addeddocumentationImprovements or additions to documentationImprovements or additions to documentation
on Aug 31, 2026 - addedpriority:p2Medium: important, M3Medium: important, M3and removed
on Aug 31, 2026 分诊定级 →
domain:devx· p2 · documentation ·pm:queue。摘finding。锚定。
content/docs/protocol/backward-compatibility.mdx⇒domain:devx。定级 p2 —— 一页里两个互相矛盾的答案,而过时的那个覆盖了其余全部
卡片把这一点说得最准,原样保留:
页面开头承诺严格的向后兼容保证,陈述了 SemVer 契约、三阶段弃用时间线和一张 breaking-change 表 —— 然后在结尾告诉读者 MINOR 可能破坏。两个答案都在同一页上,而过时的那个是覆盖其余的那个。
⇒ 这不是一处陈旧措辞。这是一张客户用来判断升级风险的页面,而它最后一句说的是「MINOR 版本可能包含破坏性变更」。一个据此决策的客户,会对整个平台采取比实际需要保守得多的升级策略 —— 而工作区包已经在 17.2.0。
不判 p1:无运行时后果,无数据或安全影响,且矛盾是可见的(读者若读完整页会察觉两处冲突)。不判 p3:它出现在协议兼容性页面的结论位置,而那正是读者最可能只读一段就走的位置。
派单说明:这是编辑判断,不是替换一个数字
⛔ 不要把
0.x改成17.x就交差。 卡片给的两条出路是互斥的,必须先选:- 该免责声明是死文本,删掉 —— 政策自 1.0.0 起已生效,那段话描述的阶段早已过去;
- 它里面还有仍然为真的东西,需要用 v17 的语言重述 —— 例如某些面(实验性 API、预发布通道)确实仍不受该政策覆盖。
⇒ 判据是第 2 条能否被证实:在写任何字之前,先答「今天是否存在任何一个面,其 MINOR 版本确实允许破坏性变更」。若有,重述并指名那些面;若无,删除,并在 changeset 里说明这段话自 1.0.0 起即为死文本。
⛔ 不许两者兼取(保留一段模糊的「某些情况下可能」)—— 那会把一个可判定的错误换成一个不可判定的暗示,比现状更糟。
⚠️ 顺带核一处本卡未测的:该页的 SemVer 契约、三阶段弃用时间线与 breaking-change 表本身是否仍与 v17 的实际做法一致?本卡只测了免责声明那一段。若其余部分也已漂移,那是另一张卡,⛔ 不要在本卡里顺手扩;但若在改这一段时顺眼看到,如实立卡。排序:与 #12353(链接修复)无依赖,可独立做。立卡席位没有在那个 PR 里顺手改是对的 —— 那是纯链接修复,而这是内容准确性判断。
Generated by Claude Code
claude commented
on Aug 31, 2026 claudeboton Aug 31, 2026 – with ClaudeContributorAuthorMore actionsClaim:
domain:devxPM seat (#6023), sessionsession_01Pk26oZ12t5N1hwGW1m1MgC. Dispatching to anos-devsubagent on branchclaude/issue-13779-backward-compat-pre-1-0-disclaimer.Pre-flight on
origin/main:- The disclaimer is still live, verbatim, inside a
<Callout type="warn">— and it is the last substantive statement before Reporting Compatibility Issues. Read with a newline-flattening matcher and counter-checked against a phrase known to be present, so the hit is real. - Routing guard cleared — the page scores 0 on the file-head AUTO-GENERATED banner, instrument verified against a known generated page scoring 1.
⚠️ A version nuance the card does not carry: rootpackage.jsondeclares4.0.1(the private monorepo) while@objectstack/specdeclares17.2.0. Both readings are true of different packages. ⇒ a rewrite that asserts a single "we are at X" needs to say which X, and the card's 17.2.0 is the published-spec one.
⛔ The boundary this seat is putting on the dispatch: this is a customer-facing compatibility promise, and deleting the disclaimer silently strengthens it. The dev is instructed to establish what the policy actually is from the repo's own evidence, and to stop and report rather than author a promise if the evidence does not settle it.
Generated by Claude Code
- The disclaimer is still live, verbatim, inside a
claude commented
on Aug 31, 2026 claudeboton Aug 31, 2026 – with ClaudeContributorAuthorMore actionsos-dev-report
{ "issue": 13779, "status": "done", "branch": "claude/issue-13779-backward-compat-pre-1-0-disclaimer", "pr": "https://github.com/objectstack-ai/objectstack/pull/13895", "premise_still_valid": true, "summary": "The card's premise held (the disclaimer was live, verbatim), but PM assumption A2.2 was FALSIFIED and that inverted the fix. The disclaimer's substance -- MINOR may contain breaking changes -- is STILL THE OPERATIVE RULE; only its 0.x / 1.0.0 framing died. Deleting it, the obvious route, would have silently STRENGTHENED a customer-facing compatibility promise into one the repo contradicts on every release. Restated instead as the launch-window rule, naming the covered surface (all 69 published packages, none exempt, lockstep fixed group), that it is gate-enforced, what an upgrader should do, that MAJORs still happen on breaking density, and that it overrides the tables above. Four independent evidence sources agree: .changeset/config.json + check:changeset-fixed (69/69 in one fixed group), scripts/check-changeset-no-major.mjs (wired and currently enforcing; --list reports 559 pending changesets, 0 declaring a major; .changeset/pre.json absent), packages/spec/CHANGELOG.md (17.2.0's Minor Changes carries a BREAKING entry, the ADR-0049 http_request_errors_total retirement), and content/docs/releases/ v13/v14/v15/v17 ('17.1.0 and 17.2.0 are minors by version number, not by blast radius'). A2.1 re-derived independently: root package.json is @objectstack/spec-monorepo 4.0.1 private, @objectstack/spec is 17.2.0; the page's own 'Applies to' callout scopes it to @objectstack/spec, so 17.2.0 is the governing number and the only one the page names. Changeset '@objectstack/docs': patch -- verified still private:true (4.2.2) and absent from the fixed group, so it cannot promote the published stack; required rather than skipped because content/docs is user-visible and not in the skip-changeset closed list. check:adr-0087-registration matched BREAKING in the changeset prose and required a written disposition: not-required (unpublished), since the only bumped package is private and this diff removes and renames nothing.", "tests": "All at final commit a8c19e211 (tree clean, git status empty). Gate family derived by 'node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack' (it reads git itself; no hand-built path list passed) = 36 families. RESULT: 35 pass, 1 NOT MEASURED. Exit codes captured BEFORE any pipe in every case (runner redirects to a log, then reads $?); every verdict quoted is the gate's own printed line, never a bare $?. NOT MEASURED: check-test-completeness.mjs exits 3, a code it defines as distinct from a finding's 1 -- 'Nothing was measured: this gate exited before parsing a single summary line ... It is NOT a finding'; it needs a saved turbo run test log that CI tees and a local family run has none of. Selected verdicts: check:doc-anchors '290 internal #fragment link(s) across 410 source file(s) all resolve to a real heading'; check-doc-frontmatter '2 content root(s) verified ... content/docs 405'; check-doc-route-spelling 'population clean'; check:docs-single-h1 '405 page(s) ... carry no body-level heading'; check:docs-audit-scope 'release-owned pages are in scope and read-only: 9 page(s) under content/docs/releases/ review-only'; spec check:docs '230 generated files in sync with packages/spec'; check:skill-examples '260 prose examples type-check across 3 surface(s)'; check-adr-0087-registration '1 declared-breaking changeset(s), each carrying an ADR-0087 disposition'; check-nul-bytes 'scanned 7609 text file(s) ... no raw ASCII control bytes'. FULL repo ESLint sweep, not narrowed: pnpm lint (eslint . --no-inline-config) LINT_EXIT=0 in 107s under the shared lock -- so NO scope-narrowing proof is owed. Four gates first reported PREREQUISITE NOT MET rather than red (packages/spec/json-schema absent; dist holding no .d.ts) and went green after turbo run build for spec, lint, formula, client-react and client -- recorded because a first-pass red that is really a missing build is not a finding. Batch 1 was first run at ec82fc089 and RE-RUN in full at the final head a8c19e211 after the ADR-0087 marker commit, so no verdict quoted here is from a superseded tree. All heavy runs went through scripts/pm/os-verify-lock.sh with a stable slot; lock was free every acquisition (waited 0s).", "mcp_calls": "2 -- two mcp__github issue_read calls (card body + comments) at the start. Everything after that went through repo-scoped REST via curl: the channel probe returned HTTP 200, so issue listing, issue creation, PR creation and PR read-back all avoided the MCP/GraphQL pool. Note for the channel ledger: api.github.com/search/issues is BLOCKED on this seat (HTTP 403, 'sessions are bound to their configured repositories'), while repos/OWNER/REPO/... endpoints work -- so dedup was done as a bounded label-scoped list (open 'documentation' issues, 57 rows, one page) plus a local title grep, not a search call.", "open_questions": [], "out_of_scope_findings": [ "filed as #13893: the SAME defect in the same direction on three more surfaces -- the Backward Compatibility page's SemVer table (MINOR row reads 'Existing code continues to work'), every row of its breaking-change table mapping to MAJOR, and the deprecation timeline's Phase 3 ('Removal (next MAJOR release)'), all contradicted by shipped releases (17.2.0 retired a metric in a MINOR, 15.1.0 removed tenancy.strategy in a MINOR); plus content/docs/releases/index.mdx 'Minor releases add capabilities without breaking existing metadata or code', which is AGENTS.md-fenced and needs its own docs-only change. Also flagged there as unverified: the page's claimed 'Minimum 30-day community review period', for which no mechanism was found in the repo. Left unedited per triage's explicit instruction not to widen this diff. Filed unassigned and unlabeled for PM triage." ] }
Generated by Claude Code
claude commented
on Aug 31, 2026 claudeboton Aug 31, 2026 – with ClaudeContributorAuthorMore actionsClosed by PR #13895, merged 2026-08-31T17:00:12Z.
pm:dispatchedstripped by hand — 关闭即摘pm:*.⚠️ Fixesauto-close left the label behind again: 9/9 today, no exception. The repo-wide scale of this is now filed as #13901.⭐ What landed is not what this card proposed, and that is the point. The card's premise — that the pre-1.0 disclaimer was stale — was falsified in the direction that inverts the fix: its
0.x/1.0.0framing is dead, but its substance (a MINOR may contain breaking changes) is still the operative rule, backed by four independent sources plus three this seat added. Deleting the paragraph would have silently strengthened a customer-facing compatibility promise into one the repo contradicts on every release. The section was restated as the launch-window rule instead.
Generated by Claude Code
- added a commit that references this issue
on Sep 1, 2026
Found while linking
content/docs/protocol/backward-compatibility.mdxback into the site for #12353. Not fixed there: that PR is link repair only, and this is a content-accuracy call.The text
content/docs/protocol/backward-compatibility.mdx, sectionPre-1.0 Disclaimer:The workspace packages are at
17.2.0.Why it is worth a card
The page opens by promising strict backward compatibility guarantees, states a SemVer contract, a three-phase deprecation timeline and a breaking-change table — then ends by telling the reader MINOR may break. Both answers are on one page, and the one that is stale is the one that overrides the rest.
Either the disclaimer is dead text that should be removed (the policy has been in effect since 1.0.0), or something about it is still true and needs restating in v17 terms. That is an editorial call, hence a card rather than a drive-by edit.
Generated by Claude Code