Deterministic, numeric style-conformance for prose. Calibrate stylometric bands from your own writing, then gate any draft against them and get measured deltas back, not vibes.
AI prose regresses toward the model's house voice. The expensive part of using it is not drafting, it is revising the output back into your own voice, and "make it punchier" is not a spec. voicegate makes style measurable: it reads your real backlist, learns the numeric bands your writing actually occupies, and tells a draft exactly which knobs are out of range and by how much.
- No accounts, no server, no telemetry. A local CLI.
- Calibrate on your own writing. Not on any named author. Your text is ground truth.
- Pure standard library. No third-party dependencies. Python 3.10+.
git clone https://github.com/Rodder5/voicegate
cd voicegate
pip install -e .
No dependencies beyond the Python standard library (3.10+).
Point it at a folder of your own work (.txt, .epub, .docx):
voicegate calibrate ./my_backlist -o my_voice.bands.json
It measures each text and writes a bands file: for every feature, the low/high range your writing occupies, padded so all of your own texts pass. The bands are derived so your real writing is guaranteed to pass its own gate. They describe you, they are not an aspiration.
voicegate score chapter_7_ai_draft.txt -b my_voice.bands.json
FAIL chapter_7_ai_draft.txt (2500 words) - 3 feature(s) off:
- words_per_sentence = 20.83, above band [16.07, 19.12] (lower by ~1.71)
- dialogue_pct = 17.84, below band [28.47, 47.25] (raise by ~10.63)
- figurative_per_1k = 7.6, above band [0.3, 2.1] (lower by ~5.5)
Exit code is 0 on pass and 1 on fail, so it drops straight into a writing pipeline or a pre-commit hook. Add --json for machine-readable output.
The defaults are genre-neutral: punctuation, sentence shape, dialogue share, question habits, profanity rate, and figurative density. What makes a result "your voice" is not the feature list, it is the bands calibrated from your text.
| feature | what it captures |
|---|---|
words_per_sentence |
sentence length, the backbone of rhythm |
mean_word_length |
diction weight, plain vs latinate |
dialogue_pct |
share of words inside quotes |
profanity_per_1k |
how coarse the register runs |
dialogue_questions_per_1k |
banter that asks vs states |
interior_questions_per_1k |
narrator self-interrogation |
exclamation_per_1k |
how often the prose raises its voice |
andbut_starts_per_1k |
sentences opening on And/But, a real rhythm signature |
figurative_per_1k |
similes and asides per 1,000 words |
longest_plain_run |
longest stretch of plain sentences before a figure, the dynamic range |
You can add your own tic features with a small JSON file, no code required:
{ "hedges": { "pattern": "\\b(sort of|kind of|a bit)\\b", "flags": "i" } }voicegate calibrate ./my_backlist --features tics.json -o my_voice.bands.json
Large language models regress toward a figurative density of roughly 7 to 8 similes-or-asides per 1,000 words. If your own voice sits below that floor, and many strong voices do, a model cannot reach it from above. It will keep adding figures you did not write, and no prompt fully stops it.
voicegate reports this. When your calibrated figurative band tops out below the floor, calibrate prints a reachability note:
! reachability: figurative_per_1k band tops out at 2.1, below the measured model floor 7.5.
A language model regresses toward ~7.5 and will struggle to write this sparely.
Measure your own model and set --floor accordingly. The point is simple: measure the voice before you promise it.
Using Jane Austen and Charlotte Bronte from Project Gutenberg (the repo ships small slices as test fixtures):
# learn Austen's bands from three slices of her prose
voicegate calibrate ./austen -o austen.bands.json
# an Austen slice passes her own gate
voicegate score austen_2.txt -b austen.bands.json
# PASS - in voice on all features.
# a Bronte slice does not: longer sentences, less dialogue, far more figurative
voicegate score bronte_1.txt -b austen.bands.json
# FAIL - 6 feature(s) off ...
Both authors calibrate below the model floor, which is exactly the finding: nineteenth-century literary prose is sparser than a modern model's default register, and cannot be reproduced by turning the temperature down.
Same input, same output, every run. No randomness, no network, no model calls. voicegate does not rewrite prose and does not judge quality. It measures conformance to a target you define, and hands the revision back to you with numbers.
MIT. See LICENSE.