Problem
load_retired_wording_literal_keys in lib/test/pin-corpus-lint.py keys retirement by literal, while RevivalAuthorization is keyed by site. The two do not line up.
The retired rows are assert_pin_red_on_removal meta-assertions ("…pin is removal-proof/removal-sensitive") that issue #810 retired as redundant_retire — redundant with the assert_pin_unique pins they were written about. Those subject pins survive and are boundary in the live ledger, and 6 of the 7 distinct literals additionally carry an explicit RETAIN_BOUNDARY row in the frozen residual-prose manifest.
Because retirement collapses to a literal key, a redundant_retired twin now poisons the retained pin that shares its literal.
Evidence
Surfaced by PR #1005 (issue #1002), where 8 of 43 gate findings landed in this class. Confirmed end to end rather than by code reading: in a throwaway worktree the retained pin at lib/test/run.sh:2653 was given the full authorization — a valid # structural-pin-ok: declaration, an exact retired-pin-revivals.tsv row, and a same-branch boundary ledger change recorded in a new bundle — committed, and the gate still reported it:
MUTATION-ROUTING lib/test/run.sh:2653 assert_pin_unique A reception pass that pushes uses an explicit destination ref literal resolves into prose at .prflow/prompt-extensions/receiving-code-review.md:135; the assert_pin_unique helper does not change the verdict
The message carries no remediation clause — there is no further step available. That is deliberate and tested: test_a_retired_literal_keeps_the_pre_948_revival_contract asserts precisely that a fully-authorized revival of a prose-target retired literal is still reported.
The same frozen manifest records 'prefer mutation evidence…' as RETAIN_BOUNDARY at one home and RETIRE_PROSE at another — direct evidence that the manifests record site dispositions that the retirement set collapses to literal keys.
Why this matters beyond that PR
This is latent for any branch that touches those lines, rename or not. A contributor who edits one of those assert_pin_unique sites for an ordinary reason inherits an unsatisfiable gate finding with no documented exit.
Desired behaviour
Decide whether load_retired_wording_literal_keys should key on site identity (source_file + helper + literal — which the manifests already record) rather than on the literal alone, and either implement that or record why the literal-level collapse is correct and what the exit is for a retained subject pin that shares a retired twin's literal.
Not in scope
Re-adjudicating any individual pin. This is about the keying, not about the verdicts.
Decision (2026-07-31): key retirement on SITE identity
The issue asks the maintainer to decide between site-keying and recording why the literal-level collapse is correct. Measurement settles it in favour of site-keying, so this is now decided rather than open.
The evidence
- The two keying schemes are structurally asymmetric in the code, not merely in effect.
RevivalAuthorization is a NamedTuple carrying full site identity — source_path, family, helper, literal_key, target_path, plus the structural category and rationale. load_retired_wording_literal_keys returns a bare set() of literals. The site information exists on one side and is discarded on the other.
- The manifests already record conflicting dispositions for the same literal at different homes. An executed scan over the frozen manifests finds 2 literals carrying both
RETAIN_BOUNDARY and RETIRE_PROSE. Literal-keying is therefore not a simplification of equivalent data — it is lossy, and it discards exactly the distinction the manifests were written to record.
- The failure it produces has no exit. The reported finding carries no remediation clause, and
test_a_retired_literal_keeps_the_pre_948_revival_contract asserts that a fully authorized revival — valid # structural-pin-ok: declaration, exact retired-pin-revivals.tsv row, same-branch boundary ledger change in a new bundle — is still reported. A contributor who edits one of those assert_pin_unique sites for an ordinary reason inherits an unsatisfiable gate.
An unsatisfiable gate with no documented exit is strictly worse than either alternative, and the data needed to fix it is already recorded. Hence the decision.
What must NOT change
This is a keying fix, not a loosening. Re-adjudicating any individual pin stays out of scope (as the issue already states), and the fix must not become a way to revive a genuinely retired literal:
- A literal retired at a given site stays retired at that site. Site-keying narrows which sites a retirement covers; it must never turn a retirement into a no-op.
- The existing authorization requirements are unchanged — a revival still needs its declaration, its ledger row, and its bundle. This changes what the gate matches, not what it demands.
test_a_retired_literal_keyed_...'s intent is preserved for the case it was written about: a retired literal at its own site still reports, fully authorized or not.
Acceptance Criteria
Not in scope
Re-adjudicating individual pins (unchanged from above). #1007 sits behind this and is not addressed here.
Problem
load_retired_wording_literal_keysinlib/test/pin-corpus-lint.pykeys retirement by literal, whileRevivalAuthorizationis keyed by site. The two do not line up.The retired rows are
assert_pin_red_on_removalmeta-assertions ("…pin is removal-proof/removal-sensitive") that issue #810 retired asredundant_retire— redundant with theassert_pin_uniquepins they were written about. Those subject pins survive and areboundaryin the live ledger, and 6 of the 7 distinct literals additionally carry an explicitRETAIN_BOUNDARYrow in the frozen residual-prose manifest.Because retirement collapses to a literal key, a
redundant_retired twin now poisons the retained pin that shares its literal.Evidence
Surfaced by PR #1005 (issue #1002), where 8 of 43 gate findings landed in this class. Confirmed end to end rather than by code reading: in a throwaway worktree the retained pin at
lib/test/run.sh:2653was given the full authorization — a valid# structural-pin-ok:declaration, an exactretired-pin-revivals.tsvrow, and a same-branchboundaryledger change recorded in a new bundle — committed, and the gate still reported it:The message carries no remediation clause — there is no further step available. That is deliberate and tested:
test_a_retired_literal_keeps_the_pre_948_revival_contractasserts precisely that a fully-authorized revival of a prose-target retired literal is still reported.The same frozen manifest records
'prefer mutation evidence…'asRETAIN_BOUNDARYat one home andRETIRE_PROSEat another — direct evidence that the manifests record site dispositions that the retirement set collapses to literal keys.Why this matters beyond that PR
This is latent for any branch that touches those lines, rename or not. A contributor who edits one of those
assert_pin_uniquesites for an ordinary reason inherits an unsatisfiable gate finding with no documented exit.Desired behaviour
Decide whether
load_retired_wording_literal_keysshould key on site identity (source_file+helper+literal— which the manifests already record) rather than on the literal alone, and either implement that or record why the literal-level collapse is correct and what the exit is for a retained subject pin that shares a retired twin's literal.Not in scope
Re-adjudicating any individual pin. This is about the keying, not about the verdicts.
Decision (2026-07-31): key retirement on SITE identity
The issue asks the maintainer to decide between site-keying and recording why the literal-level collapse is correct. Measurement settles it in favour of site-keying, so this is now decided rather than open.
The evidence
RevivalAuthorizationis aNamedTuplecarrying full site identity —source_path,family,helper,literal_key,target_path, plus the structural category and rationale.load_retired_wording_literal_keysreturns a bareset()of literals. The site information exists on one side and is discarded on the other.RETAIN_BOUNDARYandRETIRE_PROSE. Literal-keying is therefore not a simplification of equivalent data — it is lossy, and it discards exactly the distinction the manifests were written to record.test_a_retired_literal_keeps_the_pre_948_revival_contractasserts that a fully authorized revival — valid# structural-pin-ok:declaration, exactretired-pin-revivals.tsvrow, same-branchboundaryledger change in a new bundle — is still reported. A contributor who edits one of thoseassert_pin_uniquesites for an ordinary reason inherits an unsatisfiable gate.An unsatisfiable gate with no documented exit is strictly worse than either alternative, and the data needed to fix it is already recorded. Hence the decision.
What must NOT change
This is a keying fix, not a loosening. Re-adjudicating any individual pin stays out of scope (as the issue already states), and the fix must not become a way to revive a genuinely retired literal:
test_a_retired_literal_keyed_...'s intent is preserved for the case it was written about: a retired literal at its own site still reports, fully authorized or not.Acceptance Criteria
load_retired_wording_literal_keys(or its replacement) keys retirement on site identity —source_file+helper+literal— drawn from the same manifest fieldsRevivalAuthorizationalready carries, rather than on the literal alone.boundarypin that merely shares a literal with aredundant_retired twin at a different site is no longer reported, driven end-to-end (the PR PRFlow rename Tier 1: atomic directory/vendored-path/config-key/workflow-body migration + /prflow:init #1005 reproduction: the retained pin at theassert_pin_uniquesite with a full authorization) rather than asserted by code reading.RETAIN_BOUNDARYandRETIRE_PROSEare each resolved to the disposition recorded for their site, and both are covered by a test.lib/test/run.shreports zero failures and zero skips.Not in scope
Re-adjudicating individual pins (unchanged from above). #1007 sits behind this and is not addressed here.