Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
489ff4e
Add v0.3 design: portable skill across Claude Code, Codex, Cursor, He…
ccf Sep 14, 2026
811e428
v0.3 design: fold in verified Claude Desktop findings
ccf Sep 14, 2026
94c53d8
v0.3 design: add positioning copy section (research-grounded, every l…
ccf Sep 14, 2026
fcb3a06
v0.3 design revision 2: adjudicate the three-lens adversarial review
ccf Sep 14, 2026
fb823c0
Add v0.3 implementation plan (portable skill)
ccf Sep 14, 2026
5a67cc7
v0.3 plan revision 2: apply the dry-run findings
ccf Sep 14, 2026
c8b92b6
Move the plugin to the repository root
ccf Sep 14, 2026
ef10823
Make SKILL.md harness-agnostic; add frontmatter, path, and reference …
ccf Sep 14, 2026
170b680
Add Agent Plugins and Codex manifests; version 0.3.0 in lockstep
ccf Sep 14, 2026
daa2cf1
Add guard-clean script test and the claude.ai skill zip packager
ccf Sep 14, 2026
ad4ac39
Reposition humanize as research-grounded across every text layer
ccf Sep 14, 2026
3060a9f
Document installation per harness; portability and version invariants
ccf Sep 14, 2026
ef94c93
Drop the superseded tag sentence from the Workflow notes
ccf Sep 14, 2026
2e6c86f
Add the harness smoke matrix and v0.3 acceptance transcripts
ccf Sep 14, 2026
b2ff84f
Smoke matrix: section-aware judge, Codex event parser, SKIP on auth
ccf Sep 14, 2026
1a8fd75
Fix the scan-path wording, tighten step 3, concept-match smoke rows (…
ccf Sep 14, 2026
3c30d2e
Smoke matrix: re-enable trap; Hermes runs from the repo root
ccf Sep 14, 2026
e576882
Mark the v0.3 design implemented
ccf Sep 14, 2026
b69a169
Smoke matrix: distinct-row concept matching, traps, scanner-only Clau…
ccf Sep 14, 2026
0585210
SKILL.md: scan-path fallback; invocation heading
ccf Sep 14, 2026
2a39835
Docs: verified install commands, acceptance record, spec amendments
ccf Sep 14, 2026
a517f74
Smoke matrix: arm the Hermes trap before the copy; Claude evidence re…
ccf Sep 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@
"url": "https://github.com/ccf/humanize"
},
"metadata": {
"description": "Remove AI tells from prose. Skill + /humanize command grounded in StoryScope (arXiv 2604.03136).",
"version": "0.2.0"
"description": "Measures prose against 13 studies of how AI and human writing differ, from word choice to sentence rhythm to story shape, then rewrites the tells out.",
"version": "0.3.0"
},
"plugins": [
{
"name": "humanize",
"description": "Audit prose for AI tells and rewrite it to read as natural human writing, grounded in StoryScope's measured human-vs-AI feature gaps",
"source": "./plugins/humanize",
"version": "0.2.0",
"description": "Audits a draft layer by layer (vocabulary, punctuation, sentence shape, openers, closers, grammar, narrative, per-model habits) against 13 studies, then rewrites what it flags in the author's voice.",
"source": "./",
"version": "0.3.0",
"author": { "name": "ccf" },
"license": "MIT",
"keywords": ["writing", "prose", "editing", "ai-detection", "storyscope", "humanize"],
"keywords": ["humanize", "writing", "prose", "editing", "style", "ai-writing", "rewriting", "linguistics"],
"category": "writing",
"strict": true
}
Expand Down
8 changes: 8 additions & 0 deletions .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "humanize",
"version": "0.3.0",
"description": "Audits a draft layer by layer (vocabulary, punctuation, sentence shape, openers, closers, grammar, narrative, per-model habits) against 13 studies, then rewrites what it flags in the author's voice.",
"author": { "name": "ccf" },
"license": "MIT",
"keywords": ["humanize", "writing", "prose", "editing", "style", "ai-writing", "rewriting", "linguistics"]
}
21 changes: 21 additions & 0 deletions .codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "humanize",
"version": "0.3.0",
"description": "Audits a draft layer by layer (vocabulary, punctuation, sentence shape, openers, closers, grammar, narrative, per-model habits) against 13 studies, then rewrites what it flags in the author's voice.",
"author": { "name": "ccf" },
"homepage": "https://github.com/ccf/humanize",
"repository": "https://github.com/ccf/humanize",
"license": "MIT",
"keywords": ["humanize", "writing", "prose", "editing", "style", "ai-writing", "rewriting", "linguistics"],
"skills": "./skills/",
"interface": {
"displayName": "humanize",
"shortDescription": "Audit prose for AI tells at every layer, then rewrite it in the author's voice.",
"longDescription": "Reads a draft against what 13 studies measured about AI writing: word choice, punctuation, sentence shape, openers, closers, grammar, register, fiction habits, per-model quirks. A dependency-free scanner supplies the counts a model cannot eyeball, and each flag cites the sentence that triggered it.",
"developerName": "ccf",
"category": "Developer Tools",
"capabilities": ["Read", "Write"],
"defaultPrompt": ["Humanize this draft.", "Audit this text for AI tells, don't rewrite it."],
"websiteURL": "https://github.com/ccf/humanize"
}
}
19 changes: 13 additions & 6 deletions .cursor/BUGBOT.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
# Bugbot review guide — humanize

