Skip to content

docs(corpus): standard for provenance (#1321) - #1522

Merged
tucktuck101 merged 2 commits into
launchpadfrom
task/1321-corpus-standard-provenance
Aug 28, 2026
Merged

docs(corpus): standard for provenance (#1321)#1522
tucktuck101 merged 2 commits into
launchpadfrom
task/1321-corpus-standard-provenance

Conversation

@serina-mcfall

Copy link
Copy Markdown

Summary

Adds launchpad/docs/corpus/standards/provenance.md, the canonical policy node deciding what a corpus node's recorded-revision commit citation asserts, when it may move to a later revision, and what an author owes the ledger when only some claims are re-verified against a new HEAD. AGENTS.md's "Updating a node" section currently states its own four-branch text as provisional and names this issue as the place the question gets settled.

Related issue

Closes #1321

Issue type

Task


Agent provenance

Field Value
Harness / provider Claude Code
Model claude-sonnet-5
Session reference N/A
Initiating human N/A

Objective

One hand-authored corpus node, corpus-standard-provenance, that settles the recorded-revision question AGENTS.md currently defers.

Impacted components

  • launchpad/docs/corpus/standards/provenance.md

Approach and rejected alternatives

Read node.schema.json and validate.py first rather than trusting AGENTS.md's prose restatement of them: the schema has no per-claim revision field, so the recorded-revision citation is structurally a whole-ledger claim, not a per-claim one. That fact drives the whole rule — an edit that re-verifies some claims cannot honestly move the entry unless every claim (touched or not) is known to hold at the new revision, established per-claim by either re-verification or a clean, normalized git diff --name-only restricted to claims whose citations are entirely file-naming.

Rejected alternative: keep AGENTS.md's four branches verbatim as the corpus-wide rule. Branch 2 ("re-verified some → move it only if the rest still holds too — check, do not assume") never says what "check" means operationally, which is the exact ambiguity #1321 exists to close. This document replaces that branch with a decidable, per-claim procedure instead of restating the ambiguity as settled.

Found a real worked example already in this repository's own history: commit 919886b4192df6251de50c547548ecae5d85afce (on this branch, predating this task) left AGENTS.md's own recorded revision unmoved after a rebase, checked via git diff against nine normalized file citations with the two non-file citations explicitly excluded. That is this document's rule, applied before the rule was written down — used as the worked example rather than inventing a hypothetical one.

Did not edit AGENTS.md, confidence.md, or decision-references.md — out of scope for this diff. Filed a separate reconciliation issue for AGENTS.md's "Updating a node" section instead.

Verification

Command run:

python3 launchpad/project-intelligence/corpus/validate.py

Raw output:

UNVERIFIED  corpus-agents: evidence entry 1, citation 1: is a commit reference, which names no openable file
UNVERIFIED  corpus-agents: evidence entry 20, citation 1: is a graph-edge or tool-result citation, which names no openable file
UNVERIFIED  corpus-readme: evidence entry 1, citation 1: is a commit reference, which names no openable file
UNVERIFIED  corpus-standard-confidence: evidence entry 1, citation 1: is a commit reference, which names no openable file
UNVERIFIED  corpus-standard-decision-references: evidence entry 1, citation 1: is a commit reference, which names no openable file
UNVERIFIED  corpus-standard-provenance: evidence entry 1, citation 1: is a commit reference, which names no openable file
UNVERIFIED  corpus-standard-provenance: evidence entry 10, citation 1: is a graph-edge or tool-result citation, which names no openable file
UNVERIFIED  corpus-standard-provenance: evidence entry 10, citation 2: is a graph-edge or tool-result citation, which names no openable file
UNVERIFIED  corpus-standard-provenance: evidence entry 11, citation 1: is a graph-edge or tool-result citation, which names no openable file
UNVERIFIED  corpus-standard-provenance: evidence entry 12, citation 1: is a commit reference, which names no openable file
PASS  corpus validation found no errors; 10 item(s) reported unverified

Exit status: 0

Command run:

python3 -m unittest discover -s launchpad/docs/corpus/schema/tests -p "test_*.py" -v

Raw output:

Ran 27 tests in 0.033s

OK

(27/27 tests passed; all UNVERIFIED notices above are expected commit and tool-result citations, none are errors.)

  • Tests or checks were run and the raw output is pasted above
  • The diff is confined to the scope of the linked issue
  • No secrets, keys, tokens or hostnames were added to tracked files

Not verified

No node's recorded revision has actually been moved forward under this document's rule yet — the one worked example in the document (commit 919886b4) is an instance of the entry staying unmoved via the diff route, not an instance of it moving. Whether the "full re-verification" route reads as practical once a real edit needs it, on a ledger this corpus's size, is untested. Whether SHOULD 2 (recording which MUST 3 route was used, in the commit/PR description) is realistic to reconstruct from a typical PR was not tested against a live PR — the worked example predates this document and was read from its commit message. No generated view or downstream tooling was found that reads the recorded-revision entry specifically, so whether anything already assumes a different meaning than this document states is unknown.

Security implications

None. This is a documentation-only change to a Markdown policy node; it does not alter validate.py, the schema, CI, or any runtime behavior.

Escalations

Filed #1520 to reconcile launchpad/docs/corpus/AGENTS.md's "Updating a node" section: its four-branch text differs from this document's rule (this document replaces the ambiguous "re-verified some → move it only if the rest holds, check don't assume" branch with a decidable per-claim procedure), and that section explicitly says it will defer to this node once it lands. I do not have permission to edit AGENTS.md in this diff, so the reconciliation is filed as a separate task rather than done here.

…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>
Settles what a node's recorded-revision commit citation asserts, when
it may move to a later revision, and what an author owes the ledger
when only some claims in it are re-verified against a new HEAD.

node.schema.json gives a node exactly one place to record a checked
revision -- a plain commit citation in the evidence array -- and no
field records which revision a single claim was checked against. That
makes the recorded-revision entry a whole-ledger claim, so moving it
without knowing every claim holds at the new revision (not only the
ones an edit touched) would let untouched claims inherit currency
that was never checked.

The rule: a touched claim is always re-verified in the same edit
(unconditional). The recorded revision moves only when every claim in
the ledger is known to hold at HEAD, established per claim by either
re-verification or a clean, normalized `git diff --name-only` against
citations that are entirely file-naming (bare path / file line / file
range) -- the only three of six citation shapes AGENTS.md's own diff
method reaches. Anything else leaves the entry unmoved, which is
always the safe default.

AGENTS.md's own most recent fix to itself (919886b, on this branch)
is the worked example: it rebased, touched other claims, and left its
recorded revision unmoved, checked instead via `git diff` against nine
normalized file citations with the two non-file citations explicitly
excluded -- this document formalizes that practice rather than
inventing a new one.

AGENTS.md's "Updating a node" section already names this issue as the
place this question gets settled and states its own four-branch text
as provisional; this diff does not edit AGENTS.md itself, so a
reconciliation issue is filed separately for the owning task to align
that section's text with this document once it lands.

Closes #1321

Signed-off-by: Serina Mcfall <serina.mcfall@gmail.com>
@serina-mcfall serina-mcfall added the by:agent Filed or authored by an AI agent, not a human label Aug 27, 2026
@serina-mcfall
serina-mcfall marked this pull request as ready for review August 27, 2026 01:51
@tucktuck101 tucktuck101 self-assigned this Aug 27, 2026

@tucktuck101 tucktuck101 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review — standard for provenance (#1321)

The substance — what a recorded revision does and does not certify — is a genuinely useful rule,
and the override of AGENTS.md's four-branch text is legitimate: AGENTS.md hands this question to
#1321 explicitly. But the document states two opposite precedence rules 26 lines apart, and the
one a reader hits first cancels the override this node exists to make.

High — the document says AGENTS.md both wins and has drifted

provenance.md:95-100 lists launchpad/docs/corpus/AGENTS.md as the first row of its deference
table, and :102-103 says:

Those files are authoritative. Where this document and any of them disagree, they win --
this one has drifted and should be fixed.

:127-129 says the reverse:

...where the rule stated here differs from AGENTS.md's current text, AGENTS.md is the one
that has drifted.

These cannot both be applied, and the choice is load-bearing rather than cosmetic. This node's
entire substance is a deliberate override of AGENTS.md's revision-move text — the PR body lists
"keep AGENTS.md's four branches verbatim" as the rejected alternative — and AGENTS.md's post-#636
text asserts the opposite of MUST 3 route 2 in as many words. A reader who applies the :102-103
boilerplate keeps the ambiguous branch this node was commissioned to replace, leaving #1321's DoD
undischarged.

The fix is to carve AGENTS.md's "Updating a node" / recorded-revision text out of the blanket
deference clause, not to weaken the rule.

Medium — MUST 3 route 2 is unsound for absence and exhaustiveness claims

Route 2's justification (:176-186) is that if the cited files did not change, "checking it then
would have been the identical act to checking it now, so nothing was skipped." That holds only
when a claim's truth is a function of the bytes of the files it cites. It fails for claims of the
form "nothing under X does Y": a newly added file falsifies the claim while
git diff --name-only <sha> -- <cited paths> stays empty, because the new file is not among the
cited paths. Route 2 would then certify as "known to hold" a claim that has become false.

Not hypothetical — sibling PR #1517's status.md:56-59 is exactly such a claim (it survives only
because it is scoped to two named files), and ADR-0050 carries the unscoped form
("Infrastructure corpus appears nowhere else under launchpad/"). MUST 3 already excludes
claims by citation shape; it needs the parallel exclusion by claim shape, with route 1
(re-verification) as the fallback the document already provides.

Medium — no ## MUST and no ## SHOULD section

All eight normative items live inside one section titled ## The rule (:158) as bolded run-in
paragraphs — MUST 1-5 then SHOULD 1-3. Headings are: Scope and authority, What the recorded
revision means, The rule, Worked example, What the checks establish and what they do not,
Exceptions and escalation, Scope and omissions (verified by grep -n '^## ').

The meta-standard requires MUST and SHOULD as separate sections, and one list with mixed modal
verbs does not satisfy it however clearly the verbs are written. This is the same remedy #1507
records against the sibling nodes and that #1508 is landing in this very batch, so it is an
established fix rather than a judgement call. Splitting ## The rule preserves every identifier
and cross-reference.

Medium — the enforcement section never uses the word "Enforcement"

:243 is ## What the checks establish, and what they do not — a verbatim copy of
decision-references.md's heading, which is the one the documentation-standard singles out for
exactly this reason. The section's content is good (:243-256 states plainly that nothing
enforces the rule and what a green run does not establish); only the name is wrong.
## Enforcement, and where it stops is the accepted suffixed form confidence.md keeps.

Low — the H1 topic does not match the subject the id names

:85 is # Standard: the recorded revision, while the id is corpus-standard-provenance and
the file is standards/provenance.md. A future generated index resolving that id lands on a page
titled something else. If "the recorded revision" is genuinely the settled subject of #1321
rather than provenance broadly, raise that narrowing against #1321 explicitly rather than
encoding the mismatch in the H1.

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). 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

  • The core distinction — a clean git diff narrows what must be re-checked but does not certify
    that a claim still holds — is right, and matches AGENTS.md's own post-#636 wording.
  • The worked example is concrete and follows the rule it illustrates.
  • The document is explicit that nothing mechanically enforces MUST 3, rather than implying a
    check exists.
  • Node validates clean.
  • CI green at head (latest run per check).

Reviewed by tucktuck101's review lane. Both precedence passages, the heading inventory, and the
AGENTS.md comparison are my own reads at this PR head.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

by:agent Filed or authored by an AI agent, not a human

Projects

None yet

Development

Successfully merging this pull request may close these issues.

task: document corpus standard for provenance

2 participants