跳转到内容

GRP-002 循环引用

将文档间的 Markdown 链接视为图,验证是否存在循环(如 A → B → C → A 这样的闭环)。发现循环时,会报告为 error。这是项目作用域规则,会跨越 include 加载的所有文档进行评估。

检测对象仅限相对路径指向 .md 文件的链接。仅锚点链接(#section)和外部 URL 会被忽略。

文档 A 引用 B,B 引用 C,C 又引用 A,这样的循环单看任意一个文件都不可能察觉。维持一致的依赖关系需要文档图为 DAG(有向无环图);循环会导致读者困惑,并使更新影响范围难以追踪。用 AI 大量生成文档时,链接也可能在无意中变为双向,从而产生循环。本规则可检测此类循环。

字段类型必填说明
filesstring循环检测对象的文件 glob。未指定则覆盖所有文档
excludestring[]从图中排除的文件 glob 数组

省略全部选项也可工作。exclude 用于排除像目录文件或 index 文件那样有意持有多向链接的文件。

docs/a.md:
# A
See [B](./b.md).
docs/b.md:
# B
See [C](./c.md).
docs/c.md:
# C
See [A](./a.md).

发生 a.md → b.md → c.md → a.md 的循环,故判定为违例。

docs/a.md
line 2 error Circular reference detected: docs/a.md -> docs/b.md -> docs/c.md -> docs/a.md GRP-002

切断循环中「依赖最弱的链接」。例如把 c.md → a.md 的链接换成其它表达方式。

docs/c.md:
# C
This module is consumed by upstream documents.
{
"rule": "grp002",
"options": {
"files": "docs/**/*.md",
"exclude": ["docs/index.md", "docs/sitemap.md"]
}
}

exclude 中指定的文件会作为节点从图中整体排除。经由它们形成的循环不在检测对象内,因此推荐仅用于必须双向链接的目录类文件。