# Inkhaven 1.4.12 — Narrative voice profiling

_A writer finishing chapter 40 of a long novel has no way to answer the question: does chapter 40
read like the person who wrote chapter 1? Sentence rhythm, hedging density, interiority, and sensory
balance are all measurable **without an LLM, without a parser, and without any external dependency** —
and nothing in Inkhaven measured them. NARR-1 fills that gap. `inkhaven prose` produces a
deterministic, chapter-ordered voice fingerprint for every book, stores it, exposes it via CLI and
Bund, and surfaces chapter-level drift as informational findings in the Output pane. It **measures;
it never prescribes.** Five languages are first-class: **EN, RU, DE, FR, ES.** **No new runtime
crates.**_

_Plan: [NARR-1_PLAN.md](../PROPOSALS/NARR-1_PLAN.md)_

## Profile your book

```sh
inkhaven prose profile          # compute + print the per-book voice profile
inkhaven prose profile --deep   # + Tier-2 (sensory balance, active/passive ratio)
```

The metrics, all deterministic:

- **Tier 1 (language-agnostic)** — sentence-length distribution (p10–p90),
  **coefficient of variation** (a falling CV across chapters = a voice narrowing), **burstiness B**,
  and **MATTR** (length-corrected lexical diversity).
- **Tier 1 (language-sensitive)** — **modal density** (epistemic hedging — broader than modal
  auxiliaries: German Konjunktiv II, French/Spanish conditional/subjunctive adverbs) and
  **interiority ratio** (free-indirect-discourse markers; German *erlebte Rede* particles reported
  separately).
- **Tier 2 (`--deep`)** — **sensory channel balance** (visual/auditory/olfactory/tactile/kinesthetic)
  and **active/passive ratio** (per-language detection).

Every language-sensitive metric has a complete curated word list for all five languages; a book in
an unsupported language still gets the full Tier-1 rhythm tier plus a note.

## See where the voice drifted

```sh
inkhaven prose drift                       # each chapter vs the baseline
inkhaven prose drift --mode rolling        # adjacent chapters
inkhaven prose drift --reference <project> # vs another project's book (a series)
```

Drift lists each chapter's ΔCV / ΔMATTR / Δmodal / Δinteriority plus the **threshold crossings** —
the metrics that moved past their configured limit vs the baseline chapter. `inkhaven prose suggest`
explains how to read each one.

## From the editor — `Ctrl+V V`

**`Ctrl+V V`** (Voice) runs the check in the **background** — **content-hash lazy**, so only the
chapter you just edited recomputes, and **zero-AI / zero-cost** (no provider, no budget). Any
threshold crossing lands in the **Output pane** as an informational `prose` finding that navigates
to the chapter. **`Ctrl+V Shift+V`** toggles **ambient** mode (off by default): re-run after an
editing pause, gated by a cooldown floor.

## Notes

- **Self-gating, zero-cost.** Nothing runs until you ask (CLI / `Ctrl+V V` / opt-in ambient); the
  background check never calls an LLM. Profiles live in a new `.inkhaven/prose.duckdb`, invalidated
  by a content hash; a language change recomputes only the language-sensitive metrics.
- **Scripting** — read-only `ink.prose.{profile,drift,violations,refresh}`; the `prose:` config block
  tunes the window / thresholds / language and accepts `extra_modal_tokens` for genre-specific
  hedging. Structural paragraphs (STRUCT-2) are reduced to prose; Jinja templates (STRUCT-1) excluded.
- **No new runtime crates.** Built on the existing `.typ` + DuckDB + `regex` stack. New tutorial 95.
- Also: the **Output pane** gained `Home` / `End` / `PageUp` / `PageDown` navigation.
- Tests 1952 → 1996.
