Filed from #3473 so the deliberate exclusions survive the squash. Each was found during the relay-boundary work, judged out of scope for that PR, and is recorded here rather than left in a commit message.
None is a leak. The boundary in #3473 is verified in both directions: 45 adversarial vectors, and a suite grown from 110 assertions to 385, with the survive-direction coverage it previously had none of.
1. An ambiguous tier list is withheld and can refuse the sidecar
{"tier": ["fingerprint-confirmed", "not-found"]} is withheld, and refused at exit 3 when it names no searched surfaces. The value half cannot distinguish it from the ["not-found"] evasion that an earlier round closed without reopening that vector.
Asserted as a stated limit (survive-ambiguous), so it is visible rather than silent. The fix, if wanted, is a rule for what a record declaring two tiers means — which is a spec question, not a reader question.
2. Letter homoglyphs beyond the dash class
All five recognized names are hyphenated, so hyphen-likes fold to ASCII by the dash class. Going further means a confusables table (Cyrillic о → Latin o and the rest), which jq has no access to and which would itself become "a list of the code points someone thought of" — the failure mode that leaked four consecutive rounds.
The blast radius is bounded: since 7b05e0ca, an unreadable declared tier cannot reach a relay row on any rule, including the stamp rules. Such a record takes ## Unparsed or the not-relay-eligible count, both visible, and review:fanout never auto-classifies ## Unparsed.
Optional wording refinement. context/persist-findings.md currently frames the goal as rendering-equivalence and then carves out the exception. The text is honest — it says the reader "pursues that", and calls the limit "stated, not closed" — but framing a goal invites the next reader to falsify the frame. Stating the mechanism first and naming rendering-equivalence as the motive it approximates would be marginally more accurate.
3. source-not-identified versus not-found
SKILL.md:2 publishes the neutral tier as source-not-identified; everything else — rubric.md, persist-findings.md, the script's prose — says not-found. The reader now recognizes both spellings, deliberately and permanently: recognizing one name too many can only withhold a record, which is visible and counted, while recognizing one too few relays a judgment verdict. The tolerance is free and should stay.
What remains is reconciling the published name. SKILL.md:2 is the only place the divergent spelling appears, so the rename is cheap and one-directional. The argument for keeping source-not-identified as the published name: it says what was not identified, where not-found is ambiguous about what was not found. The defect is the divergence, not either name.
4. Duplicate case-folded keys
{"tier": "a", "Tier": "b"} — jq is last-wins, and the raw record text is unchanged, so a first-wins consumer reading the JSON directly could disagree with the reader. Not a boundary hole; noted for completeness.
5. A test case reports SKIP as a pass under uid 0
emit-findings.test.sh's unwritable-destination case cannot exercise its condition when running as root, and self-labels the skip in its message. Pre-existing, honest about itself, left alone.
Related
Filed from #3473 so the deliberate exclusions survive the squash. Each was found during the relay-boundary work, judged out of scope for that PR, and is recorded here rather than left in a commit message.
None is a leak. The boundary in #3473 is verified in both directions: 45 adversarial vectors, and a suite grown from 110 assertions to 385, with the survive-direction coverage it previously had none of.
1. An ambiguous tier list is withheld and can refuse the sidecar
{"tier": ["fingerprint-confirmed", "not-found"]}is withheld, and refused at exit 3 when it names no searched surfaces. The value half cannot distinguish it from the["not-found"]evasion that an earlier round closed without reopening that vector.Asserted as a stated limit (
survive-ambiguous), so it is visible rather than silent. The fix, if wanted, is a rule for what a record declaring two tiers means — which is a spec question, not a reader question.2. Letter homoglyphs beyond the dash class
All five recognized names are hyphenated, so hyphen-likes fold to ASCII by the dash class. Going further means a confusables table (Cyrillic
о→ Latinoand the rest), whichjqhas no access to and which would itself become "a list of the code points someone thought of" — the failure mode that leaked four consecutive rounds.The blast radius is bounded: since
7b05e0ca, an unreadable declared tier cannot reach a relay row on any rule, including the stamp rules. Such a record takes## Unparsedor the not-relay-eligible count, both visible, andreview:fanoutnever auto-classifies## Unparsed.Optional wording refinement.
context/persist-findings.mdcurrently frames the goal as rendering-equivalence and then carves out the exception. The text is honest — it says the reader "pursues that", and calls the limit "stated, not closed" — but framing a goal invites the next reader to falsify the frame. Stating the mechanism first and naming rendering-equivalence as the motive it approximates would be marginally more accurate.3.
source-not-identifiedversusnot-foundSKILL.md:2publishes the neutral tier assource-not-identified; everything else —rubric.md,persist-findings.md, the script's prose — saysnot-found. The reader now recognizes both spellings, deliberately and permanently: recognizing one name too many can only withhold a record, which is visible and counted, while recognizing one too few relays a judgment verdict. The tolerance is free and should stay.What remains is reconciling the published name.
SKILL.md:2is the only place the divergent spelling appears, so the rename is cheap and one-directional. The argument for keepingsource-not-identifiedas the published name: it says what was not identified, wherenot-foundis ambiguous about what was not found. The defect is the divergence, not either name.4. Duplicate case-folded keys
{"tier": "a", "Tier": "b"}—jqis last-wins, and the raw record text is unchanged, so a first-wins consumer reading the JSON directly could disagree with the reader. Not a boundary hole; noted for completeness.5. A test case reports SKIP as a pass under uid 0
emit-findings.test.sh's unwritable-destination case cannot exercise its condition when running as root, and self-labels the skip in its message. Pre-existing, honest about itself, left alone.Related