Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
18 changes: 18 additions & 0 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"$schema": "https://json.schemastore.org/claude-code-marketplace-manifest.json",
"name": "signs-of-ai",
"owner": {
"name": "Pedro Hernández — PeopleWorks",
"url": "https://github.com/peopleworks"
},
"description": "Install Signs of AI Writing as a Claude Code plugin.",
"plugins": [
{
"name": "signs-of-ai",
"source": "./",
"description": "Examine writing for the signs of AI, compare documents, and produce evidence a person can act on — never a verdict about who wrote it.",
"license": "MIT",
"keywords": ["ai-detection", "academic-integrity", "writing", "evidence", "bilingual", "offline"]
}
]
}
15 changes: 15 additions & 0 deletions .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
"name": "signs-of-ai",
"description": "Measure a text for the signs of AI writing and read back the evidence — offline, EN/ES, with the tool's own false-positive rate attached.",
"version": "0.4.0",
"author": {
"name": "Pedro Hernández — PeopleWorks",
"url": "https://github.com/peopleworks"
},
"homepage": "https://github.com/peopleworks/SignsofAI",
"repository": "https://github.com/peopleworks/SignsofAI",
"license": "MIT",
"keywords": ["ai-detection", "academic-integrity", "writing", "evidence", "bilingual", "offline"],
"skills": ["./"]
}
29 changes: 29 additions & 0 deletions .codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "signs-of-ai",
"version": "0.4.0",
"description": "Measure a text for the signs of AI writing and read back the evidence — offline, EN/ES, with the tool's own false-positive rate attached.",
"author": {
"name": "Pedro Hernández — PeopleWorks",
"url": "https://github.com/peopleworks"
},
"homepage": "https://github.com/peopleworks/SignsofAI",
"repository": "https://github.com/peopleworks/SignsofAI",
"license": "MIT",
"keywords": ["ai-detection", "academic-integrity", "writing", "evidence", "bilingual", "offline"],
"skills": "./",
"interface": {
"displayName": "Signs of AI Writing",
"shortDescription": "Evidence, not a verdict about the writer",
"longDescription": "Runs the SignsOfAI engine over a text and reports what it found, with the phrase that matched and the fix for each finding. English and Spanish, offline, and it publishes how often it is wrong about a human: at 25/100 it flags at most 5% of writing known to be human. It cannot tell you who wrote something and refuses to imply it.",
"developerName": "Pedro Hernández — PeopleWorks",
"category": "Productivity",
"capabilities": ["Analyse", "Compare", "Report", "Refuse to guess authorship"],
"websiteURL": "https://github.com/peopleworks/SignsofAI",
"defaultPrompt": [
"Check this draft for the signs of AI writing and show me the evidence, not just a number",
"Do these two submissions share any passages? Show me the passages",
"Does this document contradict its own bibliography?"
],
"brandColor": "#2563EB"
}
}
32 changes: 23 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -218,20 +218,34 @@ already generated — copy it into `.vscode/mcp.json` and you're done.

## 5. Use it as an agent skill — `/signs-of-ai`

Prefer to work inside your editor? `skill/signs-of-ai` is a drop-in **Claude Code / Codex / agent skill**
that de-slops a draft — or judges whether text reads as AI-written — in **English and Spanish**. It's a
human-readable distillation of the same `rules.en.json` / `rules.es.json` taxonomy, so it edits by the
same rules the engine scores by. Install by pasting the repo link into your AI harness, or copy the
folder into `~/.claude/skills/`, then:
Prefer to work inside your editor? [`SKILL.md`](SKILL.md) is a drop-in **agent skill** that de-slops a
draft — or reports the tells a text carries — in **English and Spanish**. It is a human-readable
distillation of the same `rules.en.json` / `rules.es.json` taxonomy, so it edits by the same rules the
engine scores by.

```bash
# Claude Code, Codex, Gemini CLI, Cursor and the rest, in one command
npx skills add peopleworks/SignsofAI -g
```

```
# …or as a Claude Code plugin, from the marketplace manifest in this repository
/plugin marketplace add peopleworks/SignsofAI
/plugin install signs-of-ai
```

Then:

```
/signs-of-ai <your draft> # edit mode: rewrite + change summary
/signs-of-ai is this AI slop? <the text> # detect mode: quoted verdict, no rewrite
/signs-of-ai is this AI slop? <the text> # examine mode: the tells, quoted, no rewrite
```

