"A spell checker knows the dictionary. A voice checker knows you. Rekindle's second decoration job is the second kind."
Job Two — a Voice Checker, Not a Spell Checker
The second job of the decoration engine is one nothing else in the world ships: a live voice checker. As you write, it underlines phrases that trip a voice rule — a register slip, a token-mirror trap, an over-forceful word choice — and floats a small margin note explaining why. A spell checker measures your text against a dictionary everyone shares. A voice checker measures it against your doctrine: the specific traps and preferences one writer has decided matter. It's the same underline-in-place UX as spell check, pointed at something personal.
A concrete example from the doctrine: a documented Korean rule flags 박다 — an over-forceful verb — where a softer choice fits the register. That's not a grammar error; no general tool would ever catch it. It's a voice rule, and only a voice checker built around one writer's doctrine can enforce it.
The Single Detection Boundary
Mechanically, it's marks plus a widget: underline the offending range (mark) and attach a note beside it (widget). All the intelligence hides behind one function, detectVoiceIssues(doc), which returns character ranges and notes. Today the detection is deterministic rules in TypeScript; later it can move to a Rust voice-engine substrate, or grow an AI-judgment layer — and the decoration code won't change, because it only ever consumes ranges. The boundary is the whole trick: keep 'what counts as an issue' behind one function, and 'how we draw it' stays identical no matter how detection evolves.
type VoiceIssue = { from: number; to: number; note: string };
// Detection is one boundary. Rules today; Rust or AI-judgment later —
// the decoration layer never changes, because it only consumes ranges.
function detectVoiceIssues(doc: string): VoiceIssue[] { /* ... */ }
Same Engine, New Purpose
Step back and notice: this is the exact machinery of Live Preview, aimed at a different question. Live Preview asked "where is markup?" and drew marks. Voice underline asks "where is a voice issue?" and draws marks plus a note. Same primitive, new input. That's the track's thesis arriving for the second time — and the reason a genuinely novel feature (a voice checker that exists nowhere else) cost almost no new machinery to build.