The de-niche sweep (B-S1/B-S2) stripped the hardcoded KTG beat
(Microsoft|Azure|Copilot|public sector|offentlig sektor) from three surfaces,
but §17 only locked agents/trend-spotter.md against its return. Generalize the
guard to the full de-niched set so a beat token cannot creep back into the
other two:
- agents/trend-spotter.md (B-S1)
- agents/content-planner.md (B-S2a)
- references/content-framework.md (B-S2a)
Single shared NICHE_TOKENS criterion + non-vacuity/false-positive self-test
(unchanged shape), then a per-file grep loop over the explicit allowlist.
Scoped per file BY DESIGN, not tree-wide: references/content-angles.md keeps
"Public Sector" as 1 of 6 example industry tables (a KEEP surface — generic
illustration, not a beat) and is deliberately NOT guarded; "AI" is the plugin's
own subject, not a niche token. Added an "AI-driven content planning ..."
negative probe to lock that in (self-test now 5 caught / 6 ignored).
Non-vacuity proven by injection: a beat token appended to each new file makes
the guard fail naming the file+line; reverts clean. Gate 87→89/0/0 (+2 file
checks; assertion-count floor §18 still satisfied).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RigJBiRFNtFZKCz21qNbQ4