Skip to content

docs: 清偿门禁记账里的 8 处版本失真 — 无锚宣称删版本指真相、脚手架记录对齐生成器、有锚重述收窄到清单 (#3708, #3709, #3710) - #3726

Merged
yinlianghui merged 1 commit into
mainfrom
claude/issue-3708-version-claims-payoff
Aug 8, 2026
Merged

docs: 清偿门禁记账里的 8 处版本失真 — 无锚宣称删版本指真相、脚手架记录对齐生成器、有锚重述收窄到清单 (#3708, #3709, #3710)#3726
yinlianghui merged 1 commit into
mainfrom
claude/issue-3708-version-claims-payoff

Conversation

@yinlianghui

@yinlianghui yinlianghui commented Aug 8, 2026

Copy link
Copy Markdown
Collaborator

Fixes #3708
Fixes #3709
Fixes #3710

清偿 PR #3711 门禁记账的 9 处失真里属这三单的 8 处(第 9 处 plugin-report/README.md:24 的修法在清单侧,归 #3690,本 PR 一字未动)。6 文件,+69 / -94。

前提复核:三单全部成立,行号也没漂

origin/main(切点 36bf20235,即 PR #3711 的合并点)逐处核过,8 处宣称全在,与 ledger 记的一致。两个反读也复现:29 个 packages 清单全部 @objectstack/spec: ^17.0.0-rc.5,34 处 typescript 全部 ^6.0.3 —— 均匀,不存在「部分包还在旧大版本」这种能救散文的读法。

处置按失真性质分三类,不套统一口径

裁决要求分类执行,实测下来三类的处置方向确实不同,记在这里免得读成不一致。

一、无锚宣称(#3708 三处)—— 删版本号,指真相

#3645 / PR #3688 立下的仓规:版本号入散文即漂移保证,一律不改写成 rc.5 / ^6,重写等于把同一台漂移机器重新上膛。

content/docs/guide/architecture-overview.md,三层架构 ASCII 图内(围栏里,这正是 #3711 决定扫描围栏而非抹掉围栏的实测依据之一):

- │  Layer 1: @objectstack/spec ^4.0.4 (The Protocol)                  │
+ │  Layer 1: @objectstack/spec (The Protocol)                         │

删掉 7 个字符、补回 7 个空格,该行长度保持 70 不变(方框本就因宽字形而各行不等宽,:18 是 69 —— 这个既有偏差不是本 PR 引入的,也没被本 PR 改动)。

同页散文:

- Located externally; consumed as `@objectstack/spec ^4.0.0`.
+ Located externally and consumed as `@objectstack/spec`; the range each package
+ installs is declared in that package's own `package.json`, under `dependencies`.

照 PR #3698 处理 Node 行的办法:真相存在(每个包清单的 dependencies)、由包管理器安装期强制,所以保留句子、把值改成指针,而不是整句删掉。

content/docs/guide/architecture.md:317:

- ObjectUI is built with **TypeScript 5.0+** in strict mode:
+ ObjectUI is built with **TypeScript** in strict mode:

这一处不加指针,与上一处不同处置,理由据实:这句话的主语是 strict mode 而不是编译器版本;而 TypeScript 的声明是贡献者工具链事实(34 处 devDependencies),不是消费者约束(包发 .d.ts),指过去会让读者以为那是安装要求。PR #3688 对同一条宣称的处置也是直接删版本(「差一个大版本,且无处可核实」)。

二、脚手架记录(#3709)—— 对齐真实生成形态,不再逐字复制

先按裁决实测当前生成形态(truth = packages/create-plugin/src/index.ts 的 manifest 字面量),测出的不符远多于 ledger 记的三行:文档那份 package.json 还多报了一个 files 字段、少报了 type / license / module / exports / dependencies / devDependencies,main 也写错(文档 dist/index.js,实为 dist/index.umd.cjs)。

处置取「改写为无版本形态」而非「入 ledger」,以该页上下文取舍,理由:这一页没有任何门禁或测试守着,而它已经证明了自己会漂;把一份逐字复制的 manifest 记成 restatement,等于宣告一个无人强制的等式。改为描述真实形态 + 指向生成器模板本身:

- ```json
- {
-   "name": "@object-ui/plugin-awesome",
-   ...
-   "peerDependencies": {
-     "@object-ui/core": "^0.3.0",
-     "@object-ui/components": "^0.3.0",
-     "react": "^18.0.0"
-   }
- }
- ```
+ Pre-configured with all necessary settings: the package identity (...), the build
+ entry points (...), and its `scripts`.
+
+ It also writes three dependency groups:
+
+ - `dependencies` — four `@object-ui` workspace packages plus an icon library, written
+   as workspace links rather than as published version ranges. Note the field: the
+   generator puts these under **`dependencies`**, not under `peerDependencies`.
+ - `peerDependencies` — `react` and `react-dom`, ...
+ - `devDependencies` — what the generated Vite build and its tests need.
+
+ Do not transcribe version ranges out of this page into a hand-written manifest. ...

「字段错」这一半因此被正面写进散文(dependencies,不是 peer)—— 这是读者照做会坏的根因,删掉数字并不会让它自己消失。

三、有锚重述(#3710)—— 对齐清单,不删

与前两类方向相反:这一族有同包 package.json 作锚,分诊已裁 B(保留并钉住),所以处置是收窄到与清单逐字一致,而不是删版本号。

packages/layout/README.md —— 分诊追评把同一块里的另外两行也并入本单(README 承诺 >=,清单其实拒绝更高大版本,方向是过度承诺,读者照装会拿到 peer 冲突):

- - `react` >= 18.0.0
- - `react-dom` >= 18.0.0
- - `react-router-dom` >= 6.0.0
+ - `react` ^18.0.0 || ^19.0.0
+ - `react-dom` ^18.0.0 || ^19.0.0
+ - `react-router-dom` ^6.0.0 || ^7.0.0

三行现在与 packages/layout/package.jsonpeerDependencies 逐字相等,已用脚本核对(三行全 MATCH)。

packages/plugin-chatbot/README.md:58:

- using `@ai-sdk/react` v3 (Vercel UI Message Stream protocol) for streaming,
+ using `@ai-sdk/react` v4 (Vercel UI Message Stream protocol) for streaming,

清单是 ^4.0.47,取其主版本。保留而不删的理由:全语料唯一一处指名协议来源的宣称,读者据它去查协议文档;删掉即失去该信息。这里刻意改写成不带点也不带符号的裸「4」—— 那个拼写门禁的 VERSION 正则匹配不到(它自己的头注已写明这个已知召回缺口),写成裸大版本等于绕过门禁,所以写 v4 并入 ledger。

ledger 清偿:27 -> 21 条,stale 9 -> 1

kind 修前 修后
anchored 1 1
restatement 11 12
sample 5 5
unanchored 2 2
stale 9 1
合计 27 21

棘轮两步(照 #3703 手法):方向先预测,后跑

裁决要求「清前红报陈旧点名、清后绿」。两步都先写下预测再跑,且预测精确到条数与条目名

步骤一 —— 文档已改、ledger 未动

预测:两条测试变红。「no entry may outlive the claim」点名 8 条(6 条被删的 + 2 条 claim 文本变了的);「records every version literal」点名 2 条新宣称;并且 react-dom / react-router-dom 两行不会出现 —— 依据不是猜:packages/auth/README.md 同款 react-dom 行今天就在树上而 ledger 里没有它的条目,main 却是绿的,所以那个拼写正则匹配不到。

实测,与预测逐条相符:

 ❯ scripts/__tests__/doc-version-claims.test.ts (6 tests | 2 failed)
   × records every version literal on the scanned surfaces
   × keeps the inventory honest - no entry may outlive the claim it excuses

AssertionError: KNOWN_CLAIMS names version claims that are no longer in the tree:
  - content/docs/guide/architecture-overview.md :: @objectstack/spec ^4.0.4
  - content/docs/guide/architecture-overview.md :: @objectstack/spec ^4.0.0
  - content/docs/guide/architecture.md :: TypeScript 5.0
  - content/docs/utilities/create-plugin.mdx :: @object-ui/core": "^0.3.0
  - content/docs/utilities/create-plugin.mdx :: @object-ui/components": "^0.3.0
  - content/docs/utilities/create-plugin.mdx :: react": "^18.0.0
  - packages/layout/README.md :: react` >= 18.0.0
  - packages/plugin-chatbot/README.md :: @ai-sdk/react` v3

AssertionError: These doc surfaces state a version and nothing in this repository can tell whether it is still true:
  - packages/layout/README.md:20  "react` ^18.0.0"
  - packages/plugin-chatbot/README.md:58  "@ai-sdk/react` v4"

 Tests  2 failed | 4 passed (6)

8 条、2 条,react-dom / react-router-dom 均未出现。这一步是本 PR 唯一能证明「ledger 缩短不是走形式」的证据:清偿前它确实以「条目所指的宣称已不在树上」变红,并把 8 条逐条点名。

步骤二 —— ledger 同步收缩

预测:6/6 绿。

$ pnpm exec vitest run scripts/__tests__/doc-version-claims.test.ts
   Test Files  1 passed (1) ;  Tests  6 passed (6)

反向验证:新增的那条自仓链接确实被门禁读到

create-plugin.mdx 新增了一条 blob/main/ 自仓链接,正落在 check-doc-links.mjs §2 的可判定形状里。预测:把路径改成不存在的,门禁必须变红并点名该行 —— 只有红了,修后的绿才是真覆盖(同 PR #3698 的做法)。

$ node scripts/check-doc-links.mjs        # 路径改坏后
- [self-repo-url] content/docs/utilities/create-plugin.mdx:150 -> .../packages/create-plugin/src/index.ts.NOPE
broken-path exit=1                        ← 与预测同向:红
restored   exit=0                         ← 还原后(文件 sha256 与改坏前逐字节相同)

措辞遵 #3656:先量后改,并检查有没有重新上膛

文件 判据 修前 修后
architecture-overview.md ^4.0.4 1 0
architecture-overview.md ^4.0.0 1 0
architecture-overview.md 重新上膛 rc.5|17.0.0 0 0
architecture.md TypeScript 5.0 1 0
architecture.md 重新上膛 ^6.0.3|TypeScript 6 0 0
create-plugin.mdx ^0.3.0 2 0
create-plugin.mdx "react": "^18.0.0" 1 0
create-plugin.mdx 重新上膛 workspace:*|^0.563|^19.0.0 0 0
layout/README.md >= 18.0.0 2 0
layout/README.md >= 6.0.0 1 0
plugin-chatbot/README.md ai-sdk/react` v3 1 0
plugin-chatbot/README.md ai-sdk/react` v4 0 1

最后一行是故意不为零的:#3710 那一族有锚,处置是对齐而不是删除,所以它必须留下一个字面量并进 ledger。三类处置方向不同,这张表如实反映,不强行凑成「全部归零」。

门禁

$ pnpm exec vitest run scripts/                     # 整个 scripts 面,确认没打断邻居
   Test Files  19 passed (19) ;  Tests  351 passed (351)

$ pnpm run type-check:scripts                       exit=0
$ pnpm exec eslint scripts/__tests__/doc-version-claims.test.ts   exit=0
$ node scripts/check-doc-links.mjs                  Links are valid across 7 scan roots. exit=0
$ node scripts/check-control-bytes.mjs              OK (scanned 3684 tracked text file(s); skipped 85 binary) exit=0
$ grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f]' (6 个改动文件)      0 命中

scripts/ 的 351 与 PR #3711 正文记的 345 不同,据实说明:那是它合并前在自己分支上量的数;本 PR 的 diff 只碰 19 个测试文件里的 1 个,该文件测试数前后都是 6,未增未减。

CI 预期(按 #3722 / #3523 step 2 落地后的真实机制写,不照抄旧口径):ci.yml / lint.ymlpull_request已经没有 trigger 级 paths-ignore 了 —— 那份排除表被移进 job 内的 "Decide whether this change needs a full run" 步骤(push 那份保留,因为没人评判推到 main 的提交)。所以本 PR 不会显示成 workflow skipping,而是照跑、由该步骤判定。排除表是 **/*.md / content/** / docs/** / apps/site/** / .changeset/**;我这 6 个文件里 5 个被排除(create-plugin.mdx 是靠 content/** 命中,不是靠 **/*.md —— 它是 .mdx),但 scripts/__tests__/doc-version-claims.test.ts 不在排除表内,于是 should_run=true,跑全量

结论方向与 PR #3688 / #3698 那两次的旧口径同(会真的跑),但机制不同:这条我在开 PR 后按 origin/main 的当前 workflow 重读过一遍才写,原稿把过滤描述成 trigger 级的,已按实际机制改写 —— 在一个专门清偿失真宣称的 PR 里留一句失真的机制描述,是本 PR 自己要防的那件事。

超出 KNOWN_CLAIMS 行的那部分改动,单独交代

派发文件面把该测试文件限定在「KNOWN_CLAIMS 行」。我另改了同文件的四处头注,理由是不改会让这个文件自己变成它要防的东西:

changeset:不加(写明判断)

围栏

越界发现(只记录、不顺手修)


🤖 Generated with Claude Code

https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt

Fixes #3708
Fixes #3709
Fixes #3710

按失真的三种性质分别处置,不套统一口径:

- 无锚宣称(#3708 三处)—— 照 #3645 / PR #3688 仓规删版本号指真相:
  architecture-overview 的三层架构 ASCII 图与散文不再写 spec 的版本区间
  (改指各包 package.json 的 dependencies),architecture.md 不再写
  TypeScript 的大版本下限。一律不改写成 rc.5 / ^6 —— 重写等于把同一台
  漂移机器重新上膛。

- 脚手架记录(#3709)—— create-plugin.mdx 逐字复制的那份 package.json
  三处版本错、字段也错(把 workspace 链接的 dependencies 记成 ^0.3.0 的
  peer),读者照做会装出一个装不上的包。改为描述真实生成形态并指向生成器
  模板本身,不再逐字复制版本区间。

- 有锚重述(#3710)—— 与自家清单对齐而不是删除:layout 的三条 peer 行
  收窄成清单逐字一致的形态(原 >= 拼写过度承诺,读者照装会拿到 peer 冲突),
  plugin-chatbot 的 @ai-sdk/react 主版本对齐清单。

ledger 相应收缩 27 → 21 条,stale 9 → 1(仅剩 plugin-report 那条,
其修法在清单侧,归 #3690)。棘轮两步实测:清前红并逐条点名 8 条陈旧条目
与 2 条未记录的新宣称,清后 6/6 绿。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt
@vercel

vercel Bot commented Aug 8, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectui Ignored Ignored Aug 8, 2026 9:08am

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation plugin tests labels Aug 8, 2026
@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Main entry (gzip) 28.1 KB 350 KB
Entry file index-BukWa__X.js
Status PASS

📦 Bundle Size Report

Package Size Gzipped
app-shell (index.js) 8.66KB 3.13KB
app-shell (runtime-config.js) 7.42KB 2.32KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 7.57KB 2.97KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 1.17KB 0.53KB
auth (AuthProvider.js) 22.10KB 4.37KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.13KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.64KB 2.21KB
auth (SocialSignInButtons.js) 9.60KB 3.89KB
auth (UserMenu.js) 3.40KB 1.22KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 35.76KB 9.11KB
auth (createAuthenticatedFetch.js) 4.37KB 1.69KB
auth (index.js) 2.35KB 1.07KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 4.91KB 0.87KB
auth (useIsWorkspaceAdmin.js) 1.61KB 0.85KB
collaboration (CommentThread.js) 26.07KB 7.56KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.65KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 480.72KB 105.64KB
core (index.js) 2.96KB 1.13KB
create-plugin (index.js) 9.08KB 2.92KB
data-objectstack (index.js) 137.51KB 35.11KB
fields (index.js) 230.90KB 56.84KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (currency.js) 1.22KB 0.64KB
i18n (i18n.js) 4.32KB 1.77KB
i18n (index.js) 2.65KB 1.06KB
i18n (pickLocalized.js) 1.70KB 0.83KB
i18n (provider.js) 9.48KB 3.27KB
i18n (useObjectLabel.js) 26.14KB 6.07KB
i18n (useSafeTranslation.js) 4.52KB 1.96KB
layout (index.js) 38.53KB 10.71KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.74KB
mobile (index.js) 1.50KB 0.62KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 2.53KB 0.85KB
mobile (useResponsive.js) 0.71KB 0.42KB
mobile (useResponsiveConfig.js) 1.36KB 0.63KB
mobile (useSpecGesture.js) 4.32KB 1.64KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 8.75KB 3.06KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 3.67KB 1.12KB
permissions (evaluator.js) 4.41KB 1.44KB
permissions (index.js) 0.91KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.52KB
permissions (usePermissions.js) 1.55KB 0.71KB
plugin-ai (index.js) 15.71KB 3.79KB
plugin-calendar (index.js) 44.98KB 12.37KB
plugin-charts (index.js) 61.04KB 17.31KB
plugin-chatbot (index.js) 180.09KB 42.72KB
plugin-dashboard (index.js) 115.50KB 29.96KB
plugin-designer (index.js) 210.51KB 42.51KB
plugin-detail (index.js) 232.79KB 57.42KB
plugin-editor (index.js) 2.46KB 1.10KB
plugin-form (index.js) 112.10KB 27.10KB
plugin-gantt (index.js) 162.55KB 39.57KB
plugin-grid (index.js) 186.61KB 49.34KB
plugin-kanban (index.js) 48.30KB 13.28KB
plugin-list (index.js) 105.12KB 25.48KB
plugin-map (index.js) 16.81KB 5.24KB
plugin-markdown (index.js) 13.72KB 4.69KB
plugin-report (index.js) 40.58KB 10.58KB
plugin-timeline (index.js) 25.76KB 7.33KB
plugin-tree (index.js) 8.50KB 2.88KB
plugin-view (index.js) 84.03KB 20.55KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.71KB 3.53KB
providers (index.js) 0.44KB 0.22KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.67KB 2.37KB
react (LazyPluginLoader.js) 3.77KB 1.33KB
react (SchemaRenderer.js) 19.28KB 6.38KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 1.02KB 0.55KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 4.09KB 1.74KB
sdui-parser (index.js) 4.47KB 2.03KB
sdui-parser (parse.js) 10.04KB 2.82KB
sdui-parser (types.js) 0.29KB 0.24KB
sdui-parser (validate.js) 4.69KB 1.48KB
types (ai.js) 0.20KB 0.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 0.99KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 0.20KB 0.18KB
types (crud.js) 0.20KB 0.18KB
types (data-display.js) 0.20KB 0.18KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.87KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-retry.js) 4.32KB 2.02KB
types (index.js) 2.71KB 1.34KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 2.59KB 1.31KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (spec-report.js) 5.05KB 1.93KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 0.20KB 0.18KB
types (ui-action.js) 3.40KB 1.71KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

@yinlianghui
yinlianghui marked this pull request as ready for review August 8, 2026 10:06
@yinlianghui
yinlianghui added this pull request to the merge queue Aug 8, 2026
Merged via the queue into main with commit fbf7d6d Aug 8, 2026
18 checks passed
@yinlianghui
yinlianghui deleted the claude/issue-3708-version-claims-payoff branch August 8, 2026 10:07
yinlianghui pushed a commit that referenced this pull request Aug 8, 2026
冲突只有一处:scripts/__tests__/doc-version-claims.test.ts。PR #3726(fbf7d6d)
在同一文件上清偿了 #3708/#3709/#3710 的 8 条失真,KNOWN_CLAIMS 27 → 21、stale
9 → 1(刻意留下的那条就是 plugin-report,修法在清单侧,归本单)。

三段冲突按并集语义在 #3726 之后的新形态上重写,而不是把本分支的旧文本贴回去:

- 条目区(第三段):两侧各自删掉了自己那条 stale——main 删的是 layout(#3710
  已把 README 的 `>= 18.0.0` 收窄成清单拼写),本分支删的是 plugin-report。
  删除的并集就是整块去掉。layout 那条必须删:它指的宣称已不在树里,留着会让
  「no entry may outlive the claim it excuses」这条棘轮红。plugin-report 那条也
  必须删:本分支新增的 restatement 单行与它 keyOf() 完全相同,两条并存会撞上
  「KNOWN_CLAIMS has duplicate entries」。
- 两段散文:改以 main 的事实清单为底(谁清偿了哪几条),把计数按合并后文件的
  真实行重算。本分支原来写的「NINE → eight」在 #3726 之后本身已经过期。

计数逐行数出来,不靠推断:合并后 21 条(与 main ±0),restatement 12 → 13,
stale 1 → 0。逐行比对 main 与解析结果的行集合,唯一差异是
`packages/plugin-report/README.md :: stale` → `:: restatement`,没有任何文件被
整条丢掉——即 #3726 的 9 条清偿全部完好过桥。另外同步了两处非冲突但被本次翻转
写旧的注释:restatement 类「12 of 21」→「13 of 21」,PEER_18_19 头注的「10 个
README / 第十一个 plugin-report 仍是 stale」→ 11 个,并说明它是从相反方向
(改清单而非改散文)加入的。

清单侧重新核对(一行读):packages/plugin-report/package.json 的
peerDependencies 现为 react / react-dom 皆 `^18.0.0 || ^19.0.0`,README:24-25
逐字相同,故 restatement 的 why 文本成立。package.json 与 changeset 均干净合并。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment