Doc impact
doc_impact
Doc impact analysis — doc refs, undocumented symbols, stale signatures.
DocImpactResult
Bases: TypedDict
Output shape of :func:analyze_doc_impact.
Source code in packages/axm-ast/src/axm_ast/core/doc_impact.py
DocRefEntry
StaleSignature
Bases: TypedDict
Stale signature record extracted from a doc code block.
actual_sig is added only after matching against the AST signatures;
intermediate entries produced by :func:_match_signature_line omit it.
Source code in packages/axm-ast/src/axm_ast/core/doc_impact.py
analyze_doc_impact(root, symbols)
Full doc impact analysis for a set of symbols.
Combines doc refs, undocumented detection, and stale signature detection.
Caveat (canonical) — all three signals rest on a purely lexical
matching, never a semantic one. A symbol counts as mentioned when its
bare name appears between backticks or in a Markdown heading, and a
documented signature is only compared inside a fenced code block. No
meaning is read: a purely semantic change leaves this output identical
byte for byte, and a bare name-drop of the symbol anywhere in the prose
is enough to remove it from undocumented.
Read the result as a list of pages to read, not a proof that the documentation is correct or up to date. Never use it as a non-regression oracle: an unchanged output proves nothing about the prose still telling the truth — a human review remains the only verdict on doc correctness.
Limits — what this tool does not detect:
- A semantic change at unchanged name. Rewrite what a symbol means without touching its name and every signal stays identical, byte for byte: nothing here reports the prose that now lies.
- A bare name-drop counted as documentation. A single backticked
mention, even in an unrelated sentence, is enough to drop the symbol
from
undocumented— presence is not coverage. undocumentedis not a non-regression oracle. An empty or unchanged result proves nothing about documentation drift.
When the semantics of a symbol change while its name does not, re-read by
hand every page listed in doc_refs: that manual pass is the one thing
this tool cannot do for you. See docs/explanation/doc_impact_limits.md.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
root
|
Path
|
Project root directory. |
required |
symbols
|
list[str]
|
Symbol names to analyze. |
required |
Returns:
| Type | Description |
|---|---|
DocImpactResult
|
Dict with |
Source code in packages/axm-ast/src/axm_ast/core/doc_impact.py
find_doc_refs(root, symbols)
Find documentation references for given symbols.
The hit is purely lexical: a reference is recorded when the bare symbol name appears between backticks or in a Markdown heading of a doc file. Nothing else is interpreted — prose outside those two forms, and the body of a fenced code block, establish no semantic link.
The returned entries are pages to read, never a non-regression oracle: a stable output does not prove the prose still describes the code.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
root
|
Path
|
Project root directory. |
required |
symbols
|
list[str]
|
Symbol names to search for in docs. |
required |
Returns:
| Type | Description |
|---|---|
dict[str, list[DocRefEntry]]
|
Dict mapping symbol name to list of references |
dict[str, list[DocRefEntry]]
|
(each with |
Source code in packages/axm-ast/src/axm_ast/core/doc_impact.py
find_stale_signatures(root, symbols=None)
Detect stale code signatures in documentation.
Compares def / class signatures in doc code blocks
against actual AST signatures.
The scope is strictly a fenced code block: a signature written in plain prose, in an indented block or in an inline span is never extracted. The comparison itself is a lexical string equality, so a reformatted but semantically equivalent signature still reads as stale, and a stale signature outside a fenced code block is invisible here.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
root
|
Path
|
Project root directory. |
required |
symbols
|
list[str] | None
|
Symbol names to check. If |
None
|
Returns:
| Type | Description |
|---|---|
list[StaleSignature]
|
List of dicts with |
list[StaleSignature]
|
|
Source code in packages/axm-ast/src/axm_ast/core/doc_impact.py
find_undocumented(doc_refs, symbol_nodes)
Return public, docstring-less symbols absent from the prose docs.
A symbol is reported only when it has no prose documentation reference
and the shared :func:is_documentation_required policy considers it a
real gap — i.e. it is public surface (name not _-prefixed) and carries
no docstring. Private/dunder symbols and symbols already documented by a
docstring are never reported; this can only ever shrink the prose-missing
set, never grow it (the output schema is unchanged).
A symbol absent from symbol_nodes (unresolvable in the analyzed source)
keeps the legacy prose-only verdict, so a genuinely missing symbol is never
silently dropped.
The prose signal it consumes is purely lexical: find_doc_refs only
matches the bare name between backticks or in a Markdown heading, and never
reads the meaning of a fenced code block. A single name-drop of the symbol
therefore suffices to drop it from this list, without any real prose being
written. See :func:analyze_doc_impact for the canonical caveat.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
doc_refs
|
dict[str, list[DocRefEntry]]
|
Output of |
required |
symbol_nodes
|
dict[str, DocSymbolNode]
|
Bare-name → parsed node index (see
:func: |
required |
Returns:
| Type | Description |
|---|---|
list[str]
|
List of symbol names that are documentation-required gaps. |