docir — design documents Graph

Documents / Issues / issue-71555a89a73d

Nothing reports a heading that appears twice in one document

A repeated heading makes --section resolve to the first occurrence and leaves the second unreachable by name, silently.

issue-71555a89a73dissueresolved#cosmetic#retrieval
View as Markdown◉ View in graph

What happens

_locate_section returns the first heading whose text matches, so a document that uses one heading twice has a second section nothing can address. Found by hand in ref-1509d5dbb4c3, a probe log that reused ## Findings produced BY these changes for two sessions: --section returned 3,731 characters and the other 4,003 were reachable only by fetching the whole body.

The document was fixed by dating both headings. Nothing would have reported it.

Why it is only a warning

First-match is the right resolution rule — an error would refuse to read a document that is merely repetitive, and hand-editing markdown is permitted, so the corpus can acquire one at any time. The gap is that the condition is invisible, not that the behaviour is wrong.

One occurrence in 142 documents, so this is a slow leak rather than a live problem, and it is exactly the shape Tier 2 exists for.

What it needs

An ambiguous-heading advisory beside oversized-section in docir lint --deep, naming the document and the heading. Cheap: the heading list is already computed by scan_headings, and the check is a count.

The guard has to assert which heading it found, not merely that it found one — a count cannot distinguish a corpus with no duplicates from a scan that looked at nothing.

Resolution

SimilarityLinter.find_ambiguous_headings reports it as a Tier 2 advisory, naming the heading and how many times it appears. It reads scan_headings, so a heading repeated inside a fenced block is not one.

Shipped alongside unqualified-section-ref, the paired gap found the same afternoon: prose naming a section that lives in another document, which is what a document split leaves behind.

That second check needed a correction before it was worth having. The first version keyed on any heading in the corpus, and both findings it produced were wrong: Resolution is a heading in dozens of issues, so quoting the word tripped it, and where several documents share a name the "it lives in X" clause picked one arbitrarily and named the wrong document. It now considers only headings unique to a single document — a check that cannot say which document is not entitled to the sentence. Both false positives are pinned as tests.

Verified by injection: removing the unique-owner gate fails test_a_heading_many_documents_share_is_never_flagged.

To amend: Re-verify: