Horror Vanguard · Parks & Rec Season 5 · gate audit

Why the anti-AI corpus looked like it failed, and the real fix

All 22 reviewer episodes (s5e01–s5e22), diagnosed against the live gate battery.
RESULT: 22 / 22 now GATE: PASS

The headline the gate output hides

The anti-AI corpus check itself never failed. Run in isolation, anti_ai_voice_gate.py returns GATE: PASS, score 0, zero severity-3 hits on all 22 episodes. What was printing GATE: FAIL is the full hv_review_gate_v2.py battery, whose first gate (G1) wraps the anti-AI corpus, so a failure anywhere in the battery reads at a glance like "the anti-AI corpus failed." The failing gates were two downstream checks, and one of them was a bug.

U1 · false positive

Opener "100% duplicate"

The uniqueness gate scans the _outputs/ archive for a matching opener and excluded "self" only by exact path. Each deployed review at public/<route>/index.md collided with its own byte-identical twin at _outputs/<archive>/s5eNN.md, a phantom 100% overlap on every episode.

F1 · real miss

No claims sheet beside the review

The gate needs a sibling index.claims.md (at least 8 verbatim CLAIM/EVIDENCE pairs tied to the transcript). The sheets already existed in _outputs/, they were just never copied next to the deployed HTML, so every review looked un-grounded.

The fix

1 · Root-cause the gate bug. opener_uniqueness() now also skips any archive candidate whose full-text Jaccard vs the draft is at least 0.85, which marks it as the review's own archive copy rather than a distinct episode. The separation is decisive: a self-copy scores 1.0, two different episodes of the same show score ~0.27, and real openers overlap only 0.22 (well under the 0.55 fail line), so a genuinely recycled opener is still caught.

2 · Ship the evidence. Copied the existing s5eNN.claims.md into each route as index.claims.md (all 22) and s5eNN.beats.tsv as index.beats.tsv (12 available). Placing claims also switched on the COVERAGE gate, which passes.

0→22episodes passing the full battery
100%→~21%opener overlap (self-collision gone)
0→588evidence lines now verified vs transcript
1 editgate line changed, no prose rewritten

Before → after, every episode

EpisodeOpener overlapEvidence verifiedWordsVerdict

Proof

$ python3 anti_ai_voice_gate.py check s5e21/index.md
  GATE: PASS   score 0   severity-3 hits 0        # the "corpus" was always clean

$ python3 hv_review_gate_v2.py s5e21/index.md   # BEFORE
  x U1 opener not unique: 100% token-overlap with s5e21.md
  x F1 no claims sheet
  GATE: FAIL

$ python3 hv_review_gate_v2.py s5e21/index.md   # AFTER
  opener uniqueness: 22% overlap | fact grounding: 59 evidence lines verified
  GATE: PASS

deploy → final state: READY
curl /                                   200
curl /horror-vanguard-parks-s5e21        200
curl /horror-vanguard-parks-s5e21/index.md        200
curl /horror-vanguard-parks-s5e21/index.claims.md 200
22/22 hv_review_gate_v2 → GATE: PASS
Gate: ~/Projects/horror-vanguard-tp/hv_review_gate_v2.py · sheets: public/horror-vanguard-parks-s5eNN/index.claims.md · live review: /horror-vanguard-parks-s5e21
🛍️ Get the printable