@recallnet/remark-lint-docs-reachability 0.2.2 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,6 +2,56 @@
2
2
 
3
3
  Flags in-scope Markdown documents that are not reachable from policy-defined roots.
4
4
 
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install -D remark @recallnet/remark-lint-docs-reachability
9
+ ```
10
+
11
+ ## Use
12
+
13
+ ```js
14
+ import { remark } from "remark";
15
+ import remarkLintDocsReachability from "@recallnet/remark-lint-docs-reachability";
16
+
17
+ await remark()
18
+ .use(remarkLintDocsReachability, {
19
+ cwd: process.cwd(),
20
+ policyPath: "./docs/docs-policy.json",
21
+ })
22
+ .process({
23
+ path: "docs/architecture/cache.md",
24
+ value: "# Cache\n",
25
+ });
26
+ ```
27
+
28
+ ## What It Checks
29
+
30
+ - all in-scope Markdown files matched by `in_scope_paths`
31
+ - graph roots declared by docs policy
32
+ - repo-local Markdown links between in-scope docs
33
+ - policy allowlists for roots, legacy docs, and orphan exclusions
34
+
35
+ The rule reports messages such as:
36
+
37
+ ```text
38
+ Document is not reachable from policy roots: docs/architecture/orphan.md
39
+ ```
40
+
41
+ ## Options
42
+
43
+ - `cwd`
44
+ Repository root used to resolve the docs policy and scan in-scope docs.
45
+ - `policyPath`
46
+ Path to the docs policy file relative to `cwd`.
47
+ Defaults to `docs/docs-policy.json`.
48
+
49
+ ## Notes
50
+
51
+ - External links are ignored. Reachability is only about repo-owned docs.
52
+ - Missing local link targets are ignored here; link correctness belongs to `remark-validate-links`.
53
+ - Broken symlinks outside the docs graph are skipped instead of crashing the scan.
54
+
5
55
  This package intentionally complements:
6
56
 
7
57
  - `remark-validate-links` for link validity
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@recallnet/remark-lint-docs-reachability",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "Remark plugin that flags markdown docs not reachable from policy roots.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -27,7 +27,7 @@
27
27
  "dependencies": {
28
28
  "remark": "^15.0.1",
29
29
  "remark-frontmatter": "^5.0.0",
30
- "@recallnet/docs-governance-policy": "0.2.2"
30
+ "@recallnet/docs-governance-policy": "0.2.3"
31
31
  },
32
32
  "publishConfig": {
33
33
  "access": "public"
package/src/index.js CHANGED
@@ -170,6 +170,8 @@ export function buildReachabilityReport(options = {}) {
170
170
  }
171
171
 
172
172
  export default function remarkLintDocsReachability(options = {}) {
173
+ let cachedReport = null;
174
+
173
175
  return (_tree, file) => {
174
176
  const cwd = options.cwd ? resolve(options.cwd) : process.cwd();
175
177
  const filePath = file.path ? normalizePath(relative(cwd, file.path)) : "";
@@ -178,7 +180,10 @@ export default function remarkLintDocsReachability(options = {}) {
178
180
  return;
179
181
  }
180
182
 
181
- const report = buildReachabilityReport({ cwd, policyPath: options.policyPath });
183
+ // @context decision !high [verified:2026-03-27] — Cache the reachability report for the lifetime of one remark process.
184
+ // remark invokes this rule once per file, but the orphan graph is repo-global. Rebuilding it per file turned 100-doc hooks into dozens of redundant full-doc parses.
185
+ cachedReport ??= buildReachabilityReport({ cwd, policyPath: options.policyPath });
186
+ const report = cachedReport;
182
187
  if (report.orphanDocuments.includes(filePath)) {
183
188
  file.message(`Document is not reachable from policy roots: ${filePath}`, {
184
189
  ruleId: RULE_ID,