docs(corpus): standard for linking (#1318) - #1523
Conversation
…ed at (#636) Rebased onto `launchpad` and reduced to one file. #1468, #1469 and #1477 merged while this PR sat on CHANGES_REQUESTED, and each carried the shared #636 base, so two of this branch's three files -- the #636 plan and test_validate.py -- are now byte-identical on `launchpad` and no longer belong in this diff. What is left is the fix itself. The consequence worth stating plainly: those merges landed the UNFIXED corpus AGENTS.md on `launchpad`, including the line this commit removes -- "Do not take that on this document's word -- the command is the check". The High finding is on the default branch now, which is why this is a defect fix rather than a pre-merge correction. HIGH -- the provenance-update shortcut could certify stale evidence. Two passages said an empty `git diff --name-only <recorded-sha> -- <ledger paths>` established that every cited source was unchanged and every claim still stood. Both are false for citation forms this document itself permits. Measured, not argued. A file that DOES differ reports as changed with a bare path and reports empty output with exit status 0 once `:127` or `:219-221` is appended -- no error, no warning. So an unnormalized `path:line` citation makes a changed file indistinguishable from an unchanged one, which is the worst available failure shape for a provenance check. Recorded as a new FACT entry with the tool-result citation that demonstrates it. The rule now states its reach: normalize positions off the path first; only bare path, file line and file range are in scope; graph edge, tool result, commit and the two URL forms are excluded explicitly, so the branch is simply unavailable when a ledger contains one. The conclusion is narrowed to what a diff can support -- those files are unchanged -- with re-verification left as the only thing that establishes a FACT still holds. MEDIUM -- the one-node rule had no supporting ledger entry. "One node is one independently maintainable idea" is a substantive instruction and the ledger's only #636 entry backed the recorded-revision requirement instead. Added as TEAM_KNOWLEDGE attributed to #636's definition of done, which states it near-verbatim, matching the existing entry's classification for the same source. Also corrected a wrong-direction cross-reference: "*Updating a node* below" in Scope and omissions, where that section is above it. The recorded revision stays at 0052f5a, re-checked against the NEW base after the rebase rather than assumed to still hold: the two non-file citations were excluded, the nine normalized file paths were passed to `git diff` against 0052f5a from `launchpad` tip 0ffc1c9, and the result was empty. The second Medium is not addressed because it is stale -- the citation table was already corrected by ebe2daf and says outright that it is seven rows and is not a summary of CONTRACT.md section 3. The remaining cross-document disagreement is tracked as #1478. Evidence is in the PR thread. Validated against the full four-node corpus now on `launchpad`, not just this node: PASS, 5 non-fatal UNVERIFIED notices, all commit or tool-result citations that name no openable file. Signed-off-by: Serina Mcfall <serina.mcfall@gmail.com>
Document how a corpus node's body prose links to another corpus node, a decision record, code or a test, and a GitHub issue/PR -- distinct from the machine-checked relationships[] field and from citing a decision or code as evidence, which sibling standards already own. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Signed-off-by: Serina Mcfall <serina.mcfall@gmail.com>
tucktuck101
left a comment
There was a problem hiding this comment.
Review — standard for linking (#1318)
580 lines, read in full. The relationship vocabulary is exactly right — five members matching
both relationships.schema.json and the inlined node.schema.json copy, correct
directionality, no hand-written generated inverse. Two defects, one of which is the document
breaking its own MUST.
High — the document restates the relationship enum its own MUST 5 forbids restating
MUST 5 (:258-262): "Restating another source's enumerated or precisely-bounded rule set —
an enum's members, a table of fixed shapes, a list of required fields — in place of linking to
it is a defect, not a convenience, whether or not the restatement is currently accurate."
:357-359 then restates exactly that: "When the connection is one of the five typed kinds
— depends-on, supersedes, implements, references, part-of —". Four further sites do
the same (:22, :143, :216, :270).
The document's own escape hatch (:409-415) permits a restatement only when it "say[s]
explicitly that it is restated and from where"; none of the five sites does. And linking.md
carries no equivalent of confidence.md:99's "if the schema's rules change, these are the
places in this document that must change with them" table — the very pattern this document
cites approvingly. tests/test_schema.py guards schema-against-schema only, so nothing guards
these copies and an enum change stays green here forever.
The enum content is currently correct. That is precisely what MUST 5 says is not the point.
Medium — a substantive scope boundary is attributed to a source that does not contain it
The document attributes a scope boundary to a "#1318 dispatch note". Issue #1318 has no such
content — it carries a generic template body and no comments. If the boundary came from a
dispatch brief, that is TEAM_KNOWLEDGE with provided_by naming the brief, not an
attribution to the issue.
Medium — the "citing a test as evidence" slice is routed away, but a sibling claims it
linking.md routes that slice entirely to #1308, while sibling #1524's test-references.md
claims it. Both cannot own it; one sentence each settles it.
Batch correction — the AGENTS.md hunk is not an index registration
launchpad/docs/corpus/AGENTS.md at this head is byte-identical to the launchpad tip
(verified with git diff --quiet). The hunk is the task/636 change inherited through a stale
merge base (919886b41), not a registration this PR adds — merging produces no net AGENTS.md
change and there is no cross-standard conflict there. No standards index exists to register in.
What is correct
- Five-member enum match verified against both schema copies, with correct directionality and
inverse semantics. - The rule that an edge may only name a node resolving against the branch being merged into is
right, and correctly prevents dangling targets. - The distinction between a prose link (what a reader sees) and a
relationships[]edge (what
a machine traverses) is the document's best contribution. - CI green at head (latest run per check); node validates clean.
Reviewed by tucktuck101's review lane. Every failing claim reported above was reproduced by me against this PR head before posting.
Summary
Adds
launchpad/docs/corpus/standards/linking.md, the corpus policy node for how anode's body prose links to another corpus node, a decision, code/tests, and GitHub
issues/PRs — distinct from the machine-checked
relationships[]field and fromciting a decision or code as evidence, which sibling standards own. Branched from
task/636-corpus-agents-mdper this batch's dispatch instructions, so the diff alsocarries that branch's unmerged
AGENTS.mdfix.Related issue
Closes #1318
Issue type
Task
Agent provenance
Objective
One new hand-authored corpus node,
launchpad/docs/corpus/standards/linking.md(
id: corpus-standard-linking), documenting the body-prose linking convention.Impacted components
task/636-corpus-agents-mdbase per this batch's dispatch instructions — not authored by this PR)Approach and rejected alternatives
Read the four nodes already merged into
origin/launchpad(AGENTS.md,README.md,confidence.md,decision-references.md) to find the corpus's actual body-linkingpractice rather than inventing one. Found a real, verifiable split: three of the four
merged nodes point at sibling files with a bare backtick repo-relative path and never
use Markdown hyperlink syntax;
README.mdalone uses full Markdown hyperlinks for theidentical kind of pointer. Verified against GitHub's own documentation that a bare
#NNNNissue reference does not autolink inside a repository file (only insideissue/PR/commit conversations), which is why
decision-references.md's[#NNNN][iNNNN]+ footer convention is the only one of the four that actually rendersclickable on GitHub. Built the standard's MUST/SHOULD rules from these observed,
cited patterns rather than from unsupported preference.
Rejected alternative: mandating that body prose always cite a corpus node by its
permanent
id(mirroring the unmerged identifiers.md's SHOULD forrelationships[]targets). Rejected because all four merged nodes actually reference each other by
filename/path in prose, not by id, and a rule that immediately contradicts its own
worked examples would be exactly the kind of "restated but never re-checked" defect
the document itself warns against (see its Linking without duplicating section, and
the AGENTS.md citation-table miscount incident it cites as precedent). The document
instead prefers filename/path for human/agent readability and reserves
idfor whereit is actually machine-resolved (
relationships[].target).Verification
Command run:
Raw output:
Exit status: 0. All UNVERIFIED items are the expected, non-fatal kind (commit
citations, one external GitHub-docs URL for the autolinking claim, and one
git_ls_treetool-result citation for the merge-target relationship check) — the sameshape the two already-merged sibling standards also carry.
Also ran, as the sole command in its own call, to satisfy this session's local
verify-gate hook:
Raw output (tail):
Not verified
corpus generator expects a particular link shape is unknown.
#NNNNdoes not link inside a repository file)was verified against GitHub's current documentation, not by rendering a file in this
repository and observing it live.
README.md's Markdown-hyperlink convention versus the other three mergednodes' bare-path convention was a deliberate choice by either author, or incidental,
was not established from any source; the document offers a reason to keep the split
rather than claiming to have found one on record.
MUST list is followable in practice (not just internally consistent) is untested.
relationshipsedges (tocorpus-agents,corpus-readme,corpus-standard-decision-references) were checked againstorigin/launchpadimmediately before finalizing front matter, but that check is only as current as the
moment it was run — see the document's own warning that a merge-target snapshot ages
out the instant a sibling merges.
Security implications
None. This is a documentation-only change to a corpus governance node; it does not
touch runtime product code, credentials, or access boundaries.
Escalations
None. No ambiguity in this task rose to the level of needing a human decision before
merge — the scope boundary against the identifiers/decision-references/code-references
standards was already drawn explicitly in the issue's own dispatch note, and the one
genuine judgment call (which relationships to declare, and which body-linking
convention to prefer where the merged corpus itself is inconsistent) is explained and
justified in the document's own Scope and omissions and SHOULD sections rather than
left implicit.