Skip to content

docs(corpus): standard for deprecating and retiring a corpus node - #1494

Merged
tucktuck101 merged 7 commits into
launchpadfrom
task/1311-corpus-standard-deprecation
Aug 28, 2026
Merged

docs(corpus): standard for deprecating and retiring a corpus node#1494
tucktuck101 merged 7 commits into
launchpadfrom
task/1311-corpus-standard-deprecation

Conversation

@serina-mcfall

Copy link
Copy Markdown

Summary

Adds launchpad/docs/corpus/standards/deprecation.md (node id corpus-standard-deprecation), the corpus's policy for how a node stops being current: the activedeprecatedretired path, what each status obliges its author to do, and what a reader arriving at a non-active node is owed. The policy rests on one mechanism verified by experiment — the validator resolves relationship targets against the nodes it loaded, so deleting a node's file breaks every inbound edge while a status change breaks none. The same experiments show no code branches on which legal status a node holds, so the document states plainly that none of its rules are enforced rather than implying a green run means more than it does.

Related issue

Closes #1311

Issue type

Task


Agent provenance

Field Value
Harness / provider Claude Code
Model claude-opus-5[1m]
Session reference worktree __worktrees/task-1311-corpus-standard-deprecation, branch task/1311-corpus-standard-deprecation
Initiating human @serina-mcfall

Objective

One hand-authored corpus node documenting the deprecation and retirement lifecycle for corpus nodes.

Impacted components

launchpad/docs/corpus/standards/deprecation.md
launchpad/plans/2026-08-26-issue-1311-corpus-standard-deprecation.md

