Open Source · JavaScript

# human

Counts the AI tells in a draft and exits with an error if one goes over budget. It takes one pattern, looks for it in every paragraph, heading and quote of the document, and prints the number. 32 detectors and 4 rhythm measures, in Spanish and English.

[Try it here](/en/app) [View on GitHub →](https://github.com/e1i0r/human) [npm](https://www.npmjs.com/package/@e1i0/human)   $ `npm install -g @e1i0/human`

## A model cannot find its own tells

The other tools ask a model to read a draft and grade it. That model finds nothing, because the prose sits exactly where it would have put it.

I watched it happen building this. In one pass of fixes over this page, the counter found six new tells I had written while removing the old ones. Not one of them looked suspicious when I read it back.

```
$ human draft.md
draft.md   3 units · 6 sentences · 43 words

  HARD
  !  banned vocabulary                3
        L1     What this system does is coordinate processes and moreover, it does so well.
        L3     It is not just a tool, it is a platform, comprehensive and complete.
        L3     It is important to note that this matters for the team.
  !  negation framing                 1
        L3     It is not just a tool, it is a platform, comprehensive and complete.

  REVIEW
  ?  pseudo-cleft                     1
        L1     What this system does is coordinate processes and moreover, it does so well.
  ?  anaphora                         2
        L5     Nobody looks.  ||  Nobody measures.
        L5     Nobody measures.  ||  Nobody notices.

  RHYTHM
  ! spread, longest to shortest     11   >= 20   FAIL
  ! share in the 10-20 band         50   <= 49   FAIL

4 over budget
```

That is the short mode. The full one prints all thirty-two with their counts, zeros included, because if it only tells you "looks clean" you have no way of knowing it checked: a broken detector looks identical to one that found nothing.

Exit code is the number of budgets exceeded, so it drops into a pre-commit hook or a CI job unchanged.

## Three levels, and separating them is what makes it work

Mixed together, the real findings sit under a pile of false positives, and then you open the report once and never open it again.

HARD · 6 detectors

### The pattern settles it

Em dashes, semicolons, curly quotes, banned vocabulary, the negation that leads with what a thing is not, and the AI transitions. Over budget fails the build.

REVIEW · 26 detectors

### You decide

The pattern points and cannot rule, so each one carries beside it the legitimate version it gets confused with.

RHYTHM · 4 measures

### The shape of the sentences

Spread between longest and shortest, how many land between 10 and 20 words, whether a short one exists, and three in a row the same size.

Four of the twenty-six apply to Spanish only: peninsular vocabulary in a text written for Latin America, English idioms translated word for word, the possessive that turns a yes or a no into a thing ("esperando tu sí"), and the thesis word where you were about to write the plain one (enunciar for decir).

## The counts arrive without anybody asking

A skill cannot make anybody follow it, and a hook does not need anybody to remember. Three entries in `~/.claude/settings.json`, and one command removes them.

before

### Writing

Hands over the register the project declared. Read it after the draft exists and you read it too late.

after

### Write, Edit

Counts that file. Nothing prints when there is nothing to look at: talk after every edit and somebody uninstalls you inside a week.

after

### Bash

Asks git which prose files you touched. A heredoc rewriting a page arrives as a Bash call, and the Write hook never sees it.

## The thresholds come from prose you already trust

Every number here is a judgement somebody made once. `human-calibrate` measures prose you already trust and replaces those numbers. I tried it on 34,250 words of one author, 29 pieces: the hard rules did not fire once. The runs-of-three measure did, and it was set wrong. The threshold was zero and that author's own median is three, so it was marking their ordinary rhythm as a fault.

The corpus has to be prose this tool never touched, and that rules out most of what you have. Your chat history does not go through a model, so `human-voice` reads your own messages and writes the profile. That file stays on your machine. There is nothing to publish: whoever runs it against their own history gets theirs.

## What a pattern cannot do

Five of the six hard ones have an automatic fix. The sixth is the negation that leads with what a thing is not, and there is no function for it. Changing it means saying what the thing is, and a regex does not know that.

It does not read either, so it never catches a number that contradicts another number or a term used ninety lines before it is explained. An earlier version of this page came back clean from all 32 detectors. I asked somebody who had not written it to read it, and they found thirty things: a count that did not add up, a sentence shape repeated six times, three English idioms translated word for word on a page that sells catching those. That reader cannot be whoever wrote the draft, and the skill carries the prompt for sending one in.

## Try it without installing anything

It underlines every finding in the text. For the five with an automatic fix it shows you the change before applying it, with a button that says what it will do. No server receives the text, which is the only honest way to offer this when what you are pasting is not published yet.

[Open the editor](/en/app)

## Needs Node 20 or newer, and pulls in no dependencies

MIT. The pattern catalogue comes from [harshaneel/humanize](https://github.com/harshaneel/humanize). What I added: the Spanish patterns, the order they get checked in, and counting instead of asking a model for an opinion.

[View on GitHub →](https://github.com/e1i0r/human) [Other projects](https://e1i0.com/en/projects/)
