Skip to content

Docs · Metrics

The opt-in Docs family adds seven metrics on top of the always-on Code family. Each one targets a specific way documentation drifts from the source it describes.

For configuration knobs see Docs › Configuration. For the bundled skills see Docs › Skills.

MetricLayerWhat it flagsSeverity
doc_freshnessA (paired)source commits since the paired doc last changedfloors (default ≥ 5 High, ≥ 20 Critical)
doc_driftA (paired)doc references an identifier no longer in the paired sourceuniform Critical
doc_coverageA (paired)pair entry whose doc path doesn’t exist on diskuniform Medium
doc_link_healthA + Binternal relative-path / #anchor link doesn’t resolveuniform High
orphan_pagesB (standalone)Layer B doc not linked from anywhere; not paireduniform Medium
todo_densityA + BTODO / FIXME / XXX / TBD / [要確認] / [要修正] markers per doc≥ 3 Medium, ≥ 10 High
doc_hotspotA (paired)paired_src_churn × debt composite — flips hotspot=true on docs-family Findingsalways Ok (decoration carrier)

Layer A (paired docs) needs a doc ⇔ src mapping in .heal/doc_pairs.json, generated by /heal-doc-pair-setup. Layer B (standalone prose docs) is auto-discovered via the [features.docs.standalone] include / exclude globs.

“Has the source moved since the doc was last touched?”

Per-pair source-commits-since-paired-doc count. Distance is measured in git commits, not wall-clock days, so the threshold doesn’t shift as the team’s commit pace changes. Floors live in [features.docs.doc_freshness] — defaults: ≥ 1 Medium, ≥ 5 High, ≥ 20 Critical.

“Does the doc still reference identifiers that exist in the source?”

Scans each Layer A doc, extracts identifier-shaped backtick spans (`Foo::bar`, `processOrder`), and emits a Finding for each one that doesn’t resolve to any identifier in the paired source. Severity: Critical — a reader acting on a missing identifier wastes time looking for code that no longer exists. The fix is mechanical: remove the reference, or restore the identifier under its new name.

Type 2 (signature mismatch) and Type 3 (semantic drift) are deferred to v0.5+.

“Does the paired doc actually exist on disk?”

Pair entries whose doc path doesn’t exist. Severity: uniform Medium by design — Critical here would incentivise empty-stub manufacturing. Medium says “consider writing this”, not “you must”. The fix is either real content or heal mark accept recording the “won’t doc” decision.

“Do the internal links in the docs resolve?”

Per-link Findings: MissingPath (relative-path link doesn’t resolve to a file) and MissingAnchor (#anchor doesn’t match any heading in the target). Heading slugs follow the GitHub-style convention (lowercase + non-alnum → -). Severity: High — internal breaks are mechanical to fix and high-impact for readers.

External HTTP links are out of scope — heal is local-only; lychee and similar cover HTTP in CI.

“Which Layer B docs aren’t reached from anywhere?”

Layer B docs that aren’t linked from any other doc and aren’t paired. Conventional entry points (README.md, index.md at any depth) are seeded as “linked” so they don’t trip the metric. Severity: Medium — an orphan doc isn’t broken, just hard to discover; the fix is usually a one-line link from the parent README.

“How many open TODOs is each doc carrying?”

Per-doc count of TODO / FIXME / XXX / TBD / [要確認] / [要修正] markers. Markers inside fenced code blocks (and, by default, backtick-quoted inline code) are excluded so a reference page that describes the marker keywords doesn’t self-flag every paragraph. Severity: ≥ 3 Medium, ≥ 10 High.

When [features.docs] is on, the Duplication observer runs a parallel pass over Markdown / RST files. Findings land under the same duplication metric string as the code-side blocks; the distinguisher is the file extension.

The use case is spotting docs copy-pasted across language mirrors (en + ja), across module-specific READMEs, or across API reference pages with shared boilerplate — the fix is usually a “see also” link plus a single canonical source.

Window length is [metrics.duplication].docs_min_tokens (default 100).

Doc Hotspot — which paired doc is most worth updating

Section titled “Doc Hotspot — which paired doc is most worth updating”

Doc Hotspot is the docs-family analogue of code Hotspot. It ranks paired doc ↔ src entries by paired_src_churn × debt, where debt = src_commits_since_doc + weight_drift × dangling_idents. A pair scores high when the source is moving fast and the doc has fallen behind — “of all your docs, this is the next one worth updating”.

Only paired entries from doc_pairs.json are scored. Standalone docs (READMEs, concept guides) live under orphan_pages / todo_density instead.

Doc Hotspot itself always carries Severity::Ok; it decorates the docs-family Findings (doc_freshness, doc_drift, doc_coverage, doc_link_health, todo_density) so the same 🔥 flag points at the next doc-pair worth updating.

/heal-doc-review frames the findings through the Diátaxis lens — Tutorial / How-to drift first (the highest-leverage fix for confused first-time readers), then Reference, then Explanation. /heal-doc-patch works through the docs slice one commit at a time:

  • doc_link_health → fix the relative path or anchor slug.
  • doc_drift → remove the stale reference, or restore the identifier under its new name on a clear rename.
  • doc_freshness → re-read the paired source and update the doc.
  • orphan_pages → add a link from the parent README, or delete the orphan.
  • todo_density → resolve the resolvable TODOs; escalate the rest to issues.
  • doc_coverage → write a real stub, or heal mark accept if the team decided this source doesn’t need its own doc.

See Docs › Skills for the full contracts.