test: pin the nine ADR-0020 gate defects that shipped untested

Every defect fixed in f7cc279 was reachable because nothing asserted against it.
The gate had 43 assertions and none of them covered a consumer repo, a non-string
description, an unclosed fence, or the two spec ceilings. Each case below fails
against the pre-fix code and passes against the current one; every one was proved
non-vacuous by mutating a scratch copy of the script and watching the test go red,
independently twice.

The two that mattered most had no fixture anywhere. A consumer repo WITH .git is
the shape the resolver exists to serve, and only the no-.git case had ever been
tested, which is exactly why the blocker was invisible. And ADR-0020 says the
walk-up runs in two passes specifically so a nested .git cannot beat a plugins/
root further up — no fixture had ever placed a .git inside a plugin.

test-adr0020-differential.sh loses _non_adr_hook_error(). It excluded MAX_LINES and
MAX_WORDS from the cross-script comparison on the untested assumption that awk and
splitlines() agree. They do not, and the divergence stayed invisible for exactly as
long as the exclusion stood. The ceilings are now compared like any other rule.

Two existing assertions were repairs, not additions. The skill-improve probe had
been fixed by this very branch, so its iteration permanently took an
assertion-free SKIP that still counted as a pass; both branches now fail loudly and
each names the other file's pin so the two stay in step. And the yaml-none fixture
emitted `---/---`, which never matched the frontmatter pattern at all — it passed on
the bare word "frontmatter", present in both messages, while never reaching the
branch it was named for. Needles throughout that file now name their branch.

Refs: #99
ADR: 0020

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015W3iwF9ncfRZddGBxsMCYi
This commit is contained in:
2026-08-16 19:49:15 +00:00
parent f7cc27908c
commit b0d6d08239
6 changed files with 673 additions and 42 deletions

View File

@@ -332,6 +332,76 @@ EOF
)"
expect "a fenced references/example-file.md does not ERROR" "$F_REF_FENCED" silent
echo ""
echo "--- an UNTERMINATED fence does not blank the rest of the body ---"
# The fenced-block exemptions above all rest on mask_fenced(), and an unclosed
# fence used to run to EOF: everything after it was blanked, so the ERROR-tier
# references/ check and both Gotchas counts silently stopped seeing any of it.
# That is the worst shape a masking bug can take — a stray ``` line, which is a
# typo an author makes while writing the very examples the masking exists for,
# turned the rest of the file invisible and the gate green. Masking may narrow
# what a check reads; it may never delete content from every check at once.
#
# Both suppressed checks are asserted, because they are separate call sites and
# a fix that restored only one would leave the other silent.
F_FENCE_REF="$(make_skill fence-unclosed-ref "$CLEAN_DESC" <<EOF
Here is how it is invoked:
\`\`\`bash
some-command --all
If the caller needs the long form, read references/behind-the-fence.md first.
EOF
)"
expect "an absent references/ pointer after an unclosed fence still ERRORs" \
"$F_FENCE_REF" errors "points at references/behind-the-fence.md"
F_FENCE_GOTCHAS="$(make_skill fence-unclosed-gotchas "$CLEAN_DESC" <<EOF
Here is how it is invoked:
\`\`\`bash
some-command --all
## Common gotchas
- first trap here
- second trap here
- third trap here
- fourth trap here
- fifth trap here
- sixth trap here
- seventh trap here
## Notes
$(filler 200)
EOF
)"
expect "a Gotchas section after an unclosed fence is still counted" \
"$F_FENCE_GOTCHAS" suggests "Gotchas section has 7 entries"
# The control. Closing the fence must still mask, or the fix above would have
# been "stop masking", which re-breaks every false-positive case in this file.
F_FENCE_CLOSED="$(make_skill fence-closed-ref "$CLEAN_DESC" <<EOF
Here is how it is invoked:
\`\`\`bash
some-command --all
\`\`\`
Dispatch tables look like this:
\`\`\`markdown
If X, read references/behind-the-fence.md.
\`\`\`
EOF
)"
expect "control: the same pointer inside a CLOSED fence is still masked" \
"$F_FENCE_CLOSED" silent
echo ""
echo "--- a references/ pointer in a same-line removal context is history, not dispatch ---"
# Narrow on purpose: a live dispatch table never describes its own target as