Skip to content

docs(guide): plugin skeleton 的 vite/typescript 对齐仓内实测,并把该拼写纳入版本声称门 (#3855) - #4963

Merged
yinlianghui merged 4 commits into
mainfrom
claude/issue-3855-plugin-guide-fossils
Aug 17, 2026
Merged

docs(guide): plugin skeleton 的 vite/typescript 对齐仓内实测,并把该拼写纳入版本声称门 (#3855)#4963
yinlianghui merged 4 commits into
mainfrom
claude/issue-3855-plugin-guide-fossils

Conversation

@yinlianghui

@yinlianghui yinlianghui commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator

Fixes #3855

按晋级评论的方向 1:两个版本值对齐仓内实测,并且回答了「#3711 的版本声称门为何漏掉它们」—— 答案让方向 1 成为唯一自洽的选择,细节见下。

前提验证:成立,但卡上的一个测量值已经漂了

三样都对着 origin/main @ 1b21b1aaa 重新读过,没有沿用卡上的数字:

卡上写的 本次实测
content/docs/guide/plugins.md 两行现状 :401-402typescript ^5.0.0 / vite ^5.0.0 ✅ 一字不差,行号也仍是 401/402
仓内 typescript ^6.0.3(38 处) ^6.0.3,40 处清单一致
仓内 vite ^8.2.0(28 处) ^8.2.1,29 处清单一致

卡上的 vite 锚点自己已经化石化了 —— 立卡到实施的九天里仓内从 ^8.2.0 走到 ^8.2.1。这不是记账瑕疵,它是这一单要修的那个机制在派发链条上又演示了一次:任何手写下来的版本值都会漂,包括用来修化石的那个值。所以只改值必然是暂时的,门那一半才是交付物。

packages/plugin-* 收窄(骨架正是一个 plugin 包)则更整齐:19 个 plugin 清单全部 vite ^8.2.1,其中 16 个声明 typescript 且全部 ^6.0.3。这就是新断言用的锚。

门为何绿:它没有漏掉这两行 —— 是归类错了

这是本单更有价值的那一半,也把「门能不能覆盖该拼写」问题直接反转了。

scripts/__tests__/doc-version-claims.test.ts 里两行都被扫到了(TypeScript / ViteTOOLCHAIN 词,名与值之间的 ": "SEP 六字符预算里的三个),都进了 KNOWN_CLAIMS —— 归类为 kind: 'sample',一个按构造只记账、不断言的类。理由原文写的是:

the plugin author picks their own bundler version after copying it

佐证不靠推断:基线 14 个测试全绿,其中下行棘轮那条(「条目所指的字面量必须仍在树上」)绿,就是「那两条 ^5.0.0 确实被匹配到了」的机械证据 —— 没匹配上的话该条目会被报为孤儿。

这句理由对独立插件成立,对该页上的那一块不成立,而这正是值得点名而非默默改掉的地方。那份骨架叫 @object-ui/plugin-myfeature,三个 @object-ui 依赖全是 workspace:*,build 脚本是 vite build && tsc --emitDeclarationOnly —— 这样拼出来的清单只在一个地方解析得开:本 workspace。于是它命名的工具链不是读者的选择,是本仓的;而本仓对此的声明是一致的。

所以门绿的根因与「棘轮看不见被拓宽的区间」同类:不是扫描有盲区,而是一个只记账不检查的类,装了一条本来就有锚的行。这也意味着方向 2(去 pin 化)在这里是次优解 —— 该行不是「无锚所以不该维护」,它有一个 19/19 一致的锚,只是没人把锚接上。

改法

  1. content/docs/guide/plugins.md:401-402typescript ^6.0.3 / vite ^8.2.1
  2. 两条 KNOWN_CLAIMS 条目 sampleanchored,新增字段 skeletonDep(与 notAPeerRestatement 的封闭纪律对称,只是方向相反:那个字段是退出检查并写明理由,这个是加入检查并指明锚的依赖名)。
  3. 新增 describe('the plugin-skeleton assertion'):从骨架行读出区间,与 19 个 plugin 清单声明的区间比对。四条失败支路各自点名不同的事实(行不成立为依赖声明 / 该依赖无锚 / 锚分裂 / 区间不符),外加三条反空绿下限。
  4. 同块的 peerDependencies react 区间照旧 sample,并把理由改写清楚:peer 说的是拷走后的插件向宿主接受什么,由它的作者拥有;devDependency 说的是在这里装什么来构建packages/cli 的 createTempAppWithRouting 生成的 app import 了未声明的 lucide-react,且其工具链区间落后仓内一到三个 major #3827 的锚定表当初把 peer 排除在锚源之外,判据同一条。
  5. sample 的类注释加了一句警示,指回本单:该类曾装着三个 major 的真实漂移,原因是「这是读者拷走的骨架」被整块接受了,而那一块里只有一部分是读者的。

后两个 commit 是自查产物:skeletonDep 的收窄改用 flatMap 而非 cast;一致性前提改为从清单派生 dep 列表(硬编码会让后加的第三个 skeletonDep —— 例如 #4961@vitejs/plugin-react —— 逃出这条前提),并把 #3855 实测的两个名字保留为对该派生的下限。

逆向验证:四个变异,方向都先预测后跑;其中一个的方向与直觉预设不一致

变异 A —— 把两个值改回 ^5.0.0(任务点名的那一个)

预测:红,但不是经由新断言的比对支路。 清单键内嵌版本字面量,所以把文档改回旧值会让两条条目变成 absent,而比对支路对 absent 是故意跳过的(本文件的「一个缺陷一个报告者」纪律 —— 棘轮下行方向已经在报它了)。因此预期红在:棘轮两个方向 + skeleton 断言的反空绿下限

实测,逐条对上:

× records every version literal on the scanned surfaces
× keeps the inventory honest - no entry may outlive the claim it excuses
× pins the skeleton toolchain to the range the in-repo plugin packages declare
  AssertionError: the skeleton assertion compared implausibly few lines ...
  expected 0 to be greater than or equal to 2
  Tests  3 failed | 15 passed (18)

据实写明而不套模板:这个变异没有证明比对支路有效,它证明的是值被棘轮钉住了 + 新断言不会空绿。比对支路要靠变异 C 才动得到。

变异 B —— 只 bump 一个 plugin 清单的 vite(半途而废的 bump)

预测:红,经由锚分裂支路 + 一致性测试。

× pins the skeleton toolchain ...
  - content/docs/guide/plugins.md :: the in-repo plugin manifests do not agree on vite,
    so there is no single range for the docs to state: "^8.2.1" in 18 (...); "^9.0.0" in 1
    (plugin-charts) - finish the bump across the plugin packages first, then update the page
× resolves the anchor unanimously ...
  expected [ '^8.2.1', '^9.0.0' ] to have a length of 1 but got 2
  Tests  2 failed | 16 passed (18)

变异 C —— bump 全部 19 个 plugin 清单,文档留在原地

这才是 #3855 存在的那个场景(「下次仓升级同一行再化石化」),也是唯一走到比对支路的变异。预测:恰好一条红,点名该页行号。

× pins the skeleton toolchain ...
  - content/docs/guide/plugins.md:402  vite: the page teaches "^8.2.1",
    every in-repo plugin package declares "^9.0.0"
  Tests  1 failed | 17 passed (18)

一致性测试在 C 里保持绿是对的:bump 做完了就是一致的,只有文档旧 —— 两条断言判的是两件不同的事。(C 在第 2 个 commit 的收窄重构之后原样重跑过一次,红法一致。)

变异 D —— 抽掉 vite 条目的 skeletonDep(证第 3 个 commit 的派生下限真的咬)

预测:红两条 —— 新下限点名 vite,加上 skeletonChecks.length >= 2 那条计数下限。

× pins the skeleton toolchain ...
× resolves the anchor unanimously ...
  AssertionError: vite lost its skeletonDep entry - either the plugin guide stopped naming
  it or the inventory did, and this premise is no longer being checked for it:
  expected [ 'typescript' ] to include 'vite'
  Tests  2 failed | 16 passed (18)

四个变异全部还原后复跑 18 passed,git status 干净。

测试

$ pnpm exec vitest run scripts/__tests__/doc-version-claims.test.ts
   Test Files  1 passed (1) ;  Tests  18 passed (18)      # 基线 14,新增 4

$ pnpm exec vitest run scripts/ --maxWorkers=2             # 整个 scripts 面,确认没打断邻居
   Test Files  50 passed (50) ;  Tests  1171 passed (1171)

$ pnpm run type-check:scripts        exit=0
$ pnpm exec eslint scripts/__tests__/doc-version-claims.test.ts        exit=0
$ node scripts/check-control-bytes.mjs
   ✅ OK (scanned 4433 tracked text file(s); skipped 85 binary)
$ grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f]' 本 PR 三个文件        0 命中
$ node scripts/check-doc-links.mjs           Links are valid across 13 scan roots.
$ node scripts/check-doc-component-types.mjs ✅ Every documented component type is registered.
$ node scripts/check-changeset-no-major.mjs  ✅ No changeset declares a `major` bump.

消费半径扫过:除本门禁外,读 guide/plugins.md 的只有 check-doc-links.mjs 及其测试,而后者用的是自建内存 fixture('guide/plugins.md': '[Charts](...)'),不碰版本字面量。没有别的包的 fixture 拼写这两个值。

changeset

空 frontmatter + 正文,照 docs/test-only 先例(guide-layout-sidebar-nav-4840.mdguide-layout-app-shell-4827.mddoc-component-type-ratchet-4823.md)。不动任何发版包的 src/;check-changeset-presence.mjsno changeset is owed,这一条是显式声明「不发版」而非搭车。

⛔ 未触碰 content/docs/releases/**

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


🤖 Generated with Claude Code

https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt

…3855)

`content/docs/guide/plugins.md` 的插件 `package.json` 示例教 `typescript ^5.0.0` /
`vite ^5.0.0`,而仓内 19 个 plugin 包一致声明 `^6.0.3` / `^8.2.1` —— 差一个与三个 major。

耐久半边是回答 #3711 的版本声称门为何绿:它没有漏掉这两行。两行都被扫到、都进了
`KNOWN_CLAIMS`,但归类为 `sample` —— 一个只记账不断言的类,理由写的是「插件作者拷走后自己
挑打包器版本」。该理由对独立插件成立,对 `workspace:*` 的清单不成立。两条现改为 `anchored`
并带新字段 `skeletonDep`,新断言从示例行读出区间与仓内 plugin 清单比对,下次工具链 bump
会点名该页变红,而不是再化石化一次。同一块的 `peerDependencies` react 区间照旧 `sample`。

Co-authored-by: Claude <noreply@anthropic.com>
claude added 2 commits August 17, 2026 08:15
filter-then-map 编译等价,但读起来像是在假设不变式而不是建立它 —— 与本文件其余部分
的取向相反。顺带写明 `linesOf` 的缓存原为 README 写的、这里是首个非 README 复用者。

Co-authored-by: Claude <noreply@anthropic.com>
硬编码 ['vite','typescript'] 会让后加的第三个 skeletonDep(如 #4961 的
@vitejs/plugin-react)逃出这条前提,只剩主断言守。改为从 skeletonChecks 派生,
并把 #3855 实测的两个名字保留为对该派生的下限 —— 否则派生自己可能静默变成空循环。

Co-authored-by: Claude <noreply@anthropic.com>

Copy link
Copy Markdown
Collaborator Author

PM 记录:CI 两红是基分支断裂,非本 PR(会话 session_01GTRjn8xBqp75dk7kFupVRt)

Test shard 1/4 与 3/4 的失败是 app-generator.test.ts 的 lucide-react 区间钉 —— dependabot c1454a2d9(#4959)升了 workspace 而 CLI 生成器模板未跟,任何 PR 的 merge-ref 都红,与本 PR 的 diff(plugins.md + doc-version-claims)零交集。热修卡 #4968 已派;落地后本 PR update-branch 重跑,届时再走三件套。本 PR 实物核验与本地验证均已通过,验收不受影响,只等基线恢复。


Generated by Claude Code

Copy link
Copy Markdown
Collaborator Author

PM 验收:ACCEPT(#3855,批次 19,PM 会话 session_01GTRjn8xBqp75dk7kFupVRt)

门答案(本卡核心):#3711没有漏扫 —— 是归类错:两行早在 KNOWN_CLAIMS 里,被装进只记账不断言的 sample 类;原理由「读者自选打包器版本」对独立插件成立、对本仓 workspace 骨架不成立(workspace:* 依赖 + 只在本仓解析得开)。机械佐证齐(下行棘轮绿 = 条目非孤儿)。修法 = 值跟实测现值(卡面锚自己九天内也漂了一步 ^8.2.0→^8.2.1,即「只改值必然暂时」的直接证据)+ sample→anchored 重归类 + 派生式骨架断言(4 失败支路 + 3 防空下限);peer react 留 sample 的判据与 #3827 一致(peer 是作者拥有的宿主接受面)。

反向验证:四变异全预判先行 —— A 如实报「不经由新比对支路」(absent 跳过,一缺陷一报告者);C 正是「下次升级再化石化」场景,恰一条红精确点名行号;B/D 逐字命中。

实物核验(已过):3 文件 +392/−11;标识 0;releases 0。CI(update-branch 后亲读终态):19 项全 completed,17 success + 2 skipped,零失败 —— 此前两 shard 红为 GA 断裂基线问题(已由 PR4978 解阻),与本 PR 零交集,已在线程记录。

附带产出:#4961(骨架 import 未声明依赖,已入队)+ 两处预核「不用动」防机械补齐。

→ undraft + auto-merge (SQUASH)。


Generated by Claude Code

@yinlianghui
yinlianghui marked this pull request as ready for review August 17, 2026 11:58
@yinlianghui
yinlianghui added this pull request to the merge queue Aug 17, 2026
Merged via the queue into main with commit 7d10177 Aug 17, 2026
20 checks passed
@yinlianghui
yinlianghui deleted the claude/issue-3855-plugin-guide-fossils branch August 17, 2026 11:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

2 participants