Perpetūra, part 3: voice as a spec
Perpetūra has a style guide as precise as a code contract, and it’s the document I’d rescue first from a fire.
The prose system
The guide defines a texture target: roughly 60% plain sentences, 30% reflective, 10% peak. If every sentence reaches, none of them land. It also names specific patterns by name, so during revision they can be pointed at clearly rather than argued about vaguely.
The mechanical subset lives in prose-check.js, running in CI on every push.
Em-dashes outside interrupted dialogue and American spellings fail the build.
Softer patterns (negation chains over budget, five-and sentence cascades)
warn and leave the call to a human. The linter’s own docs admit the limit:
it catches mechanics, not judgment.
The newest instrument is a register profiler. The drafts are mine; AI touches prose only in refinement passes. And refinement has a failure mode of its own: calibrate each chapter against its neighbour and the voice drifts wave by wave, invisible by eye because every adjacent pair reads fine. So every chapter is now measured against the story’s trunk on mechanical proxies (contractions per thousand words, sentence length, dialogue share) and has to land inside that story’s own numeric band before it counts as done.
Voice wasn’t found in one pass. The git history shows Hyunjae rewritten four times, v2 through v5, the diffs shrinking each round until the last one locked it in and updated the bible. Later voice work got surgical; there are commits like “collapse three ‘Not…’ negation chains into comma tricolons” and “break the uniform ‘and… and…’ climax cadence.”
The council
For editorial review I built a skill that convenes a council. Five lenses (romance, craft, architecture, canon, series), each reviewed by its own agent, plus an external bench of non-Anthropic models for cross-vendor disagreement. Findings go through a debate round, then an adversarial verify pass where a skeptic tries to kill each finding against the actual prose. What survives lands in a report, prioritized P0 to P2, with file-and-line locations. The council never edits. It argues; I adjudicate. I love that the reports preserve the disagreements the council couldn’t resolve: those are reliably the most interesting notes in them.
My favorite finding so far, from Reine’s review: two chapter closings “state the route verdict outright,” breaking the house rule that a closing may carry feeling and action but never the verdict. A machine caught me moralizing my own ending. I fixed it, and the rule got stronger.
There’s a separate continuity auditor for the things no linter reaches: semantic invariants like “this character must read alive on every branch” and “this object exists on one route only.” One reader agent per route, a synthesis pass across them, then a skeptic per finding. Same shape as the council: machines report, the author decides.