From 3b288c0a21536682a2a2878a6d10e55d0a6d9169 Mon Sep 17 00:00:00 2001 From: Malin Date: Wed, 19 Aug 2026 14:47:19 +0200 Subject: [PATCH] feat: add humanize-generated-content skill MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Codifies the existing (but silently skippable) humanize step as a checked skill after a real content batch published without it — codex hand-rolled its own generation call instead of going through content-agent/agent.py, which unconditionally runs both draft_rewrite() and humanize(). This skill makes the requirement explicit, gives the safe invocation path, and states how to verify the pass actually ran rather than trusting a delegate's self-report. Co-Authored-By: Claude Sonnet 5 --- skills/humanize-generated-content/SKILL.md | 108 +++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 skills/humanize-generated-content/SKILL.md diff --git a/skills/humanize-generated-content/SKILL.md b/skills/humanize-generated-content/SKILL.md new file mode 100644 index 0000000..6d3dd8f --- /dev/null +++ b/skills/humanize-generated-content/SKILL.md @@ -0,0 +1,108 @@ +--- +name: humanize-generated-content +description: Use whenever generating text that will be published somewhere a real external reader sees it — a WordPress post, landing-page copy, marketing content, a public-facing article. Not for internal docs, code, commit messages, or conversational replies. Ensures every such draft passes through a humanize rewrite before publishing, not just the pipelines that happen to already do it. +--- + +# Humanize Generated Content + +## Scope — read this first + +This applies to **generated text intended for public, external-facing +publication**: blog posts, landing-page copy, marketing content, articles on +any of the granja-managed sites. It does **not** apply to internal docs, +code, commit messages, memory notes, or normal conversational replies — +running an AI-detection-evasion pass on a commit message would be wasted +effort with no reader who cares. If it's not going to sit on a public page +for a stranger to read, this skill doesn't apply. + +## The rule + +**Any draft headed for publication gets a humanize pass before it goes +live — not "usually," not "the pipeline probably does it," a checked step.** + +This exists because it already failed silently once: a content batch +delegated to a coding CLI hand-rolled its own draft-generation call instead +of going through the project's own `content-agent/agent.py`, and the +humanize pass never ran. Nothing errored. The post just published +AI-flavored. The fix isn't "be more careful next time" — it's routing +through a path that can't skip it, and checking that it didn't. + +## The mechanism + +**Preferred: use `content-agent/agent.py` directly, don't hand-roll +generation.** Its `main()` unconditionally calls `draft_rewrite()` then +`humanize()` — there is no flag to skip the humanize pass. If content-agent +already covers the site/niche, this is the safe path by construction: + +``` +cd /home/malin/granja +REPLICATE_API_TOKEN= python3 content-agent/agent.py \ + --domain --niche \ + --language \ + --source-text "" \ + --out /tmp/.json +``` + +The output JSON's `models.humanize` field records which model actually ran +the pass — that's your verification, not the exit code. + +**If content-agent doesn't cover the target** (a one-off script, a delegate +task outside the existing niches/domains), still route the draft through the +same humanize step manually before publishing: + +```python +from agent import humanize, agy_run # content-agent/agent.py +final = humanize(config, token, niche, draft_text, language) +``` + +or, for a standalone call outside that module, `agy_run(prompt, +model="gemini-3.1-pro-high")` — see `content-agent/agent.py`'s `agy_run()` +for the exact CLI invocation (absolute path to the `agy` binary, required +when not running under a login shell — a cron job silently failed on this +once by using a bare `agy` that wasn't on `PATH`). + +**Why agy/gemini-3.1-pro-high specifically, not a different backend:** +resolved via a direct A/B test (2026-07-24), not a per-task guess — the +identical humanize prompt scored 97-99% AI-detected when run through +Replicate's `google/gemini-3-pro`, and 63% when run through agy on the same +content. Don't substitute a different backend without re-running that kind +of comparison first. + +## Verify, don't trust + +A delegate or subagent reporting "I humanized it" is a claim, not a fact — +matches this repo's general "verify, don't relay" rule. Before treating a +batch as done: + +- Check the actual output artifact names which model ran the humanize pass + (`models.humanize` in content-agent's JSON output, or equivalent) — not + just that a step in the log says it happened. +- For anything higher-stakes than a routine local-news recap, spot-check + with an actual AI-detector rather than trusting the pass ran clean. + +## What "good" humanized output actually looks like (so you can spot bad output, not just missing output) + +The humanize prompt itself (see `content-agent/agent.py::humanize()`) is +built from confirmed, specific tells — worth knowing when reviewing output, +since a technically-humanized draft can still fail if it re-adds these: + +- **Fabrication risk from the "add a small concrete detail" instruction.** + Confirmed twice as a real failure mode: a fabricated "18 euro/day" sunbed + rate and a "3 euro" coffee with no source basis, and a wholly invented + named orchestra performing at a castle. A concrete detail must be grounded + in the source material or genuinely safe general knowledge — never a + specific invented name, statistic, or price. +- **A compact bulleted "quick tips" closer is a strong AI tell** — confirmed + as the exact difference between a 100%-AI-scored and a 78%-human-scored + version of otherwise-comparable content. Should read as full paragraphs + with real specifics, not a terse bulleted list. +- **Personifying the destination/subject as an agent acting on the reader** + ("the island hits you with...", "leaves you breathless") is a confirmed + high-impact tell (caught by GPTZero's own sentence-level flagging). Should + read as a plain stated observation instead. +- **The "not just X, but Y" contrastive construction** and **reflexive + rule-of-three lists** are both known LLM tics the pass should be actively + breaking, not reproducing. + +If reviewing output that still shows these patterns, treat it as a failed +humanize pass even if the pipeline step technically ran.