This repo is a Claude Code plugin that audits prose for AI tells and rewrites
it. Design spec: `docs/design/2026-09-13-humanize-plugin-design.md` and
`docs/design/2026-09-14-humanize-v0.2-design.md`.
This repo is an agent skill that audits prose for AI tells and rewrites it, on
evidence from the studies in `skills/humanize/references/SOURCES.md`. Design specs:
`docs/design/2026-09-1{3,4}-humanize-*-design.md`.

## Invariants to enforce

- `plugins/humanize/skills/humanize/scripts/surface_scan.py` imports only the
- `skills/humanize/scripts/surface_scan.py` imports only the
Python standard library and runs on Python 3.9+. Flag any third-party import
or 3.10+ syntax (match statements, `X | Y` in runtime positions, PEP 604 in
non-annotation code).
- Nothing under `tests/` or `plugins/**/scripts/` makes network or LLM calls.
- A `Base rate:` line in `plugins/humanize/skills/humanize/references/*.md`
- Nothing under `tests/`, `skills/**/scripts/`, or `tools/package_skill_zip.py` makes network or LLM calls.
- `skills/` is harness-agnostic: no harness variables (`${CLAUDE_…}`, `HERMES_SKILL_DIR`,
`CURSOR_…`, `CODEX_…`) and no install commands inside it; frontmatter is exactly the Agent
Skills fields (`argument-hint` is a hard error outside Claude Code). `tests/test_portability.py`
enforces both.
- Version lives in `plugin.json`, `.claude-plugin/plugin.json`, `.codex-plugin/plugin.json`, both
`marketplace.json` fields, `pyproject.toml`, and the newest CHANGELOG heading —
`tests/test_portability.py` fails on drift.
- A `Base rate:` line in `skills/humanize/references/*.md`
must trace to a row in `data/storyscope_feature_gaps.csv` (or a future CSV
documented in `data/README.md`; none added in v0.2). If a PR changes a
number, check the CSV row. Any other number must sit on a `Scan:`, `Rule
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ __pycache__/
.pytest_cache/
.venv/
.superpowers/
dist/
31 changes: 30 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,34 @@ All notable changes to this project are documented here. The format follows

## [Unreleased]

## [0.3.0] - 2026-09-14

### Added
- Agent Plugins 1.0 manifest (`plugin.json`) and Codex manifest (`.codex-plugin/plugin.json`),
so the plugin installs into Codex, Cursor, and Hermes with their own tooling.
- `tests/test_portability.py`: spec-only frontmatter, no harness-specific content under
`skills/`, runtime references named, guard-clean scripts, manifests and CHANGELOG in
version lockstep, zip packager contract, study count matches `SOURCES.md`.
- `tools/package_skill_zip.py`: builds the claude.ai skill upload from the plugin.
- `tools/smoke_harnesses.sh`: local acceptance matrix with scanner-evidence PASS rule;
transcripts under `docs/acceptance/v0.3/`.
- README install table for Claude Code, Codex CLI, Cursor, Hermes Agent, Claude Desktop.

### Changed
- Repository layout: the plugin now lives at the root (`skills/humanize/`); the marketplace
`source` is `./`.
- `SKILL.md` is harness-agnostic: relative `scripts/surface_scan.py` path, plain-words options,
document extraction described generically; `argument-hint` removed (a hard error outside
Claude Code). The `/plugin` install lines moved to the README.
- Public copy describes humanize as grounded in the thirteen studies in
`references/SOURCES.md` and covering every layer of a text; StoryScope is named where it is
the source of a number.
- `pyproject.toml` version now tracks the plugin version.

### Migration
- Existing Claude Code installs: `claude plugin marketplace update humanize && claude plugin
update humanize@humanize`.

## [0.2.0] - 2026-09-14

### Added
Expand Down Expand Up @@ -87,7 +115,8 @@ Initial release (#1).
CI (pre-commit, pytest on Python 3.9 and 3.13, `claude plugin validate
--strict`), and a Bugbot review guide.

[Unreleased]: https://github.com/ccf/humanize/compare/v0.2.0...HEAD
[Unreleased]: https://github.com/ccf/humanize/compare/v0.3.0...HEAD
[0.3.0]: https://github.com/ccf/humanize/compare/v0.2.0...v0.3.0
[0.2.0]: https://github.com/ccf/humanize/compare/v0.1.2...v0.2.0
[0.1.2]: https://github.com/ccf/humanize/compare/v0.1.1...v0.1.2
[0.1.1]: https://github.com/ccf/humanize/compare/v0.1.0...v0.1.1
Expand Down
30 changes: 22 additions & 8 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
# humanize — working notes for Claude

Claude Code plugin that audits prose for AI tells and rewrites it. Evidence base:
StoryScope (arXiv 2604.03136). Spec and plan: `docs/design/`. Changelog: `CHANGELOG.md`.
Agent skill that audits prose for AI tells and rewrites it. Evidence base: 13 studies
in `references/SOURCES.md`. Spec and plan: `docs/design/`. Changelog: `CHANGELOG.md`.

## Commands

```
uv sync # first time
uv run pytest -q # 100 tests, must be warning-free
uv run pytest -q # must be warning-free
uv run ruff format <files> && uv run ruff check --fix <files>
claude plugin validate --strict .
uv run python plugins/humanize/skills/humanize/scripts/surface_scan.py --text <file>
claude plugin validate --strict . # marketplace JSON only; does not inspect plugin or skill contents
uv run python skills/humanize/scripts/surface_scan.py --text <file>
python3 tools/gen_tell_scaffold.py style|narrative # regenerate reference scaffolds
```

Expand Down Expand Up @@ -47,8 +47,16 @@ Never run bare `ruff format .` — ruff 0.16 formats Python fences inside
- `SKILL.md` stays under ~150 lines. `/humanize` is the skill itself — do not add
a `commands/` directory (it registers a duplicate skill named `humanize`).
- Marketplace entry stays `strict: true` with no component arrays; `plugin.json`
is authoritative. Bump `version` in both when shipping.
- Nothing under `tests/` or `plugins/**/scripts/` touches the network.
is authoritative. Version lives in `plugin.json`, `.claude-plugin/plugin.json`,
`.codex-plugin/plugin.json`, both `marketplace.json` fields, `pyproject.toml`,
and the newest CHANGELOG heading — `tests/test_portability.py` fails on drift.
- Nothing under `tests/`, `skills/**/scripts/`, or `tools/package_skill_zip.py` touches the network.
- `skills/` is harness-agnostic: no harness variables (`${CLAUDE_…}`, `HERMES_SKILL_DIR`,
`CURSOR_…`, `CODEX_…`) and no install commands inside it; frontmatter is exactly the Agent
Skills fields (`argument-hint` is a hard error outside Claude Code). `tests/test_portability.py`
enforces both.
- Public copy names StoryScope only where it is the specific source of a number or a file; the
tool is described as grounded in the `SOURCES.md` registry (the study count is tested).

## Workflow

Expand All @@ -57,7 +65,13 @@ linear history required, the four CI jobs must pass on an up-to-date branch, and
every review thread must be resolved — so after fixing a Bugbot finding, resolve
its thread (GraphQL `resolveReviewThread`) before merging. Merge with
`gh pr merge --rebase` (rebase is the only enabled method; merged branches are
deleted automatically). Tag releases on `main` after the merge (`vX.Y.Z`). CI runs pre-commit, pytest (3.9 and
deleted automatically). Release: `tools/smoke_harnesses.sh` must PASS on every harness installed
here (transcripts under `docs/acceptance/`), then merge, then post-merge acceptance from `main`
(Codex `plugin marketplace add ccf/humanize` without a ref, Hermes `skills install`, Claude plugin
upgrade, Cowork marketplace add), then tag and `gh release create vX.Y.Z
dist/humanize-skill-X.Y.Z.zip` (built by `python3 tools/package_skill_zip.py`), then verify the zip
uploads and triggers in claude.ai chat. Anything found after the merge is fixed forward as a patch
release. CI runs pre-commit, pytest (3.9 and
3.13), and plugin validation; Cursor Bugbot reviews every PR and re-reviews on
push. Pre-commit hooks run on every commit; never `--no-verify`. After merging a plugin change:
`claude plugin marketplace update humanize && claude plugin update humanize@humanize`.
Expand Down
113 changes: 64 additions & 49 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,39 +1,55 @@
# humanize

A Claude Code plugin that finds and removes the tells that mark prose as
AI-generated, and rewrites it to read as natural human writing — without
flattening the author's voice.

It is grounded in [StoryScope](https://github.com/jenna-russell/storyscope)
(Russell, Rajendhran, Pham, Iyyer, Wieting, *StoryScope: Investigating
idiosyncrasies in AI fiction*,
[arXiv:2604.03136](https://arxiv.org/abs/2604.03136)), which measured 304
narrative and stylistic features on 61,575 stories and found that AI writing
converges on shared defaults while human writing disperses. This plugin turns
the 77 features with the largest human-vs-AI gaps into an audit checklist,
adds the surface-level tells StoryScope deliberately excluded, and pairs both
with a dependency-free scanner for the numbers a model can't eyeball. v0.2
adds a grammar and repetition layer from register and reader-perception
studies (Reinhart et al. 2025; Jakesch et al. 2023; Herbold et al. 2023 and
others); every cited number resolves in `references/SOURCES.md`.
An agent skill that audits prose for the tells of AI writing and rewrites them
out, without flattening the author's voice. Runs in Claude Code, Codex, Cursor,
Hermes Agent, Claude Desktop.

The reference entries rest on thirteen studies. StoryScope (2026) measured 304
narrative and stylistic features over 61,575 stories, and its widest human-vs-AI
gaps supply the base rates. Reinhart et al. (2025) put participial modifiers at
5.3 times the human rate and nominalization at 2.1 times. Jakesch et al. (2023)
found repeated phrasing the strongest true signal of a text's source. Herbold et
al. (2023) recorded a lexical-diversity reversal between model generations, a
reminder that findings expire. humanize turns that work into an audit checklist
plus a dependency-free scanner for the counts a model cannot eyeball; every flag
quotes the line it came from. One pattern organizes the whole checklist: AI
converges on shared defaults while human writing disperses. Every cited number
resolves in `references/SOURCES.md`.

## Install

```
/plugin marketplace add ccf/humanize
/plugin install humanize@humanize
```

Requires Python 3.9+ on `PATH` for the scanner. No other dependencies.

Optional, for Word/PDF/PowerPoint inputs: Anthropic's `document-skills`
plugin, which humanize delegates extraction to (its `docx` read path uses
`pandoc`; `brew install pandoc` on macOS).

```
/plugin marketplace add anthropics/skills
/plugin install document-skills@anthropic-agent-skills
```
Commands were checked against each CLI's `--help` for this release; installs
that fetch from GitHub (Codex, Hermes) are exercised at the acceptance steps
recorded in `docs/acceptance/`.

| Harness | Install | Verify | Invoke |
|---|---|---|---|
| Claude Code | `/plugin marketplace add ccf/humanize` then `/plugin install humanize@humanize` | `claude plugin list` | `/humanize …` or automatically |
| Codex CLI | `codex plugin marketplace add ccf/humanize` then `codex plugin add humanize@humanize` — or `cp -R skills/humanize ~/.agents/skills/` | `codex debug prompt-input "hi"` lists the skill | `$humanize …` or automatically |
| Cursor | `cp -R skills/humanize ~/.cursor/skills/` (every project) or `.cursor/skills/` (this project) | the skill appears in the `/` menu | `/humanize …` or automatically |
| Hermes Agent | `hermes skills install ccf/humanize/humanize --category writing`; in a running session, `/reload-skills` | `hermes skills list` | `/humanize …` or automatically |
| Any Agent-Skills harness | `npx skills add ccf/humanize` or `cp -R skills/humanize ~/.agents/skills/` | harness-specific | harness-specific |
| Claude Desktop — Cowork | Customize → Plugins → Add from repository `ccf/humanize` → install `humanize` | listed under Customize → Plugins | `/` or `+` picker, or automatically |
| Claude Desktop — chat (claude.ai) | Customize → Skills → upload `humanize-skill-<version>.zip` from the [latest release](https://github.com/ccf/humanize/releases); "Code execution and file creation" must be on | listed under Customize → Skills | automatically, or the sidebar `/` menu |

Notes:

- **Codex** reads `<repo>/.agents/skills/` and `~/.agents/skills/` but not `.claude/skills/`, and
caps the injected skills catalog at 2% of the context window; a long catalog drops skills.
- **Cursor** syncs only `~/.cursor/skills/` to Cloud Agents, and only with **Sync Skills for Cloud
Agents** on (Settings → Agents). The Cursor marketplace is reviewed by hand and has no CLI.
- **Hermes** scans installed scripts (`surface_scan.py` is standard-library and passes) and runs
the scanner on the host, so on a remote terminal backend (docker, modal, ssh) the scan step is
skipped and the audit proceeds from reading alone. `hermes plugins install` also works on
recent builds but installs the package disabled and read-only; prefer `hermes skills install`.
Installing from a raw `SKILL.md` URL fetches one file and is not supported.
- **Claude Desktop** picks up a Cowork plugin update only when `version` changes. In claude.ai
chat the skill triggers by description; picking it from the `/` menu passes no arguments.
- **Word, PDF, PowerPoint inputs.** humanize delegates extraction to the harness's document
skills. In Claude Code that is Anthropic's `document-skills` plugin (`/plugin marketplace add
anthropics/skills`, `/plugin install document-skills@anthropic-agent-skills`; its `docx` read
path uses `pandoc` — `brew install pandoc` on macOS); Claude Desktop ships the same skills.

## Use

Expand Down Expand Up @@ -100,32 +116,31 @@ Rewrite (excerpt):
## What's inside

```
plugins/humanize/
skills/humanize/
SKILL.md the procedure
references/
principles.md
surface-tells.md vocabulary, punctuation, shape, discourse moves
style-tells.md 20 StoryScope style features with base rates
narrative-tells.md 57 StoryScope narrative features (fiction only)
model-fingerprints.md Claude / GPT / Gemini / DeepSeek / Kimi tendencies
SOURCES.md citation registry (not loaded at runtime)
scripts/surface_scan.py stdlib-only metrics: burstiness and sentence tails, punctuation,
tricolons, not-but, wordlists, closers, repeated phrases,
participial tails, container nouns, nominalization hits,
disclaimer opener
data/ StoryScope taxonomy + computed feature gaps
tools/gen_tell_scaffold.py regenerate reference scaffolds from the data
tests/ pytest; no network, no LLM calls
skills/humanize/
SKILL.md the procedure
references/
principles.md
surface-tells.md vocabulary, punctuation, shape, discourse moves
style-tells.md 20 style features with StoryScope base rates
narrative-tells.md 57 narrative features (fiction only), StoryScope base rates
model-fingerprints.md Claude / GPT / Gemini / DeepSeek / Kimi tendencies
SOURCES.md citation registry (not loaded at runtime)
scripts/surface_scan.py stdlib-only metrics: burstiness and sentence tails, punctuation,
tricolons, not-but, wordlists, closers, repeated phrases,
participial tails, container nouns, nominalization hits,
disclaimer opener
data/ StoryScope taxonomy + computed feature gaps
tools/gen_tell_scaffold.py regenerate reference scaffolds from the data
tests/ pytest; no network, no LLM calls
```

## Development

```
uv sync
uv run pytest -q
claude plugin validate .
uv run python plugins/humanize/skills/humanize/scripts/surface_scan.py --text some.txt
claude plugin validate --strict .
uv run python skills/humanize/scripts/surface_scan.py --text some.txt
```

CI (`.github/workflows/ci.yml`) runs the same pre-commit hooks, pytest on
Expand Down
Loading
Loading