feat(linkedin-studio): extend §17 de-niche guard to content-planner + content-framework (B-S2 follow-up) [skip-docs]
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
This commit is contained in:
parent
e75cd42bed
commit
9f9c4bbd86
1 changed files with 34 additions and 26 deletions
|
|
@ -695,23 +695,28 @@ fi
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# --- Section 17: Trend-Spotter De-Niche Guard (B-S1) ---
|
# --- Section 17: De-Niche Guard (B-S1 + B-S2) ---
|
||||||
echo "--- Trend-Spotter De-Niche ---"
|
echo "--- De-Niche Guard ---"
|
||||||
|
|
||||||
# The trend-spotter agent states its own contract — "the niche lives in the source
|
# The de-niche sweep removed the hardcoded KTG beat (Microsoft / public-sector) from
|
||||||
# list and the user's pillars, never in this agent" (Source Scanning Framework). For
|
# three surfaces so the domain comes from the user's profile/pillars at runtime, never
|
||||||
# that to be true the agent file must name NO specific vendor or sector beat: the
|
# baked in (plugin-is-domain-general):
|
||||||
# domain comes from the user's profile/pillars at runtime, never hardcoded here
|
# - agents/trend-spotter.md (B-S1: pillar-driven scanning; the agent's own
|
||||||
# (plugin-is-domain-general). Pre-B-S1 the file contradicted itself, hardcoding the
|
# contract says "the niche lives in the source
|
||||||
# Microsoft/public-sector beat in its description, mission, trigger table and
|
# list and the user's pillars, never in this agent")
|
||||||
# relevance filter. This guard forbids those KTG-beat proper nouns from returning to
|
# - agents/content-planner.md (B-S2a: planner calendar recast off the beat)
|
||||||
# agents/trend-spotter.md. Scoped to this one agent by design (B-S1); the wider
|
# - references/content-framework.md (B-S2a: recast + renamed from ai-content-framework.md)
|
||||||
# de-niche sweep (B-S2) covers the other surfaces. Non-vacuity self-test mirrors
|
# Each must name NO specific vendor or sector beat; this guard forbids those KTG-beat
|
||||||
# Sections 8/13: the criterion must catch the beat tokens and ignore generic prose
|
# proper nouns from returning to any of them. Scoped per file BY DESIGN: the check runs
|
||||||
# (incl. the content-framework.md reference filename — B-S2a recast + renamed it
|
# against this explicit allowlist, NOT the whole tree, because references/content-angles.md
|
||||||
# from ai-content-framework.md, de-nicheing the file the agent reads).
|
# legitimately lists "Public Sector" as one of six example industry tables (a KEEP surface,
|
||||||
# Case-insensitive: "Public sector" and "public sector" name the same beat, and a
|
# generic illustration — not a hardcoded beat), and "AI" is the plugin's own subject, not a
|
||||||
# future reintroduction could use either case — the positive set locks that in.
|
# niche token. Non-vacuity self-test mirrors Sections 8/13: the criterion must catch the beat
|
||||||
|
# tokens and ignore generic prose (incl. the content-framework.md reference filename — B-S2a
|
||||||
|
# recast + renamed it from ai-content-framework.md — and "AI"-flavoured planner prose, locking
|
||||||
|
# in that "AI" is never treated as a beat). Case-insensitive: "Public sector" and "public
|
||||||
|
# sector" name the same beat, and a future reintroduction could use either case — the
|
||||||
|
# positive set locks that in.
|
||||||
NICHE_TOKENS='Microsoft|Azure|Copilot|public sector|offentlig sektor'
|
NICHE_TOKENS='Microsoft|Azure|Copilot|public sector|offentlig sektor'
|
||||||
TS_SELFTEST_OK=1
|
TS_SELFTEST_OK=1
|
||||||
while IFS= read -r probe; do
|
while IFS= read -r probe; do
|
||||||
|
|
@ -737,20 +742,23 @@ sector milestones in the user's domain
|
||||||
the user's content pillars and expertise areas
|
the user's content pillars and expertise areas
|
||||||
references/content-framework.md
|
references/content-framework.md
|
||||||
major product/model releases
|
major product/model releases
|
||||||
|
AI-driven content planning across the user's pillars
|
||||||
NEGATIVE17
|
NEGATIVE17
|
||||||
if [ "$TS_SELFTEST_OK" -eq 1 ]; then
|
if [ "$TS_SELFTEST_OK" -eq 1 ]; then
|
||||||
pass "trend-spotter de-niche self-test: 5 beat tokens caught (case-insensitive), 5 generic forms ignored"
|
pass "de-niche self-test: 5 beat tokens caught (case-insensitive), 6 generic forms ignored (incl. 'AI' kept as the plugin's own subject)"
|
||||||
else
|
else
|
||||||
fail "trend-spotter de-niche self-test failed — the guard no longer enforces the no-beat criterion"
|
fail "de-niche self-test failed — the guard no longer enforces the no-beat criterion"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
TS_NICHE_HITS=$(grep -niE "$NICHE_TOKENS" agents/trend-spotter.md 2>/dev/null || true)
|
for guarded in agents/trend-spotter.md agents/content-planner.md references/content-framework.md; do
|
||||||
if [ -z "$TS_NICHE_HITS" ]; then
|
NICHE_HITS=$(grep -niE "$NICHE_TOKENS" "$guarded" 2>/dev/null || true)
|
||||||
pass "trend-spotter names no hardcoded vendor/sector beat (domain comes from pillars)"
|
if [ -z "$NICHE_HITS" ]; then
|
||||||
else
|
pass "$guarded names no hardcoded vendor/sector beat (domain comes from pillars)"
|
||||||
fail "trend-spotter hardcodes a vendor/sector beat — generalize to pillar-driven prose:"
|
else
|
||||||
echo "$TS_NICHE_HITS"
|
fail "$guarded hardcodes a vendor/sector beat — generalize to pillar-driven prose:"
|
||||||
fi
|
echo "$NICHE_HITS"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue