Context:
Identified during work on #11 (see its follow-up comment) and in the architectural review of #12.
Description:
internal/docscheck (added in #12) gates claims that are mechanically false — a link that does not resolve, a path that does not exist, an undated changelog section. It explicitly does not, and cannot, reach a different and more dangerous class: prose in a versioned contract that describes behaviour nothing verifies.
The motivating case, from #11's follow-up comment: docs/schema-threat-model.md stated that the rendered companion "anchors every entity in one namespace", and used that claim to justify the document-wide identifier uniqueness rule. Seven of thirteen collections were not anchored. The same claim was echoed in CHANGELOG.md and two comments in internal/threats/validate.go, so a reader had four mutually consistent statements of something the template did not do. A link checker would have passed all four.
Two more of the same kind: the control-character guarantee the docs promised for ~60 unchecked fields, and the escaping rules in docs/config.md.
What actually caught the anchoring claim was a reviewer reading the template. What now pins it is TestEveryDeclaredEntityIsAnchored, which enumerates the fixture's own collections so a collection added later fails the test the day the fixture declares one.
The gap: that fix exists as one good instance, not as a repository convention. Nothing makes the link from a prose claim to its verifying test discoverable to the next reviewer working under the same time pressure that let the original claim drift.
Proposal:
Add a convention to AGENTS.md, beside the "Documentation checks" section #12 introduced: every behavioural claim in a versioned contract document (docs/schema*.md, docs/config.md, docs/cli.md) cites the test that pins it — the same way CHANGELOG.md already cites issue numbers.
This is a documentation change, not a checker. Do not build a linter for it: deciding from text whether a claim is "verified" versus merely unreferenced is not mechanically decidable, and #12's whole design premise is that a check which cries wolf gets switched off.
If the convention proves its worth, a narrow follow-on check becomes plausible later — assert that a backticked TestXxx name cited in docs/*.md actually exists in the Go source, symmetric to CheckNamedPaths but for identifiers. That is speculative and should not be built ahead of the convention it would enforce.
Rationale:
Deferred from #12, which correctly scoped itself to mechanically-false claims and said so in its package comment rather than pretending to cover this. The architectural review of #12 recommended codifying the convention as a companion change.
Reference:
Acceptance Criteria:
Context:
Identified during work on #11 (see its follow-up comment) and in the architectural review of #12.
Description:
internal/docscheck(added in #12) gates claims that are mechanically false — a link that does not resolve, a path that does not exist, an undated changelog section. It explicitly does not, and cannot, reach a different and more dangerous class: prose in a versioned contract that describes behaviour nothing verifies.The motivating case, from #11's follow-up comment:
docs/schema-threat-model.mdstated that the rendered companion "anchors every entity in one namespace", and used that claim to justify the document-wide identifier uniqueness rule. Seven of thirteen collections were not anchored. The same claim was echoed inCHANGELOG.mdand two comments ininternal/threats/validate.go, so a reader had four mutually consistent statements of something the template did not do. A link checker would have passed all four.Two more of the same kind: the control-character guarantee the docs promised for ~60 unchecked fields, and the escaping rules in
docs/config.md.What actually caught the anchoring claim was a reviewer reading the template. What now pins it is
TestEveryDeclaredEntityIsAnchored, which enumerates the fixture's own collections so a collection added later fails the test the day the fixture declares one.The gap: that fix exists as one good instance, not as a repository convention. Nothing makes the link from a prose claim to its verifying test discoverable to the next reviewer working under the same time pressure that let the original claim drift.
Proposal:
Add a convention to
AGENTS.md, beside the "Documentation checks" section #12 introduced: every behavioural claim in a versioned contract document (docs/schema*.md,docs/config.md,docs/cli.md) cites the test that pins it — the same wayCHANGELOG.mdalready cites issue numbers.This is a documentation change, not a checker. Do not build a linter for it: deciding from text whether a claim is "verified" versus merely unreferenced is not mechanically decidable, and #12's whole design premise is that a check which cries wolf gets switched off.
If the convention proves its worth, a narrow follow-on check becomes plausible later — assert that a backticked
TestXxxname cited indocs/*.mdactually exists in the Go source, symmetric toCheckNamedPathsbut for identifiers. That is speculative and should not be built ahead of the convention it would enforce.Rationale:
Deferred from #12, which correctly scoped itself to mechanically-false claims and said so in its package comment rather than pretending to cover this. The architectural review of #12 recommended codifying the convention as a companion change.
Reference:
internal/threats—TestEveryDeclaredEntityIsAnchored, the pattern to generaliseinternal/docscheck/docscheck.go— package comment, which declines this class explicitlyAGENTS.md— "Documentation checks", where the convention belongsAcceptance Criteria:
AGENTS.mdstates the convention and shows one worked exampledocs/config.mdescaping claims each cite their pinning test