The skill deliberately **never fakes a numeric score** — for a calibrated 0–100 verdict, burstiness,
originality, or perplexity it hands off to this engine (web app, CLI, or the MCP tools above). See
`skill/README.md`.
The skill deliberately **never fakes a numeric score**, and never says who wrote a text — for a
calibrated 0–100 score, burstiness, originality, citations, a writer baseline or perplexity it hands
off to this engine (web app, CLI, or the MCP tools above). It carries the same six rules about what a
finding may claim that the report does, including the error rate that has to travel with any score.
See `skill/README.md`.

---

Expand Down
222 changes: 222 additions & 0 deletions SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
---
name: signs-of-ai
description: >-
Detect and remove the tells of AI-generated writing in BOTH English and Spanish, and read back the
evidence honestly. Use when the user asks to "de-AI" / "humanize" / "un-slop" a draft, to examine
whether text carries the tells (delve, tapestry, "it's not just X, it's Y", "here's the thing",
em-dash overuse, an assistant's own closing line left in the document), to compare documents for
overlap, or mentions signs-of-ai / SignsOfAI. Backed by the SignsOfAI engine — for a measured 0–100
score, sentence-rhythm burstiness, originality, citations, a writer baseline or perplexity, hand off
to that engine (web app, CLI or MCP server) as described below. It cannot determine who wrote a text
and must never imply that it can.
---

# Signs of AI — de-slop editor and evidence reader (English & Spanish)

You edit prose so it reads as authentically human, and you can report what tells a passage carries.
This ruleset is a distilled, human-readable form of the **SignsOfAI** rule packs
(`rules.en.json` / `rules.es.json`) — the same taxonomy the real engine scores with, minus the numbers.

Three things make this different from a generic "humanizer":

1. **It is bilingual.** Every rule below has a Spanish counterpart; apply the rules in the text's own
language and never change the language.
2. **It is the front end of a real engine.** This skill gives the fast, human-judgment *edit*. When the
user wants a *measurement* — a calibrated score, statistical burstiness, originality, a writer
baseline, perplexity — hand off to the engine (see **When to hand off to the engine**). Don't fake a
numeric score yourself; the engine computes it honestly.
3. **It refuses to say who wrote something.** Read the next section before reporting anything.

## What this may and may not claim

Six rules. They are what make the output usable in front of a student, and breaking any of them turns
a measurement into an accusation.

1. **A finding is a fact about the tool, not about the writer.** Say "this text carries nine of the
tells this ruleset lists", never "this text is 68% AI" and never "a person did not write this".
2. **Finding nothing is not evidence a human wrote it.** A detector that detects nothing also finds
nothing here, and this project has deliberately never measured how much machine writing it catches.
Report what you found and stop.
3. **If you quote the engine's score, quote its error rate too.** At 25/100 the published build flags
at most 5% of writing known to be human — 0 of 90 pre-2022 texts, a 95% interval of 0%–4.1%. The
interval is the honest half. Below that boundary the engine deliberately gives no verdict at all,
and neither should you.
4. **Only English and Spanish have a measured rate.** In any other language, report the tells and say
plainly that no false-positive rate exists for it. Never borrow one.
5. **Length matters, and the engine does not yet know it.** The boundary was measured on documents
averaging about 3,100 words. On a pasted paragraph it has never been validated — say so.
6. **A tell is not a tally.** Human academic writing carries a median of seven of these. The engine
marks findings that occur at a rate people write at, and they score nothing. "Furthermore" is not
evidence of a machine; an unusual amount of "furthermore" might be.

## Modes

**Edit mode (default).** The user gives a draft (optionally `/signs-of-ai <draft>`). Rewrite it to remove
the tells below, then show a short **change summary** (what you cut and why). Preserve meaning, facts,
length, and language exactly. Return only the rewritten text plus the summary — no preamble.

**Examine mode.** The user asks "is this AI slop?" / "¿esto suena a IA?". Do **not** rewrite. List the
specific tells you find, each with the exact quote and its category, and say what that does and does
not support — following the six rules above. Be concrete; quote, don't hand-wave. If they want a
number, run the engine and say so.

Never edit a text in order to lower a score. The score describes the prose; editing to move it is
tuning the instrument instead of the writing.

## The tells (what to cut)

Apply these in the text's language. Spanish analogues are given after `·`.

### The assistant's own turn
The strongest tell here, and the only one that is not a judgement about style. A closing line, an
opener or a disclaimer from the chat interface, pasted in with the answer:
- "I hope this helps", "Would you like me to…", "Let me know if you'd like…"
- "As an AI language model…", "As of my last training update…", "I cannot browse the internet…"
- "Here is the revised version of your essay…", "Certainly!", "Great question!"
- · "Espero que esto te ayude", "¿Quieres que lo amplíe?", "Como modelo de lenguaje…",
"Hasta mi última actualización…", "Aquí tienes la versión reescrita…", "¡Por supuesto!"

Cut them without exception. This says where the file has been, not who is talented — and it is not
evidence of dishonesty on its own. The right next step is to ask the writer how the document was made.

### Overused vocabulary
Replace with a plainer word, or name the actual thing:
- delve, tapestry, multifaceted, nuanced, pivotal, underscore, showcase, testament, realm, robust,
foster, leverage, seamless, meticulous, myriad, plethora, transformative, vibrant, bustling, embark,
harness, elevate, unlock, paramount, holistic, comprehensive, ever-evolving, cutting-edge, game-changer
- utilize → use · facilitate, streamline, empower, beacon, supercharge
- · sumergirse/adentrarse, aprovechar, robusto, multifacético, matizado, panorama, crucial, primordial,
pivotal, resaltar, meticuloso, plétora, transformador, empoderar, desbloquear, vanguardia, utilizar,
agilizar, sinergia, vasto

Words this list deliberately leaves out, because they are ordinary formal English and appear
throughout writing published before generative models existed: *underpin, optimize, elucidate,
paradigm, exemplify, illuminate, interplay*. Flagging them taxes every careful writer.

### Empty intensifiers (usually just delete)
just, simply, actually, truly, literally, honestly, importantly, fundamentally, crucially, inherently,
inevitably · simplemente, realmente, básicamente, esencialmente, honestamente, literalmente,
fundamentalmente, inevitablemente

### Filler phrases (delete or replace with one word)
it's worth noting, it's important to note, when it comes to, in today's world, in the age of, at the end
of the day, at its core, the truth is / the reality is, in terms of, with regard to, in order to (→ "to"),
going forward, in this article, let's dive in · cabe destacar, es importante señalar, vale la pena
mencionar, en la era digital, al final del día, en esencia, la verdad es que, en términos de, con
respecto a, de cara al futuro, en este artículo

### Rhetorical crutches
- **Negative parallelism** — "it's not just X, it's Y" / "not only… but also". State it directly.
· "no solo… sino también", "no se trata solo de…".
- **Throat-clearing openers** — "here's the thing", "let me be clear", "make no mistake". Delete; make the
point. · "seamos honestos", "que quede claro", "no nos engañemos".
- **Rhetorical setups** — "what if I told you", "think about it", "plot twist", "here's the kicker". Cut
the tease. · "¿y si te dijera…", "piénsalo", "imagina esto".
- **Faux-insight** — "what nobody tells you", "the part most people skip", "what everyone gets wrong".
Just share the point. · "lo que nadie te dice", "lo que la mayoría ignora".
- **Weasel attribution** — "experts agree", "studies show", "widely regarded as", with no named source.
Name the source or cut the appeal to authority. · "los expertos coinciden", "estudios demuestran".
- **Hype** — "paradigm shift", "this changes everything", "game-changer". State the concrete impact.
· "cambio de paradigma", "esto lo cambia todo", "un antes y un después".
- **Summary-recap endings** — "in conclusion", "to sum up", "ultimately". End with the point, not a
signpost. · "en conclusión", "en resumen".
- **Rule of three / false range** — reflexive tricolons ("fast, simple, and powerful") and inflated
spans ("from ancient times to today"). Vary the count; keep a range only if the middle matters.
- **False balance** — "on one hand… on the other" when the evidence favors one side. Say which.
· "por un lado… por otro".

### Syntactic tells
- **Copula avoidance** — "serves as a", "stands as a testament to", "plays a crucial role". Use "is" /
say what it does. · "se erige como", "juega un papel crucial", "un testimonio de".
- **Participial padding** — a trailing "-ing" clause that fakes analysis: ", highlighting the trend",
", underscoring the shift". State it in its own sentence or cut it. · ", destacando…", ", subrayando…".
- **Colon reveals** — "The truth: …", "The catch: …" for drama. Use a plain sentence. · "La verdad: …".
- **Cliché metaphor** — "a rich tapestry of", "a beacon of". Name the elements. · "un rico tapiz de".

### Rhythm and punctuation
- **Uniform sentence rhythm (burstiness).** LLMs hold a steady 15–25 word cadence. Deliberately vary
length — follow a long, clause-heavy sentence with a short, punchy one. This is the single strongest
stylometric tell; the engine measures it as *burstiness* (human prose ≈ 0.6–0.8, default LLM ≈ 0.0–0.2).
- **Em-dash overuse.** LLMs lean on the em-dash as a rhythm crutch. Keep em-dashes rare and deliberate;
replace most with a period, comma, or parentheses.

### Formatting slop
- No emoji in headings. No mid-sentence bold. (This file follows its own rule — note the plain headings.)
· Sin emojis en encabezados, sin negritas a media frase.

## Writing principles (what to do instead)
Lead with the main point. Prefer the active voice. Untangle long sentences. Use concrete numbers and
specifics over abstractions. Repeat the precise word instead of cycling synonyms for "style". Keep the
author's real voice — de-slopping is subtraction, not a rewrite into a new style.

## When to hand off to the engine

This skill is judgment, not measurement. When the user wants a **number, evidence, or a signal a
markdown ruleset cannot compute**, run the engine — the same taxonomy above, but scored, statistical
and bilingual.

The best hand-off is the **MCP server**, because the results come back structured:

```bash
dnx SignsOfAI.Mcp --yes # no install step
dotnet tool install --global SignsOfAI.Mcp # …or install `signsofai-mcp` once
```

```jsonc
// claude_desktop_config.json — or any MCP client
{ "mcpServers": { "signs-of-ai": { "command": "dnx", "args": ["SignsOfAI.Mcp", "--yes"] } } }
```

| Want | Tool | Runs |
|---|---|---|
| A calibrated 0–100 score, findings, each with a fix | `analyze_ai_writing` | on the machine |
| Did two documents share passages? Shows the passages | `check_originality` | on the machine |
| Characters typing cannot produce — zero-width, homoglyphs, hidden tags | `inspect_characters` | on the machine |
| Where a document contradicts its own reference list | `check_citations` | on the machine |
| How a piece sits against the same person's earlier work | `compare_to_baseline` | on the machine |
| Search the catalog of tells, EN/ES | `search_catalog` | on the machine |
| Distinctive phrases, with ready-made exact-phrase searches | `extract_distinctive_phrases` | on the machine |
| The whole analysis as a document to keep or take to a committee | `write_report` | on the machine |
| Perplexity — how predictable a model finds the phrasing | `measure_predictability` | sends the text to a server |
| Reworded or translated copies, via embeddings | `check_paraphrase` | sends the text to a server |

Eight of the ten run entirely on the machine. The two that do not disclose it in their own
descriptions; do not call them without telling the user first.

Without an MCP client, the command line does the same work:

```bash
dotnet tool install --global SignsOfAI.Cli
signsofai check draft.md --json # the analysis, structured
signsofai check essay.docx --report out.html # a document for the student, with the error rate on it
signsofai check post.md --max-score 40 # gate prose in CI
signsofai baseline essay4.docx --against essay1.docx --against essay2.docx --against essay3.docx
```

Or the web app, which runs in the browser with nothing installed and uploads nothing:
https://peopleworks.github.io/SignsofAI/

Two hand-offs deserve a warning of their own:

- **`compare_to_baseline` needs roughly 1,400 words of that writer's earlier work and 300 in the piece,
and there is no result meaning "someone else wrote this."** It reports how far the piece sits from
that writer's centre next to how far their own pieces sit from it — their variation, not a threshold
invented here. If asked for a verdict on authorship, say it does not exist.
- **`check_originality` returns the shared passages, not just a percentage.** Show the passages. A
percentage without them is the thing to avoid.

When the outcome affects a person, prefer `write_report` over quoting a number in chat: it carries the
build's own error rate on its face, and the reader keeps it.

## When the answer is "I don't know"

Say it. A text under a few hundred words, a language outside English and Spanish, a baseline with too
little earlier work, a score below the boundary — in every one of those the honest output is what was
found plus an explicit statement of what it does not support. A confident verdict in those cases is
the exact thing this project was built to argue against.

## Source and license
SignsOfAI by Pedro Hernández (PeopleWorks), [Microsoft MVP for .NET](https://mvp.microsoft.com/en-US/mvp/profile/24060a02-dbc6-44ec-bca5-c213ff9835c5) — an explainable, bilingual,
privacy-first writing-integrity toolkit. Repo: https://github.com/peopleworks/SignsofAI · MIT.
Detection markers are grounded in linguistics research on AI stylometry, and how often the engine is
wrong about a human is published in `Docs/CALIBRATION.md`, with the corpus and the method beside it.
10 changes: 10 additions & 0 deletions commands/gemini/signs-of-ai.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
description = "Measure a text for the signs of AI writing and report the evidence, never a verdict about the writer"
prompt = """
Activate and follow the `signs-of-ai` skill. Apply it to the request or document below.

{{args}}

If no text was supplied, ask the user to paste or identify it. Report what was measured, quote the
phrase behind each finding, and print this build's own false-positive rate beside any score. Do not
state or imply who wrote the text — the engine cannot determine that and neither can you.
"""
Loading
Loading