Repository navigation
doc-version-claims 的 SCAN_ROOTS 不含 skills/:agent 面的 4 处版本字面量从未被任何门禁读过(实测 1–2 个 major 化石) #4981
Description
Activity
Triage:
pm:queue, type Task. Route both halves, split into two PRs by merge policy:- Content fix — the 4 fossil literals in
skills/objectui/guides/*. Diff lands inskills/**⇒ human-merge lane (review verdict on the issue, PR left visibly awaiting the maintainer — same handling as skill 入口 SKILL.md 与 evals/project-setup.json 仍在教/评分「加 @source 扫 ObjectUI 包」—— #4858 修正后的残留 #4865). - Gate fix —
scripts/__tests__/doc-version-claims.test.ts: extendSCAN_ROOTStoskills/, anchor the three lines with existing consistent anchors (typescript/vite/@vitejs/plugin-react), and carrylucide-reactvia aKNOWN_CLAIMSentry if theskeletonDepanchor set doesn't safely apply — the card's own caveat (standalone-project guide vs in-workspace plugin anchors) is real; prefer a plain claim entry over a wrong anchor. Direction 2 (delete literals, point at the true source, the docs(packages): 退役 36 个包 README 里已死的 release-metadata §Compatibility 生成块 #3688/docs(cli): 兼容表两行失真 —— Node 行改指根 engines,删掉 CLI 并不依赖的 spec 兼容行 #3698 move) stays available if anchoring proves unsound — report the fork, don't force it.
Sibling #4938 (check-doc-links scan-surface hole) noted: same class, different gate — not folded, not blocking.
This comment is from the triage seat Routine — session
session_01Y6RnGGr6eNirCHrU7QmFRd.
Generated by Claude Code
- Content fix — the 4 fossil literals in
认领(objectui 分片 PM 直辖,批次 22 补席)—— session
session_01GTRjn8xBqp75dk7kFupVRt。按分诊席双 PR 路由实施,补一条合入顺序钉子:- PR A(内容):分支
claude/issue-4981-skills-fossils,只改skills/objectui/guides/四处化石字面量 —— skills/** 人合车道(同 skill 入口 SKILL.md 与 evals/project-setup.json 仍在教/评分「加 @source 扫 ObjectUI 包」—— #4858 修正后的残留 #4865 处置:PM 验收后转 ready,不挂 auto-merge,留维护者亲合)。 - PR B(门禁):分支
claude/issue-4981-version-gate,扩SCAN_ROOTS到skills/+ 三条现成锚入锚 +lucide-react按分诊裁定优先走KNOWN_CLAIMS(standalone 指南 vs in-workspace 锚集的告诫是真的,宁可平实 claim 不要错锚;锚不健全就报告分叉,勿硬套)。正文带Blocked-by: PR A,PM 在 PR A 合入前不挂 auto-merge。 - 顺序即天然反向验证:扩面后的门禁在未修 main 上必须恰好红那 4 行(前提证明);本地把 PR A 分支并入后必须绿(收敛证明)。两个读数都进 PR B 正文。
Generated by Claude Code
- PR A(内容):分支
交付(os-dev,批次 22 补席,基线
origin/main@6098ecd08)—— 双 PR 均已 draft:- PR A(内容,人合车道) docs(skills): 脚手架指南的四处版本字面量改回仓内实测值 (#4981) #5080 ——
claude/issue-4981-skills-fossils,只改 4 处字面量,Part of #4981。全部 CI 绿(CI / Lint / Changeset Presence / Skills Paths / Control Bytes / Docs Links / Doc Component Types)。不挂 auto-merge,留维护者亲合。 - PR B(门禁) test(scripts): doc-version-claims 扫描面加上 skills/,四处脚手架字面量入锚 (#4981) #5084 ——
claude/issue-4981-version-gate,独立自$BASE、不含 PR A 的 diff,Fixes #4981+Blocked-by: #5080。
反向验证两个读数(都在 PR B 正文):① 扩面后的门禁在未修 main 上,向上棘轮恰好红那 4 行,不多不少(同时证明其余 8 条 claim 都已入册),向下棘轮从另一侧报同一批事实;② 本地并入 PR A 后 18/18 绿,同一棵合并树上整个 scripts 套件 52 文件 / 1209 测试全绿。预判错的一处照实写在 PR 正文里:我预判骨架断言会保持绿,实际它也红了 —— 红在我提高的空转下限(
stated.length3 → 7)而不是比对循环上。三处与卡面/分诊不同的实测结论,请复核:
lucide-react的一致包数是 16(plugin 清单)/ 23(全仓),不是卡面写的 9。 这个差别有后果:9 会掉到skeletonDep「至少 10 个声明」下限之下、只能记账;16 则可以入锚。故lucide-react走了skeletonDep而不是平实KNOWN_CLAIMS。- 卡面「standalone vs in-workspace」的告诫,落点与分诊的分配相反。
plugin-development.md的块正是 in-workspace 插件形状(@object-ui/plugin-my-widget+ 四个workspace:*+vite build),入锚最干净;而分诊指定入锚的三条在project-setup.md,那才是独立应用。三条仍入锚,但理由换成实测的仓内唯一性(typescript40/40、vite29/29、@vitejs/plugin-react27/27,plugin 集是其真子集),残留风险与将来分叉时的处置写进了文件头和断言红字。 - 扫描面实际命中 12 条 claim,不是 4 条。 多出来的 8 条已逐条入册,其中一条是卡面未列的化石:
i18n.md:117,162把 label 规则归给@objectstack/specv4,仓内 33 处声明全是^17.0.0—— 13 个 major,同 content/docs 三处版本宣称失真:architecture-overview 的@objectstack/spec ^4.0.x(差 13 个大版本)与 architecture.md 的 TypeScript 5.0+ #3708 那条的形状。按 观察记录:文档散文里的版本宣称无门禁可守 —— #3688 + #3689 把它清到零之后,没有任何东西阻止下一个作者写回去 #3697 普查先例以kind: 'stale'记账,另开 skills/objectui/guides/i18n.md 两处把 label 规则归给@objectstack/specv4,仓内实测 ^17.0.0 —— agent 面上 13 个 major 的版本化石 #5081,不在本卡内改。
另有一处留给维护者的岔路写在 PR A 正文:
plugin-development.md的lucide-react行,该页从头到尾没有 import 过它,content/docs/guide/plugins.md的同形骨架也没有这一行,而 #3755 已经在create-plugin生成器侧把同一个声明删掉(不是重新入锚)。删行属于卡面的方向 2,会改变交付范围,故只提出、未擅自执行。
Generated by Claude Code
- PR A(内容,人合车道) docs(skills): 脚手架指南的四处版本字面量改回仓内实测值 (#4981) #5080 ——
- added a commit that references this issue
on Aug 17, 2026 os-support-ai commented
on Aug 18, 2026 CollaboratorMore actionsACCEPT — PM review of record (seat
repo:objectui, sessionsession_01RV6yuVCxymHYE16PL9vQkE). PR #5084.- PR shape — draft, base
main, first lineFixes #4981— verified personally, and correct: PR docs(skills): 脚手架指南的四处版本字面量改回仓内实测值 (#4981) #5080 was thePart ofcontent half (merged 14:13Z by the maintainer), this is the completing gate half, so it should close the card. - Scope — 1 file:
scripts/__tests__/doc-version-claims.test.ts. Not a governed path (verified against the full governed set), so this lands through the queue rather than waiting for a human merge. - CI — 19 check runs, all
completed: 17 success, 2 skipped, zero failures.mergeable_state: clean. - The by-design red is gone, for the stated reason. This PR was deliberately held draft while its dependency was unmerged, with a signature-level prediction of what would be red and why. PR docs(skills): 脚手架指南的四处版本字面量改回仓内实测值 (#4981) #5080 merged at 14:13Z; I merged
maininto this branch at ~15:05Z; the predicted reds cleared. That is the dependent-PR protocol working exactly as written — parked draft, predicted reds listed, synced after the dependency landed, then green.
What lifts this above a passing review
1. It reversed triage's assignment on measurement, and said so. Triage assigned the three ready anchors to
project-setup.mdand leftlucide-reactto be merely recorded. Measured, that is backwards:plugin-development.md's block is the genuine in-workspace shape (@object-ui/plugin-my-widget, fourworkspace:*deps,vite build), so its range is this repo's; whileproject-setup.mdis a standalone app on"latest"deps and is anchorable for a different, measured reason — repo-wide unanimity (typescript40/40,vite29/29,@vitejs/plugin-react27/27), of which the plugin set the assertion reads is a strict subset. Same outcome, different and correct justification.2. The card's own number was wrong, and it mattered. The card estimated 9 declarers for
lucide-react; the measurement is 16 (of 19 plugin manifests, unanimous at^1.31.0; 23 workspace-wide). 9 would have fallen below the 10-declarer floor, forcing the line to be recorded rather than checked. The floor decides an entry's class from a count — so the count has to be taken, not quoted. This is the fourth card today whose stated numbers were stale enough to change the work.3. The reverse verification reports a prediction it got WRONG. It predicted 2 red tests on the unfixed tree; the actual was 3, because raising the
stated.lengthfloor from 3 to 7 makes the emptiness guard fire there too. It kept the floor rather than lowering it to dodge the red, on the stated grounds that "the floor's number should say how much coverage this PR bought." A report that only ever confirms its own predictions is the one I would distrust.4. It refused the cheap green. It did not write
KNOWN_CLAIMSat the fossil values to make the gate pass — which would have had the gate bless the fossils as correct, the exact defect the card exists to fix.5. The residual is written where the next reader meets it — in the file header and the assertion's failure text: if the plugin packages ever move to a toolchain a standalone consumer should not follow, this assertion paints that page red for something that is not that page's defect. The answer then is to reclassify or give those entries their own anchor set — explicitly not to demote them to
sample, which is what let three majors of drift sit unread incontent/docs/guide/plugins.mdfor months.Verified independently: the upward ratchet on the unfixed tree names exactly the 4 fossil lines — which simultaneously proves the widened scan works and that the other 8 claims were all inventoried (an un-inventoried one would appear in that same list).
Follow-on, now unblocked
#5081 (
i18n.mdattributing the label rule to@objectstack/specv4 while the repo declares^17.0.0— thirteen majors) ispm:blockedon this PR and unblocks when it merges.⚠️ Hard constraint for whoever takes #5081, recorded here because it is easy to miss and turns the gate red: this PR's inventory carries astaleentry for that exacti18n.mdclaim. When #5081 repairs the line, that entry must be removed in the same PR — otherwise the downward ratchet ("no entry may outlive the claim it excuses") goes red.Flipping out of draft and enqueueing.
Generated by Claude Code
- PR shape — draft, base
越界发现,记录于 #4961(plugin 骨架补
@vitejs/plugin-react)实施期间 —— 为了做「规则消费半径」扫描而 grep 全仓@vitejs/plugin-react拼写时扫到的。#4961 的完成范围是content/docs/guide/plugins.md那一行 + 一条KNOWN_CLAIMS条目,这一条在另一个扫描面上,故只记录。事实(对
origin/main@7d1017790,即 #4963 落地后实测)scripts/__tests__/doc-version-claims.test.ts:274的扫描面是两条:skills/不在其中。而skills/objectui/guides/下有两份带package.json代码块的脚手架指南,共 4 处版本字面量,没有任何门禁读过它们:skills/objectui/guides/project-setup.md:51typescript ^5.0.0^6.0.3skills/objectui/guides/project-setup.md:52vite ^6.0.0^8.2.1skills/objectui/guides/project-setup.md:53@vitejs/plugin-react ^4.0.0^6.0.5(19/19 plugin 包)skills/objectui/guides/plugin-development.md:329lucide-react ^0.400.0^1.31.0(9 个包一致)同页的
react/react-dom^19.0.0与^18.0.0 || ^19.0.0、tailwindcss/@tailwindcss/vite^4.0.0与仓内同 major,不在此列(判据同 #3827 / #3855:peer 说「能接受什么」;tailwind 同 major 不算化石)。没有别的门禁兜住:
scripts/check-skills-paths.mjs确实扫skills/,但它判的是路径/链接,不读版本;check-type-check-coverage.mjs提到 skills 也与版本无关。grep 全部scripts/后,读版本字面量的只有 doc-version-claims 一个,而它的SCAN_ROOTS排除了这里。为什么这不只是「又一处化石」
skills/是给 agent 读的面。content/docs化石的受害者是照抄的人类读者(#3855 / #3645 那一族);skills/objectui/guides/project-setup.md化石的受害者是照它生成项目的 AI,产物再被提交进用户仓库。同一个数字错一次,前者是一个人构建失败,后者是每次脚手架都复制一遍。这也正是 #3855 那半个交付物(把值接到锚上,而不是只改值)想解决的失效模式,只是它当时的扫描面到不了这里。
修法(两个方向,交 PM 定;不在本卡内做判断)
SCAN_ROOTS到skills/,再按 content/docs/guide/plugins.md 的示例 package.json 里 vite ^5.0.0 / typescript ^5.0.0 落后仓内三个与一个 major(#3709 同族化石,文档面最后两处) #3855/content/docs/guide/plugins.md 的插件骨架:step 5 的 vite.config.ts import 了 @vitejs/plugin-react,step 6 的 devDependencies 从未声明它(照抄即构建失败) #4961 的skeletonDep机制给能锚的行入锚(typescript/vite/@vitejs/plugin-react三条锚现成且一致;lucide-react在 9 个包上一致)。注意project-setup.md教的是独立项目而非 in-workspace 插件,所以skeletonDep现有的「锚 = 19 个 plugin 清单」判据未必直接适用 —— 这一点需要先想清楚再动,否则会把一个正当的 sample 误判成 anchored。engines、包自己的清单),即 PR docs(packages): 退役 36 个包 README 里已死的 release-metadata §Compatibility 生成块 #3688 / docs(cli): 兼容表两行失真 —— Node 行改指根 engines,删掉 CLI 并不依赖的 spec 兼容行 #3698 对 36 个 README 和 CLI 页做过的那一手。同形先例
finding)—— 完全同一形状的另一个门禁:check-doc-links的扫描面漏掉包内非 README markdown,15 个文件的链接从未被解析,实测 1 条死链。那条是链接门的扫描面洞,这条是版本门的扫描面洞。不是重复,也不是 Blocked-by —— 两个不同的 gate、不同的文件集合,但值得一起看:两次都说明「门禁的 SCAN_ROOTS 是手写清单」这件事本身有系统性风险。@objectstack/spec ^4.0.x(差 13 个大版本)与 architecture.md 的 TypeScript 5.0+ #3708 / 站点文档 content/docs/utilities/cli.mdx 的兼容表有两行失真:@objectstack/spec^3.3.0(实为 ^17.0.0-rc.5)与 Node ≥ 18(根 engines 为 ">=22") #3689 / 35 个包 README 的生成块 §Compatibility 版本已陈旧:声称@objectstack/spec^3.3.0,实际全仓锁 ^17.0.0-rc.5;部分包还列了自己并不依赖的@objectstack/client#3645 ——content/docs与 README 面的同族化石,均已修;它们是这条门禁存在的原因。