feat(scripts): check-doc-links 扫描面第三扩 CONTRIBUTING/ROADMAP/docs (#3572) - #3589
Merged
Conversation
`SCAN_ROOTS` 追加三行,全部沿用既有的 `disk` 规则:
{ path: 'CONTRIBUTING.md', rule: 'disk' },
{ path: 'ROADMAP.md', rule: 'disk' },
{ path: 'docs', rule: 'disk' },
这三面正是 #3536 头注释里「Still not bought」点名的下一批,当时标价
「one SCAN_ROOTS row each — plus fixing what that turns red」。红账已由
#3545 / PR #3571 单独付清(3 条死链),所以本次是纯三行:实测 70 条链接、
52 条可判定、落地当日零死链——扩展该有的形状,对照 #3479(16 个死目标)
与 #3490(18 个)那种「门禁与欠账同时到货」。
`docs/**` 是三者中从未被量过的一面:Lychee 的扫描范围虽然列了它,但那个
工作流只有 schedule + workflow_dispatch,`pull_request`/`push` 按 #3213
ruling B 被刻意注释掉,拦不住任何 PR;它的 49 条链接里有 47 条此前从未被
任何能让构建失败的东西解析过。
不新增规则类、不新增 reason、不新增 hint。
头注释如实写下已知边界:`stripCode()` 在扫描前抹掉围栏与行内代码,所以
**围栏内的链接对本门禁不可见,死活都不可见**。这不是假想——CONTRIBUTING.md
的 25 条链接里 10 条在围栏内,门禁真正判定的只有 1 条。那 10 条正是 #3570
的实例类(演示 docs 链接写法的围栏,其"正确示例"路由自己是死的);修那段
文字是 #3570 的事,指出没有门禁够得着它是本注释的事。
测试(+8):
- 两个既有 pin 测试用 toEqual 硬钉 SCAN_ROOTS,新行会让它们**响亮地红**
——不是自动覆盖。逐根的 count 断言那一半才是不会自我扩展的:补齐三行
各自的下限,否则某行打错字导致整棵树扫空时上面的测试仍会绿。
- 新 describe 覆盖三面的 reject/accept,含 docs/ 递归遍历、离开 docs/ 的
链接照收(无 collection 可逃)、无扩展名拼写与绝对 `/...` 照拒。
- 围栏边界作为**决定**钉住,而非留成日后被误读为覆盖的静默缺口。该测试
与 docs/ vs content/docs 对照测试都带一条 control 链接:否则删掉扫描行
它们会因「什么都没扫」而空绿——本文件存在的意义就是防这个。
ci-cd-pipeline.md 三处被证伪,做最小事实订正:扫描面清单、disk 规则的
适用文件、双检查器对照表那一行;并把「若改用 docs 规则会拒掉 61 条」按新
扫描面重算为 111。另加一段说明围栏边界,以免读者把该表读成全覆盖。
Fixes #3572
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
yinlianghui
marked this pull request as ready for review
August 7, 2026 14:57
This was referenced Aug 7, 2026
This was referenced Aug 7, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #3572
SCAN_ROOTS追加三行,全部沿用既有的disk规则,不新增规则类 / reason / hint:这三面正是 #3536 头注释里 "Still not bought" 点名的下一批,当时标价「one SCAN_ROOTS row each — plus fixing what that turns red」。红账已由 #3545 / PR #3571 单独付清(3 条死链),所以本次是纯三行。
实测(与 #3571 的预告逐项吻合)
先预告再跑,四项全中:
CONTRIBUTING.mdROADMAP.mddocs/**node scripts/check-doc-links.mjs→Links are valid across 6 scan roots.,exit 0。零清理清单——对照 #3479(16 个死目标)、#3490(18 个)那种「门禁与欠账同时到货」。docs/**是三者中从未被量过的一面。Lychee 的扫描范围虽然列了它,但那个工作流只有schedule+workflow_dispatch——pull_request/push按 #3213 ruling B 被刻意注释掉,拦不住任何 PR。它的 49 条链接里 47 条此前从未被任何能让构建失败的东西解析过。已知边界:围栏内的链接看不见(如实写进头注释)
stripCode()在扫描前抹掉围栏与行内代码(这正是相对链接检查得以安全开启的前提,#3536 已论证),所以围栏内的链接对本门禁不可见,死活都不可见。不是假想:
CONTRIBUTING.md共 25 条链接,10 条在围栏内,门禁真正判定的只有 1 条(其余 14 条是#anchor与外链)。那 10 条正是 #3570 的实例类——一段演示 docs 链接写法的围栏,其"正确示例"路由自己是死的。修那段文字是 #3570 的事;指出没有门禁够得着它是本注释的事。头注释同时写明为什么不该靠放宽stripCode()来补:围栏内合法地存在不是链接的[…](…),区分「示意路由」与「可执行路由」是另一个门禁的活。与 #3570 的并行协调
本 PR 未触碰
CONTRIBUTING.md(#3570 正在改其内容)。真仓跑对该文件报出 0 条——与预期一致:它要修的三条死"示例"路由都在围栏内,stripCode抹掉了。围栏边界测试用的是 fixture 而非真实文件内容,不与 #3570 的编辑抢同一段文本。测试(+8,57 → 65)
pin 测试是否自动覆盖新行?一半是,一半不是 —— 这正是 #3542 自述里的 anti-vacuous-green 教训:
toEqual硬钉SCAN_ROOTS/Object.keys,新行让它们响亮地红,已按新表扩写;CONTRIBUTING.md/ROADMAP.md为 1,docs为 ≥ 15)。新 describe 覆盖三面的 reject/accept:#3545 真实死链形状、
docs/递归遍历(15 个文件里 13 个在子目录,只开顶层会静默全绿)、离开docs/的链接照收(无 collection 可逃)、无扩展名拼写与绝对/...照拒。两处 control 链接:围栏边界测试与
docs/vscontent/docs/对照测试如果只断言「期望的那一条」,删掉扫描行它们会因什么都没扫而空绿。各加一条必被报出的 control 后,删行即红——已实测(见下)。逆向验证(先定方向,再跑;四项全中)
ROADMAP.md(单文件根)植入死链example-relative[example-relative] ROADMAP.md:1900 -> ./docs/NOWHERE-3572.md,exit 1docs/adr/嵌套文件(目录根)植入死链[example-relative] docs/adr/9999-reverse-check.md:3,exit 1Links are valid across 3 scan roots.,exit 0测试层同做一次:撤掉三行后 7 个新增/扩写的测试变红,其中包含围栏边界测试——证明那条 control 链接确实让它无法空绿。全部植入项已还原,工作树只剩三个目标文件。
ci-cd-pipeline.md:三处被证伪,做最小事实订正(披露)except围栏内内容。另加一段说明围栏边界,以免读者把该表读成全覆盖。该文件对 Lychee「deliberately not a PR gate」的描述本身正确,未动。
顺手发现(未在本 PR 修,已另立单)
#3587(observation-class,
finding,未指派):scripts/check-doc-links.mjs:157与测试文件:853两处称 Lychee 是 "weekly cron withcontinue-on-error",而check-links.yml实际是fail: true且根本没有 PR 触发器。结论「gates nothing」对,机制说反了——照该理由行事的人会去摘一行不存在的continue-on-error,而真取消注释pull_request:会立刻变成 #3213 明令不要的硬门禁。属 #3536 既有注释,不在 #3572 改动面内,故只订正本 PR 新写的那句(按正确机制表述),旧两处留给 #3587。验证
无 changeset:纯 CI 门禁改动,非用户可见特性。未触碰
content/docs/releases/。Generated by Claude Code