This PR is stacked. The branch is based on task/636-corpus-agents-md (PR #1462), so the diff against launchpad also carries AGENTS.md, #636's plan and a validator test file. That is deliberate and matches the sibling PRs in this batch — see the merge-order proof under Verification.

Approach and rejected alternatives

The document is built around the one thing here that is mechanically true and checkable — file presence decides edge resolution — and is explicit that everything else is convention a reviewer holds. Each MUST names the mechanism behind it, so the reasoning stays checkable even where the rule has no external source.

Rejected: attributing the MUST/SHOULD content to issue #1311 as TEAM_KNOWLEDGE. That was the original plan. AGENTS.md at this branch's base rules it out — "not a place to park a decision you made yourself" — and #1472 records the same narrowing. The issue asked for a policy with a MUST/SHOULD split; it did not supply the content. The document states those rules as its own and says so, instead of laundering an unsourced decision through an evidence class.

Rejected: deduplicating the MUST list against AGENTS.md's "Retiring a node" steps. They overlap almost one-to-one. Resolving it needs an ownership ruling plus a coordinated edit, and this branch may not touch AGENTS.md. Filed as #1481; the node discloses the overlap rather than claiming it links out.

Rejected: declaring relationships edges to corpus-agents. The edge validates on this branch and would be a hard error the moment this node reached launchpad ahead of #1462. Merge order, not an empty corpus — and the node says so, with the command to re-check, because that reason expires.

Verification

Command run:

cd /home/serina/Launchpad/buzz/__worktrees/task-1311-corpus-standard-deprecation
python3 launchpad/project-intelligence/corpus/validate.py
python3 -m unittest discover -s launchpad/docs/corpus/schema/tests -p "test_*.py"
python3 -m unittest discover -s launchpad/project-intelligence/corpus/tests -p "test_*.py"

Raw output:

UNVERIFIED  corpus-agents: evidence entry 1, citation 1: is a commit reference, which names no openable file
UNVERIFIED  corpus-standard-deprecation: evidence entry 1, citation 1: is a commit reference, which names no openable file
UNVERIFIED  corpus-standard-deprecation: evidence entry 17, citation 1: is a graph-edge or tool-result citation, which names no openable file
PASS  corpus validation found no errors; 3 item(s) reported unverified
validator exit=0

Ran 27 tests in 0.029s

OK

Ran 79 tests in 0.372s

OK

The three UNVERIFIED notices are expected and non-fatal: one is corpus-agents' own pre-existing provenance entry, and two are this node's — the single permitted commit-only revision FACT, and the git ls-tree tool-result citation behind the merge-target claim (no openable file can evidence a file's absence from another branch).

Merge-order proof (prompted by #1488 defect B). AGENTS.md step 9 covers relationships to unmerged nodes but says nothing about bare-path citations to them, which carry the identical hazard. Run with the negative control, because the control is what makes the result mean anything:

### TEST 1 — node alone on a bare origin/launchpad (AGENTS.md unmerged)
exit=1
FAIL  corpus-standard-deprecation: evidence entry 13, citation 1: does not resolve to a real file in the repository
FAIL  corpus-standard-deprecation: evidence entry 18, citation 1: does not resolve to a real file in the repository
FAIL  2 corpus validation error(s)

### TEST 2 — NEGATIVE CONTROL: same node, the two AGENTS.md citations swapped for a file that IS on launchpad
exit=0
PASS  corpus validation found no errors; 2 item(s) reported unverified

### TEST 3 — THE ACTUAL PR MERGE RESULT: origin/launchpad + this whole branch
merged cleanly
exit=0
PASS  corpus validation found no errors; 3 item(s) reported unverified

Test 3 decides it: this branch carries AGENTS.md, so the merge result resolves both citations whichever of #1462 or this PR lands first. Test 1 shows the node is not portable to a bare launchpad on its own, which is the disclosed stacking dependency, and test 2 shows the check discriminates rather than passing for unrelated reasons.

The document's central negative claims were verified by experiment, not by reading:

=== PROBE 1  active --depends-on--> deprecated, --references--> retired
PASS  corpus validation clean
exit=0

=== PROBE 2  CONTROL: identical corpus, all three active
PASS  corpus validation clean
exit=0

=== PROBE 3  retired target present vs FILE DELETED
PASS  corpus validation clean
exit(present)=0
FAIL  probe-new: relationship target 'probe-old' does not match any known node id
FAIL  1 corpus validation error(s)
exit(deleted)=1

=== PROBE 4  status outside the enum
FAIL  probe-status: schema violation at status: failed 'enum' constraint
      (schema requires: ["draft", "active", "deprecated", "retired", "flagged"])
exit=1

Probe 1 against its control (probe 2) is what establishes that no code branches on the status value. Probe 3 is the delete-vs-status-change asymmetry the whole policy rests on. Probe 4 is why the document does not claim "nothing reads status" — the cross-model reviewer proved that phrasing false, and it was corrected.

Front-matter self-checks, run as a script against the committed file:

(a) bare-path citations: 22  missing: none
(b) commit-only evidence entries: 1
(c) 'relationships:' key present: False
STEP1-GATE: PASS
  • 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

The cross-model gate ran and returned REQUEST_CHANGES; its re-check of the fixes did not run. Codex (gpt-5.6-sol) completed a full pass and raised three Medium findings — a false central claim, a self-contradiction about authority, and two unledgered body claims. All three were fixed. Codex was then asked to confirm the fixes closed its findings, and that confirmation run died on credit exhaustion (#1467) before reporting on any of them. A same-vendor review-final pass was run as an explicitly labelled stand-in and found that all three fixes had corrected the named instance but not swept the class; those sweeps are the last commit. No different model has checked the current state of this branch. Treat the cross-model gate as run-once-and-not-reconfirmed, not as discharged.

Beyond that:

  • No node has ever actually been deprecated or retired in this corpus. Every rule is written against the mechanism, not against a retirement anyone has performed. The mechanism is verified; the procedure is untested end to end.
  • Whether any reader ever sees status is unknown. The claim that a retired node keeps silently receiving traffic assumes generated views and readers that do not exist yet (task: document corpus standard for generated content #1316 owns generation, task: document README.md #639 the human entry point). What is verified is narrower: no check branches on which value the field holds.
  • The deprecated/retired split is unratified. Not reviewed against task: document corpus standard for status #1323, which owns the status field, because that node does not exist yet. If task: document corpus standard for status #1323 defines these values differently, it wins.
  • No SDD progress ledger exists for this plan, though the sibling task-639 worktree has one. The build-change skill version used here ships no record-step.sh. All four done when conditions were re-verified by hand by review-final and hold; the gap is record-keeping, not an ungated step.
  • The evidence ledger's FACTs were checked by me and by three reviewers opening the cited files, but nothing automated can check them. The validator confirms a path resolves and never opens the file. That gap is now task: nothing checks the corpus front-matter conventions AGENTS.md says no check will raise #1492.
  • I did not verify the node renders in any viewer — no corpus renderer exists.

Security implications

None. The change adds two Markdown documents and no executable code, no configuration, no credentials, no hostnames and no CI surface. It does not alter what the validator checks or how it runs.

Escalations

  • task: the deprecation standard and AGENTS.md carry two authored copies of the retirement procedure #1481 — the deprecation standard and AGENTS.md carry two authored copies of the retirement procedure. Raised by review-code at Low, confirmed by review-adjudicate at Medium. Deferred: resolving it needs an ownership ruling and an edit to AGENTS.md, which this branch may not touch. The node discloses the overlap instead of claiming it links out. Its evidence was corrected mid-task once a whitespace-insensitive comparison found five shared runs rather than the two first reported.
  • task: nothing checks the corpus front-matter conventions AGENTS.md says no check will raise #1492 — nothing checks the front-matter conventions AGENTS.md says no check will raise: the one-commit-only-FACT rule, a floor on real citations, and merge-target citation resolution. Raised by Codex at Low, recommended for filing by review-final because it compounds across ~45 sibling nodes rather than affecting this one.
  • bug: three more defects in the corpus AGENTS.md create procedure, found by following it literally on #1312 #1488 changed what I did. Its defect B — that AGENTS.md step 9 covers relationships but not bare-path citations — is why the merge-order proof above exists with a negative control rather than as an assertion. Its defect C is why the ledger was reconciled against the finished body after the last round of edits, which is how the duplication measurement's missing entry was found.
  • Merge order is a hard dependency. This PR must not be squashed or cherry-picked in a way that separates the node from AGENTS.md; test 1 above shows what that costs.
  • Two review-plan findings were fixed in the plan before anything was built, rather than filed: a done when that a passing run could satisfy vacuously, and no mechanical check for the "exactly one commit-only FACT" convention. Both now have thresholds.
  • I have not reviewed my own work, and I did not approve any of the reviews that ran against it.

…ent (#1311)

Adds launchpad/docs/corpus/standards/deprecation.md, node id
corpus-standard-deprecation: the path from active through deprecated to
retired, what each status obliges an author to do, and what a reader
arriving at a non-active node is owed.

The mechanism the whole policy rests on: the validator resolves a
relationship target against the ids of the nodes it LOADED, and it loads
by walking the corpus tree for Markdown files. Deleting a node's file
therefore breaks every inbound edge, while a status change breaks none.
Verified in a scratch corpus with --root, both directions.

The same property makes the policy unenforceable. Nothing reads a node's
status -- enum membership at schema validation is the only check made on
the field anywhere -- so deprecated and retired are a distinction no tool
holds. An active node declaring depends-on a deprecated node and
references a retired one validates byte-identically to a control corpus
where all three are active. The document says so plainly rather than
implying a green run means more than it does.

No source in this repository defines what deprecated or retired mean; the
schema and its README explain flagged only. The MUST and SHOULD lists are
therefore stated as this node's own rules with no external authority,
rather than attributed to the issue that asked for them -- AGENTS.md's
current wording rules out parking a decision you made yourself in
TEAM_KNOWLEDGE, so the honest move is to make the claim visibly unsourced
and name the mechanism behind each rule instead.

No relationships, for merge order rather than an empty corpus: the merge
target carries no node outside the excluded schema/ subtree. That same
dependency covers the one evidence entry citing AGENTS.md by path, which
would fail on launchpad ahead of the branch introducing that file --
the hazard a sibling filed as #1473, disclosed here rather than left
implicit.

Also adds the plan.

Plan: launchpad/plans/2026-08-26-issue-1311-corpus-standard-deprecation.md
Refs #605

Signed-off-by: Serina Mcfall <serina.mcfall@gmail.com>
…ure (#1311)

review-adjudicate confirmed at Medium that every MUST in this node maps onto a
step of AGENTS.md's "Retiring a node", two of them close to verbatim -- while
the node's own scope table told a reader it links that procedure rather than
restating it. The duplication is a real problem for a corpus whose ADR-0028
premise is one canonical source, and nothing detects it: the validator never
reads body prose, so two contradicting copies of a policy validate as cleanly
as one.

Deciding which document owns the retirement procedure needs a coordinated edit
across both, and editing AGENTS.md is out of scope here, so the duplication
itself is filed as #1481 rather than resolved.

WHAT CHANGED: the node stops claiming it does not restate. The table row names
the overlap, and a note under it says the corpus carries the policy twice, that
the two must be edited together until #1481 rules on ownership, and that no
check will catch them drifting apart.

This is disclosure, not resolution -- it makes an inaccurate sentence accurate
without deciding the ownership question that is #1481's.

Refs #605, #1481

Signed-off-by: Serina Mcfall <serina.mcfall@gmail.com>
Codex (gpt-5.6-sol) returned REQUEST_CHANGES with three Mediums, two of them
false statements this node made about itself and one a violation of AGENTS.md's
own evidence rule. All three are Definition-of-Done failures rather than
improvements, so they are fixed here rather than filed.

1. "The validator never reads a node's status" was FALSE, and it was the
   document's most load-bearing claim. Schema validation does read the field:
   status: obsolete fails with an enum violation and exit 1, which the reviewer
   reproduced. The true claim is narrower -- no code branches on WHICH legal
   value the field holds. The section now says that, names the failing probe,
   and the matching evidence entry drops "never read" for the same reason.

2. The authority table said the MUST and SHOULD lists are backed by "this node,
   and nothing else" while the paragraph below it disclosed that every MUST
   restates AGENTS.md's retirement procedure. Both could not be true. The MUSTs
   do have an authority -- AGENTS.md -- and what is genuinely unsourced is the
   deprecated/retired distinction and the SHOULD guidance, because no source in
   the repository defines what either status means. The table now splits the two
   and says where each is checkable.

3. Two substantive body claims had no ledger entry, which AGENTS.md requires and
   no check enforces: the currency semantics separating depends-on from
   references, and duplicate-id detection. Both now have FACT entries, and both
   cite a source that genuinely establishes them -- relationshipMeta's
   directionality strings and find_duplicate_ids respectively.

Also corrects this node's own duplication disclosure, which said "two of them
close to verbatim" of the MUSTs. Whitespace-insensitive comparison finds four
shared phrases, only two inside the MUST list; both documents are hard-wrapped,
so a naive grep misses them. #1481 has been corrected with the same evidence.

The reviewer's fourth finding (Low) is recorded, not fixed: it reports the STEP 2
transcripts missing from scratchpad/i1311/, but that path is the SESSION
scratchpad, which the reviewer's sandbox cannot see and which must not be written
into the repository tree. review-adjudicate refuted the identical finding from
review-code earlier. Its second half -- that no reusable front-matter checker is
committed -- is real and out of scope for one document.

Front-matter gate after the change: 20 bare-path citations, all resolving; one
commit-only FACT; no relationships key. Validator exit 0; 79 + 27 tests OK.

Refs #605, #1481

Signed-off-by: Serina Mcfall <serina.mcfall@gmail.com>
…1311)

A same-vendor review-final pass, run because the cross-model gate's confirmation
died on credits, found that all three earlier fixes corrected the instance they
were raised against and not the class. That is the failure mode a same-vendor
reviewer is worst at catching, so it is worth naming: the sweep, not the
sentence, was the deliverable.

1. "no check reads the field" survived in two more places after the previous
   commit corrected the section it was raised in -- including under "Expected but
   not verified", the sentence that tells a reader what WAS established. Both now
   say no check branches on WHICH value the field holds. Swept: no occurrence of
   the false phrasing remains in either file.

2. The authority table still credited the whole SHOULD list to "this node, and
   nothing else" while SHOULD 2 restates AGENTS.md's step 3. #1481, filed by the
   commit that wrote the table, already recorded that SHOULD 2 is a restatement --
   so the document and its own issue disagreed. The table now splits SHOULD 2 out.

3. The duplication measurement -- the most falsifiable claim in the document --
   had no ledger entry, which is exactly the omission finding 3 asked to sweep
   for. It now has one, plus entries for the validator never reading body prose
   and for the #1481/#1473 cross-references.

Also: the phrase count was still low (five shared runs, not four; MUST 6 matches
the AGENTS.md *Updating a node* section rather than the retirement one, so entry
18 now says "retiring or updating"); adding the duplication entry made the
AGENTS.md citation count two, so the prose saying "One evidence entry cites" is
corrected again; the excluded `developer` audience is now disclosed rather than
silently decided; and the plan's ALREADY TRUE block, a committed artefact a
future agent reads, no longer asserts the claim the gate refuted.

MERGE-ORDER PROOF, prompted by #1488 defect B. AGENTS.md step 9 covers
relationships to unmerged nodes but says nothing about bare-path CITATIONS to
them, which carry the identical hazard. Three-way check with the negative control
that makes it worth anything:

  1. this node alone on a clean origin/launchpad -> exit 1, failing on exactly
     the two AGENTS.md citations (entries 13 and 18)
  2. control, same node with those two citations swapped for a file that IS on
     launchpad -> exit 0, proving the check discriminates
  3. the ACTUAL PR merge result, origin/launchpad + this whole branch -> exit 0

Test 3 is the one that decides it: this branch carries AGENTS.md, so the merge
result resolves both citations whichever of #1462 or this PR lands first. The
citations are kept -- they source the retirement-procedure claims and the
duplication measurement -- and the dependency stays disclosed in the body.

Ledger reconciled against the finished body per #1488 defect C. 23 entries, 22
bare-path citations all resolving, one commit-only FACT, no relationships key.
Validator exit 0; 79 + 27 tests OK.

Refs #605, #1481, #1488

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 26, 2026
@serina-mcfall

Copy link
Copy Markdown
Author

CI green on the pushed branch — recorded by the author, not an independent review.

Dead Token Reference Guard  pass   7s
Detect Changed Paths        pass  22s
adr-boundary                pass   8s
audit                       pass  1m11s
check                       pass  22s
scripts                     pass  31s
validate                    pass  10s

validate is the corpus validator, and its passing here confirms the merge-order
prediction in the body: the branch carries AGENTS.md, so both bare-path citations to it
resolve on the merge result. The local three-way test with its negative control is in
Verification.

Still outstanding, and the reason this stays a draft: the cross-model gate returned
REQUEST_CHANGES, its three findings were fixed, and its confirmation run died on credit
exhaustion (#1467) before checking the fixes. Green CI does not speak to that — no check
here reads a node's status, compares a claim against its cited source, or reads body
prose at all. A different model re-checking commits 6489b51b4 and 77466b232 is the
missing signal.

@serina-mcfall serina-mcfall self-assigned this Aug 26, 2026
@serina-mcfall
serina-mcfall marked this pull request as ready for review August 26, 2026 21:08
@tucktuck101 tucktuck101 self-assigned this Aug 26, 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.

Request changes

Medium: MUST 1 doesn't require the retired status

launchpad/docs/corpus/standards/deprecation.md:227 says "Retire by changing `status`" without requiring the retired value, yet the node claims every MUST restates the retire procedure (lines 141,170). An author can change to deprecated and call it retired. Require status: retired in MUST 1, or stop claiming the MUSTs restate AGENTS.md.

Medium: retirement provenance weakened vs the source procedure

:232,240 records the reason+revision only in the body and requires no more than any ledger change. AGENTS.md (retire procedure) requires the reason recorded in the body AND the ledger at the checked revision. Require the reason and checked revision in the evidence ledger too, or declare the intentional divergence.

What looks good

Relationship-resolution and id-permanence guidance are sound.
[panel: fable+codex]

Also unstack after #1462 (same bundled payload).

@tucktuck101 tucktuck101 removed their assignment Aug 26, 2026
…-standard-deprecation

Signed-off-by: Serina Mcfall <serina.mcfall@gmail.com>
…Ts claimed to restate (#1311)

MUST 1 said "changing status" without naming which value, so an author
could set status: deprecated and satisfy the rule while the node's own
table claims every MUST restates AGENTS.md's retire procedure -- which
requires the retired value specifically. Now names it.

MUST 3 recorded the reason only in the body. AGENTS.md's retire step 6
requires it in the body AND the evidence ledger at the checked revision;
MUST 3 now matches.

review-final finding (fable+codex panel), verified against branch head
before fixing: both gaps were still open, confirmed against AGENTS.md's
"Retiring a node" procedure and the schema's status enum.

Signed-off-by: Serina Mcfall <serina.mcfall@gmail.com>
@serina-mcfall

Copy link
Copy Markdown
Author

Round-2 findings addressed

Both verified against branch head (77466b232, which predated this review) before fixing — neither was already closed.

  • Medium (MUST 1 doesn't require the retired status): MUST 1 now says "setting status to retired" explicitly, and states that changing to deprecated is a different obligation under this page, not retirement — matching AGENTS.md's Retiring a node step 1 ("Set status to the retired value").
  • Medium (retirement provenance weaker than the source procedure): MUST 3 now requires the reason recorded in the body and the evidence ledger at the checked revision, matching AGENTS.md step 6 ("Record why, in the body and in the ledger, at the revision you checked").

Merged origin/launchpad in (clean, no conflicts — AGENTS.md is byte-identical across branches). Validator passes clean (0 errors, 6 unverified/expected); full test suite green (79 tests).

Fixed at 0c4f2bb74. Requesting re-review.

@serina-mcfall
serina-mcfall dismissed tucktuck101’s stale review August 27, 2026 22:45

Fixed since this review by follow-up commit 0c4f2bb: MUST 1 now requires setting status to retired specifically, and MUST 3 now requires provenance in both the node body and the evidence ledger. Verified directly against current text. Dismissing as stale/resolved.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Reviewed commit 8eef887443f0ea0acf6e203f55bb8c0f917083dc against merge base dea96f837690703b1298ab3f0e49e1b82fecb8cf.

Incomplete

This review is INCOMPLETE and must not be read as a full pass:

  • no dimension was actually reviewed: the pipeline ran the 'default_reviewer' stub reviewer, which reports every dimension clean without reading it (a real dimension reviewer is #116)

Containment

No containment findings.

Fetched and empty: pr_review_comments.

Automated containment covers the delimiter boundary and unambiguous injection tells only. It does not cover injection phrased as ordinary, unremarkable prose. The absence of a containment finding is not evidence that this pull request contains no injection attempt.

@tucktuck101
tucktuck101 merged commit 7ba134b into launchpad Aug 28, 2026
25 checks passed
@serina-mcfall
serina-mcfall deleted the task/1311-corpus-standard-deprecation branch August 31, 2026 20:25
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 deprecation

2 participants