feat(linkedin-studio): short-form de-AI gate via differentiation-checker + voice-guardian

Wire the orphan differentiation-checker (#10) into the five short-form
creation commands (post/quick/react/carousel/video) as a De-AI /
Differentiation Gate at each command's quality-check step: confirm the
LinkedIn-named substance signals (personal substance, original thinking,
concrete specifics, genuine voice) + a soft engagement-bait check, and
delegate an originality pass to linkedin-studio:differentiation-checker
when the angle risks commodity content. Add Task to allowed-tools in
quick/react/carousel (post/video already had it from Step 13).

Extend (not duplicate) hooks/prompts/voice-guardian.md's AI-pattern
section with the same named signals from research/01 D8 + research/03 D4.
Runtime-loaded prompt — no compile-hooks.py, no hooks.json change
(verified: compile-hooks --check reports no drift).

Test: new hooks/scripts/__tests__/linkedin-content-filter.test.mjs pins
the content/non-content boundary the gate is scoped by (14 tests).
Full hook suite 76/76, structure lint 61/61.

Plan Step 14 (Wave 4 S2). Counts unchanged (26 commands / 19 agents).
[skip-docs]: tre-doc + version bump deferred to Step 21 per remediation plan.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-05-30 02:31:41 +02:00
commit e2ed3eb0aa
7 changed files with 131 additions and 0 deletions

View file

@ -12,6 +12,7 @@ allowed-tools:
- Bash
- AskUserQuestion
- mcp__mcp-image__generate_image
- Task
---
<!-- MCP_IMAGE_TEXT_OVERLAY: VERIFIED -->
<!-- MERMAID_CHART_RESOLUTION: UNTESTED -->
@ -117,6 +118,12 @@ Run against the Carousel Quality Checklist from `carousel-templates.md`:
If any item fails, fix before presenting.
### De-AI / Differentiation Gate
The caption is the feed text, and it rides the same low-substance down-rank LinkedIn confirmed. Confirm the caption and cover slide carry the signals LinkedIn named — **personal substance, original thinking, concrete specifics, genuine voice** — and use no mechanical-response engagement bait ("Comment YES", "Like for Part 2"); a genuine question is fine. (The voice-guardian hook scores the caption on save.)
If the deck's premise is a list the audience has seen many times — commodity content — delegate an originality pass to the `differentiation-checker` agent: invoke it via `Task` with `subagent_type: linkedin-studio:differentiation-checker` (foreground, from this command layer), then sharpen the angle before generating slides.
## Step 5.5: Generate Slide Images
Generate a visual for each slide using mcp-image (Nano Banana Pro). If mcp-image is unavailable or fails, skip this step — the command degrades gracefully to text-only output with a manual design guide.

View file

@ -134,6 +134,12 @@ Before presenting, verify against `assets/checklists/quality-scorecard.md`:
- [ ] Topic aligns with user's 5 core expertise areas
- [ ] Passes thought leadership test (helps someone decide or think differently)
### De-AI / Differentiation Gate
LinkedIn reach-suppresses low-substance AI content (officially confirmed — down to first-degree connections, not deleted). Confirm the draft carries the signals LinkedIn named — **personal substance, original thinking, concrete specifics, genuine voice** — and uses no mechanical-response engagement bait ("Comment YES", "Like for Part 2"); a genuine question is fine. (The voice-guardian hook scores this automatically on save.)
If the angle risks being commodity content — a take the audience has seen many times — delegate an originality pass to the `differentiation-checker` agent: invoke it via `Task` with `subagent_type: linkedin-studio:differentiation-checker` (foreground, from this command layer), then apply its angle suggestions before presenting.
## Step 6: Present Draft
Present ONE draft with:

View file

@ -14,6 +14,7 @@ allowed-tools:
- Read
- Bash
- AskUserQuestion
- Task
---
# Quick LinkedIn Post (5-Minute Workflow)
@ -144,6 +145,10 @@ Create the post, then verify:
**All 6 = Yes? -> Ready to post.**
### De-AI / Differentiation Gate (fast)
Even quick posts ride the low-substance down-rank LinkedIn confirmed. Confirm one concrete specific plus a genuine point of view (not generic advice), and no mechanical-response bait ("Comment YES", "Like for Part 2") — a real question is fine. (The voice-guardian hook scores this on save.) Only when the take feels like commodity content does an originality pass earn its time: delegate to the `differentiation-checker` agent via `Task` with `subagent_type: linkedin-studio:differentiation-checker` — otherwise keep the 5-minute promise and skip it.
## Step 6: Present Draft
Show the post with:

View file

@ -14,6 +14,7 @@ allowed-tools:
- WebFetch
- Bash
- AskUserQuestion
- Task
---
# React to External Content — URL-to-Post Pipeline
@ -126,6 +127,12 @@ Verify against quality rules:
- [ ] Topic aligns with expertise areas
- [ ] CTA invites discussion, not just "What do you think?"
### De-AI / Differentiation Gate
A reaction still has to add something only you can. Confirm the draft carries the signals LinkedIn named — **personal substance, original thinking, concrete specifics, genuine voice** — and uses no mechanical-response engagement bait ("Comment YES", "Like for Part 2"); a genuine question is fine. (The voice-guardian hook scores this on save.)
If your take echoes the source instead of extending it — commodity reaction — delegate an originality pass to the `differentiation-checker` agent: invoke it via `Task` with `subagent_type: linkedin-studio:differentiation-checker` (foreground, from this command layer), then sharpen the angle before presenting.
## Step 7: Present Draft
Show:

View file

@ -121,6 +121,12 @@ Before presenting, verify the script passes the video quality gate:
- [ ] Topic aligns with expertise pillars
- [ ] No external links in post caption
### De-AI / Differentiation Gate
The post caption rides the same low-substance down-rank LinkedIn confirmed for text. Confirm the script's core idea and caption carry the signals LinkedIn named — **personal substance, original thinking, concrete specifics, genuine voice** — and use no mechanical-response engagement bait ("Comment YES", "Like for Part 2"); a genuine question is fine. (The voice-guardian hook scores the caption on save.)
If the idea is a take the audience has seen many times — commodity content — delegate an originality pass to the `differentiation-checker` agent: invoke it via `Task` with `subagent_type: linkedin-studio:differentiation-checker` (foreground, from this command layer), then sharpen the angle before presenting.
## Step 6: Present the Script
Present using the standardized output format: