diff --git a/.okf/build/test-gates.md b/.okf/build/test-gates.md
index 496b0858e..5aebe62b1 100644
--- a/.okf/build/test-gates.md
+++ b/.okf/build/test-gates.md
@@ -866,6 +866,23 @@ found the founding year wrong in eight places because each kept its own copy.
Full fault-injection matrix, including what nothing guards:
`docs/20-29-testing-qa/20.11-gate-fault-injection-2026-08-22-reference.md`.
+## Inject BOTH directions, or the gate is half-tested (2026-08-22)
+
+Planting the defect and watching it fail proves the gate can fire. It does not
+prove the gate can stay quiet. Plant a legitimate LOOKALIKE and watch it PASS.
+
+The missing half cost four false positives in one day: a marker accused this
+repo's own real `jt_site` case study of being fabricated; an AI-tell rule fired
+on "anyone on **the team** could remember"; a phrase marker flagged a quoted
+exhibit inside a ```diff fence as our own claim; a single-line `
` grep
+reported a working diagram as missing because Hugo wraps the tag across lines.
+Each verdict was trusted, and correct work was nearly changed to satisfy it.
+
+**When a gate accuses something, reproduce the accusation by hand before
+believing it.** The fabrication ratchet's phrase scan now strips fenced code for
+exactly this reason, and was verified both ways on a throwaway probe post:
+legitimate exhibit PASS, same phrase in prose FAIL.
+
# A green visual run means nothing without its `[snap_diff]` line
The gem resolves every baseline with `git show HEAD:`. Anything that
diff --git a/.okf/content/voice-rules.md b/.okf/content/voice-rules.md
index a624ee8b2..82ddb6321 100644
--- a/.okf/content/voice-rules.md
+++ b/.okf/content/voice-rules.md
@@ -82,6 +82,26 @@ Full table in 90.11 §1b.
from the writer brief reached published HTML on five posts. Report cadence
in the handback, never in the file.
+# Slop is found by cold eyes, not by a score or a grep (2026-08-22)
+
+A `bin/check-post-voice` was written and deleted the same day, on Paul's call. A
+regex catches "Not X. Not Y." and misses prose that is fluent, on-pattern and
+lifeless - and a passing run reads as "the voice is fine", the same false
+confidence as a link checker reporting green over a tenth of a site.
+
+What a four-lens panel caught that no script could: **section-level rhythm**.
+Every H2 in three posts landed on a one-sentence aphorism paragraph -
+"evidence, evidence, punchline, white space, next heading" - and all three posts
+opened on the identical two-beat reveal. Sentence lengths varied; the
+choreography did not. Read two consecutive sections aloud; if they land the same
+way, one has to change SHAPE, not wording.
+
+The panel: ICP cold read, voice/AI tells, competitor standard (the reviewer
+fetches two current competitor posts), claim verification. Different agent type
+than the writer, briefed with goal and artifact rather than conclusions, each
+required to name something it would cut. Three approvals means the panel was not
+asked a real question.
+
# Banned structural patterns (reject on sight)
Slogany reveal-twist flips ("X wasn't Y - it was Z") **unless the text names WHO
diff --git a/.okf/log.md b/.okf/log.md
index f15e3d745..d8b432f92 100644
--- a/.okf/log.md
+++ b/.okf/log.md
@@ -51,6 +51,52 @@ make it green: restructure same-day entries under one heading, and add
`timestamp` to the 23 concepts missing it (anchored to each file's last commit
time, which is verifiable - never invented).
+## 2026-08-22 - four cold-eyes reviewers found what a script had just passed
+
+Three posts shipped having passed every check their author could run, including
+a purpose-built `bin/check-post-voice`. Paul read them as slop and overruled the
+script: "it's hard to have determined automate to detect ai slops, you need to
+run different agents from cold eyes review". Deleted the same day it was written.
+
+The category error is worth naming because it was made hours after the opposite
+lesson was written down. Correctness is not greppable - established that morning,
+recorded in [claims-canon](/content/claims-canon.md) - and then a regex was built
+for SLOP, which has the same property. Worse, a green PASS from it reads as "the
+voice is fine", which is the exact false-confidence failure the same day's blog
+post is about.
+
+A four-lens panel then found, in posts a script had passed:
+
+- **Section-level rhythm.** Every H2 landing on a one-sentence aphorism -
+ "evidence, evidence, punchline, white space, next heading" - five times a post,
+ three posts. Plus an identical two-beat opening reveal in all three. Sentence
+ lengths varied; the choreography did not. This is the actual slop and no
+ pattern-matcher can see it.
+- **Numbers I was confident about.** `[snap_diff] 287 screenshots compared` took
+ 287 from the unit-test run count; a link total came from today's build while
+ describing a fix that landed at 114,050; a tool output was reproduced inside a
+ fence with one field edited. Not fabrication - real measurements from the wrong
+ run, which is why they survived self-review.
+- **Cited but never spent.** Two of three posts listed a footer source the body
+ never engages; one had its claim on the cover image while the post never told
+ the story.
+- **A command that reports success having checked nothing.**
+ `content/blog/**/index.md` matches nothing in bash without `shopt -s globstar` -
+ published in a post about checks that check nothing.
+- **Attribution unchecked while the quote was checked.** "Responsible Statecraft
+ traced it" - they reported it, NewsGuard traced it. "Both publish their error
+ bars" - one does.
+
+Also corrected at source: `Rakefile` and this bundle's test-gates both said the
+link gate was green "for a year"; git says it shipped 2026-07-21, one month
+before it was caught.
+
+Rules written where writers will hit them:
+[voice-rules](/content/voice-rules.md) gains the cold-eyes section,
+[test-gates](/build/test-gates.md) gains the both-directions injection rule,
+and CLAUDE.md's blog section lost two bullets that routed future sessions into
+the rejected method.
+
## 2026-08-22 - the codeblocks drift was STALE BASELINES; five theories closed at once
**`rendering-stack`**: re-recorded `linux/` on master (`dc11791ab`, all 55) and
diff --git a/STATUS.md b/STATUS.md
index 0b7aeea59..63e7a4ea8 100644
--- a/STATUS.md
+++ b/STATUS.md
@@ -21,7 +21,7 @@
| LinkedIn (primary demand lane) | **LIVE** — 3 posts published (2026-08-13/18/19), first metrics read 2026-08-20; ICP-E lane on disk: 1 posted + 4 approved (of 10 planned), validation clock running | Post an approved draft (week1-tue / week1-wed) at Stream 0 cadence (3-4/wk) | [`metrics-ledger`](linkedin-posts/metrics-ledger.md) · [`plan`](docs/workflows/linkedin-icp-validation-plan.md) |
| 2608 site design system (v2 `/next/` rail) | Paused 2026-08-22 mid-flight; 3 pilots built + voted | Apply the [repositioned pilot copy](docs/projects/2608-site-design-system/20-29-strategy/20.09-repositioned-pilot-copy.md) (2608's own 20.09 — not the content plan); then Paul's 5 decisions | [`2608 README`](docs/projects/2608-site-design-system/README.md) |
| Positioning / homepage offer (2608 niche research + [ADR-0007](docs/adr/0007-homepage-main-offer-and-copy.md)) | **Paused 2026-08-22** — 8 research lanes complete, copy drafted + panel-voted, nothing shipped to the live site; landed on master via [#606](https://github.com/jetthoughts/jetthoughts.github.io/pull/606) | Resume via the HANDOFF — read its corrections first: the staffing constraint was briefed backwards, so every lane's discards need re-reading before acting on a shortlist | [`HANDOFF`](docs/projects/2608-niche-research/HANDOFF.md) |
-| Blog / SEO (2510) | Constrained by 20.09 §1 (outreach first). R-queue empty/retired; replacement queue is §13 (restocked 2026-08-21) | Per §1: LinkedIn cadence + sourcing outrank a new post; when drafting, take §13 N-queue | [`20.09 §13`](docs/projects/2510-seo-content-strategy/20-29-strategy/20.09-content-plan-revision-aug-2026.md) |
+| Blog / SEO (2510) | **Pipeline rebuilt and 3 posts shipped 2026-08-22.** It previously had no invokable way to produce a post - `/blog-next` never writes and the delivery half existed only as agents. Now three skills: `/blog-operator` (the door, REPAIR > UPGRADE > WRITE > RESTOCK), `/blog-next`, `/blog-write`. Live: [what-senior-developers-catch-that-ai-misses](content/blog/what-senior-developers-catch-that-ai-misses/index.md), [how-to-audit-content-you-didnt-write](content/blog/how-to-audit-content-you-didnt-write/index.md), [when-did-a-test-last-fail-on-purpose](content/blog/when-did-a-test-last-fail-on-purpose/index.md), plus an upgrade to claude-code-xp-team-workflow. Fabricated case studies purged from 14 posts; two ratchets live in `marketing_copy_test.rb` (fabrication baseline 9, uncited baseline 38). §1 outreach constraint still stands - Paul drove these directly. | **§13h**: verify the uncited technical guides, highest-traffic first (crewai 6,458 impr, propshaft 6,194, solid-cache 4,891) - re-rank before starting, the table decays. **N9** still parked: the AI code-search benchmark, design owed before any runs. | [`20.09 §13h`](docs/projects/2510-seo-content-strategy/20-29-strategy/20.09-content-plan-revision-aug-2026.md) |
| 2605 course | v2 live; measuring. Diagnosis: **arrival, not content**; course SEO/AEO **closed** (Paul 2026-08-21) | LinkedIn arrival-test cards **LI-0…LI-D** in [`content-plan`](linkedin-posts/content-plan.md); no new funnel posts on the unproven bridge | [`TASK-TRACKER`](docs/projects/2605-tech-for-non-technical-founders/TASK-TRACKER.md) |
| 2607 campaign tasks | Cold-public-sourcing premise tested and **failed** (3 sweeps, 4 venues, 0 verified-fresh rows; Reddit still un-openable) | Sept-restart Paul decision: retire the cold lane or buy Reddit API access (backlog §c) | [`2607 backlog`](docs/projects/2607-vibe-code-rescue/backlog.md) |
| Test/CI hygiene | **Gates rebuilt 2026-08-22.** Fault-injecting 8 realistic defects caught **3**; now catches **8** ([#576](https://github.com/jetthoughts/jetthoughts.github.io/pull/576), audit in [`20.11`](docs/20-29-testing-qa/20.11-gate-fault-injection-2026-08-22-reference.md)). Link job was excluding 90% of links — 114,050 checked now vs 15,642, and it found 5 real site defects ([#574](https://github.com/jetthoughts/jetthoughts.github.io/pull/574)). `bin/dtest` was comparing **nothing** from a worktree ([#578](https://github.com/jetthoughts/jetthoughts.github.io/pull/578)). CI Linux screenshot job green (run 32565008850) | **Paul decides the dtest arch policy** (below); otherwise nothing queued | [`test-gates`](.okf/build/test-gates.md) |