# Release notes

Per-release write-ups for every published Inkhaven version. Each
file walks through what changed at user-facing granularity — new
chords, new modals, new config knobs, new CLI subcommands — plus
migration notes when the on-disk shape moved.

The point of these is **continuity**: a writer coming back to the
TUI after a few months should be able to read one or two notes and
see what they missed without trawling the git log.

| Version  | Released   | Notes                                | Highlights |
| -------- | ---------- | ------------------------------------ | ---------- |
| **1.3.29** | 2026-06   | [`1.3.29.md`](1.3.29.md)          | **Inner Socrates, in conversation.**  A focused follow-on to 1.3.28 — the Socratic interrogator (RFC INNER_SOCRATES-1; reference [`INNER_SOCRATES.md`](../INNER_SOCRATES.md)) becomes **interactive**.  The AI pane's **F9** scope cycle gains **Socrates** (after Facts): a sticky **conversation** scope that seeds the chat with the active Reader Persona's voice + the open paragraph's questions, then hands you the prompt (the persona discusses; it never drafts your prose) — the same conversation `Ctrl+B J → C` opens, now in the standard scope cycle, with the scope shown in the AI header.  **Per-finding outcomes** on a Socratic question in the **Output pane**: **`i`** record-as-intent (declare the category a deliberate choice, chapter-scoped — writes an intent-ledger entry that stops the question here), **`m`** make-note (a **Socratic Notes** entry quoting the question + the passage with room for your response), **`x`** mark-addressed, **`d`** dismiss (still feeds the promotion mechanism); each dismisses the message once handled, and the Output footer advertises them.  Completes INNER_SOCRATES-1's interactive layer.  **Zero new deps.**  Tests 1713 (stable). |
| **1.3.28** | 2026-06   | [`1.3.28.md`](1.3.28.md)          | **Inner Socrates.**  A third examined-authorship pillar (RFC INNER_SOCRATES-1; reference [`INNER_SOCRATES.md`](../INNER_SOCRATES.md)) — the ConLang Suite examines your languages and the world simulator your world; **Inner Socrates examines your prose**, surfacing **questions** (never corrections) about the assumptions it treats as given, the framings it presupposes, the tensions inside it, what each scene does for the work.  Two tracks like the world fact-checker: a **Fast track** (deterministic, instant, no LLM — 7 categories: asserted necessity / hedging / structural patterns / unattributed dialogue / sentence length / tense shifts / pronoun ambiguity, five languages, ambient on a writing pause or `Ctrl+B J → F`) and a **Slow track** (the configured LLM, cost-capped — 5 prose categories: hidden assumptions / internal tensions / framings / significance / echoes, plus 3 that read the prose against the project **timeline**: dramatization gaps / implications / temporal density).  Three severities — **Notice** (hidden by default) / **Inquiry** / **Probe** — onto the Output pane.  **Five Reader Personas** (Inner Socrates, the Careful Editor, the Skeptical Reader, the First-Time Reader, the Slow Reader), each calibrated to read differently; author your own (`persona new`, or `Ctrl+B J → N` AI wizard), stored at `~/.config/inkhaven/personas/` or the new **Intent** system book (the 13th).  The **intent ledger** — the prose sibling of WORLD-4's magic ledger, same vocabulary — suppresses what you declared deliberate; a **promotion mechanism** builds it from repeated dismissals, and **`.isl` bundles** carry series-level intentions to the next book.  A **conversation** mode (`Ctrl+B J → C`) seeds the AI pane with the persona's voice + the paragraph's questions to talk it through (it discusses, never rewrites).  Full CLI (`inner-socrates check / timeline / persona / suggestions / bundle / findings`) + read-only `ink.inner_socrates.*` Bund words.  Also ships **WORLDBUILDING.md**, the WORLD-4 reference.  **Zero new deps** (all inherited from PANE-1 + WORLD-4).  Tests 1658 → 1713.  One new tutorial (78). |
| **1.3.27** | 2026-06   | [`1.3.27.md`](1.3.27.md)          | **The world, mapped (and a deeper checker).**  1.3.25 built a world and 1.3.26 read your prose against it; 1.3.27 **draws** the world and deepens the checker (RFC WORLD-4, toward P7; plan [`WORLD-4_PLAN.md`](../PROPOSALS/WORLD-4_PLAN.md)).  **Maps** — **`inkhaven realworld map`** emits a **MapSpec v2** from the compiled geology / climate / hydrology / demographics layers and renders it with [**plakat**](https://crates.io/crates/plakat) (`plakat map --map-spec` loads our spec and skips its own LLM): a **features PNG** + a **GeoJSON** under `assets/maps/`, mountain ranges clustered from the heightfield, rivers tracing their real D8 course, settlements as landmarks (coastal cities → ports), and the resolved positions read back to **refine each accepted Place's coordinates** (`--spec-only` / `--no-ingest`; `Ctrl+B W → M`; plakat optional — a missing binary degrades to a notice).  **A deeper fact-checker** — a **slow track** (`fact-check --slow`) asks the LLM for the subtle contradictions patterns miss, with a **cost preflight** (estimated tokens + daily tally), a per-call soft cap (`--max-cost` / `--force`), a daily ceiling, and **retry-with-backoff**; a **coherence pass** (`realworld coherence <node>`) checks a run of paragraphs **against each other** citing the `¶` numbers; **scope chords** (`Ctrl+B W → F →` `P` paragraph / `B` book / `R` recent); an opt-in **idle auto slow-check** (`Ctrl+B W → S`); and a fifth fast category, **economy** (a metal worked that the geology doesn't yield).  **Multilingual & never-fail** — place names resolve in their **grammatical cases** (`в Москве` matches `Москва`; German genitive), detection reports a **confidence** and degrades to English rather than guessing, the optional enhanced parser (`INKHAVEN_LANG_MODEL`) is never required, and detection never panics.  **Author-declared setting** — optional `geography` / `hydrology` / `economy` blocks + expanded `geology` materialize into a **Setting** chapter; **declared landmarks** become gazetteer entries resolved by name and **declared resources** join the checker's known goods.  Ships a complete [`examples/realworld/Earth.hjson`](../../examples/realworld/Earth.hjson) and fixes the stale World overview panel.  **Zero new deps** (plakat is an optional external binary; the MapSpec + GeoJSON use `serde_json`).  Tests 1625 → 1658.  Two new tutorials (76, 77). |
| **1.3.26** | 2026-06   | [`1.3.26.md`](1.3.26.md)          | **The World Fact-Checker.**  The other half of the world simulation (RFC WORLD-4 Branch B, fast track; plan [`WORLD-4_PLAN.md`](../PROPOSALS/WORLD-4_PLAN.md)) — 1.3.25 built a world; 1.3.26 reads your prose and flags claims that don't fit it, **as you write**.  A **magic ledger** (`magic:` block in `world.hjson`) declares your world's exceptions to physics — each rule names a `kind`, the categories it `covers`, and who/where it applies to; the checker consults it **lazily** (only after a candidate warning) and suppresses covered, applicable findings with a note instead of nagging.  The **fast-track fact-checker** is deterministic + instant (no LLM), four categories: **travel time** (distance + duration → implausible pace, pure prose), **climate** (weather contradicting a place's climate zone), **demographics** (a population far from the modeled figure), **astronomy** (a moon count vs the world's sky).  Climate + demographics resolve place names through a **gazetteer** built from the Place↔World cross-references — closing the loop (compile → accept cities → write → check).  **Real-time**: when a project has a world, pausing on a paragraph runs the check and the findings appear in the **Output pane** (no chord, no focus stolen; a re-check replaces the paragraph's prior findings).  Explicit forms: **`Ctrl+B W` → `F`** (open paragraph) and headless `inkhaven fact-check --text "…"`.  The `Ctrl+B W` hub gains `F` alongside `C` (compile) and `P` (proposals).  **Zero new deps** (reuses `regex` + the DuckDB stores + the Output pane).  Non-breaking + opt-in (only runs with a `world.hjson`).  Tests 1613 → 1625. |
| **1.3.25** | 2026-06   | [`1.3.25.md`](1.3.25.md)          | **World Simulation.**  Inkhaven gains an actual simulated world — a new **`inkhaven realworld`** compiler turns a structured `world.hjson` into a coherent, physically-grounded world materialized into a new **World** system book (first slice of RFC WORLD-4, the compiler half; plan [`WORLD-4_PLAN.md`](../PROPOSALS/WORLD-4_PLAN.md)).  Five **deterministic** layers, each a pure function of `(definition, seed)`: **astronomy** (Kepler year, insolation, lunar synodic periods, tides, calendar-divergence flag), **geology** (seed → tectonic plates → procedural heightmap → continents / mountains / minerals, or **DEM import**), **climate** (zonal model — stellar-flux mean, latitude profile, elevation lapse, rainfall belts + orographic rain shadows → Köppen biomes + winds), **hydrology** (D8 flow → rivers with Strahler order → lakes → watersheds → settlement priors), **demographics** (biome carrying-capacity → a Rank-Size hierarchy of cities / towns / villages).  Each **materializes** into the World book (10th, after Artefacts) + a heightmap PNG; idempotent.  A **proposal queue** turns settlements into named **Place** records you accept/reject (`realworld propose` / `proposals …`), recording a **Place↔World cross-reference** on accept; re-running never re-proposes a resolved site.  **`Ctrl+B W`** is the World overview hub — **`C`** compiles + materializes + seeds the queue, **`P`** reviews proposals.  Also **completes RFC PANE-1**: per-kind `Enter`, `e` edit+remember, `ai_task_complete` notices, bare-`print` mirror, Output as the default launch pane; new **`Ctrl+B D`** deterministic translation + lexicon/variety routing (focus mode → `Ctrl+B Shift+W`).  Two pure-Rust deps (`noise` + `delaunator`, geology only); else zero new deps.  Non-breaking.  Tests 1582 → 1613. |
| **1.3.24** | 2026-06   | [`1.3.24.md`](1.3.24.md)          | **The Output Pane.**  A new right-side **Output** pane for structured one-way notifications from every subsystem — the first slice of RFC PANE-1, the planned TUI rearchitecture (plan [`PANE-1_PLAN.md`](../PROPOSALS/PANE-1_PLAN.md)).  The AI pane stays a conversation; Output absorbs everything Inkhaven *tells* you.  **Zero new deps** (reuses DuckDB / ratatui / Bund VM / chords).  **`Ctrl+B Tab` / `Shift+Tab`** cycle the right region between Output and AI (default AI; launch view unchanged); messages carry a severity icon (`●`/`⚠`/`⊗`/`↻`) + kind + summary, pinned on top, with per-message `o` expand (a translation's per-word trace renders inline) · `d` dismiss · `p` pin · `r` **remember** (commit a translation to memory) · `a` **ask the AI** (carries the message's full detail into the conversation by reference, not value).  Persisted in a per-project DuckDB store; headless CLI `inkhaven output show|emit|dismiss|clear`.  **Translation (LANG-3)** routes into Output (`translation_result` + a `⚠` uncovered-word report); new **Bund `ink.io.*`** stdlib (print/log/notify/message.*) gives script output a home in the TUI.  Non-breaking; the shell CLI is unaffected.  Tests 1576 → 1582. |
| **1.3.23** | 2026-06   | [`1.3.23.md`](1.3.23.md)          | **Local Translation: the ConLang Suite learns to translate.**  A constructed language can now be **translated** — English↔conlang and conlang→conlang — fully offline, deterministically, improving as you correct it (core of RFC LANG-3; reference [`CONLANG.md`](../CONLANG.md)).  **Python-free, training-free, zero new deps.**  **Tier 1 (rule-based)** — **`language translate`** maps each English word to a headword by its lexicon gloss and hands the clause to the LANG-1 syntax engine, so it reorders + inflects for free (*the bird sees the stone* → `kira nami pata` SVO / `kira pata nami` SOV); lexicon-aware parsing (verb by meaning, adjective agreement, number); **`reverse`** (conlang→English) and **`cross`** (conlang→conlang via an English pivot), each with a per-word confidence + trace.  **Tier 2 (retrieval, not a trained model — Amendment A1)** — the corpus *is* the knowledge, so it's retrieved via the in-binary `fastembed` + vector store: **`remember`** confirms a translation reused immediately (no retraining; exact overrides with the rule-based kept as an alternative, near matches are **semantic**), **`corpus`** seeds from a bundled English pool, **`eval`** scores quality reference-free (round-trip + coverage), **`export-translation`** ships the system as a portable `.itm` pack.  Full Bund surface (`lang.translate`/`reverse`/`cross`/`remember`/`memory`/`corpus`/`eval`/`export`).  Tests 1548 → 1576. |
| **1.3.22** | 2026-06   | [`1.3.22.md`](1.3.22.md)          | **The ConLang Suite: Sociolinguistics & Contact.**  A whole new pillar (RFC LANG-2) — a constructed language stops being uniform and lives among its speakers and neighbours (reference [`CONLANG.md`](../CONLANG.md)).  The insight: a **dialect is a sound-change chain applied synchronically** and a **loanword is a phonotactic repair**, so the features mostly orchestrate the LANG-1 engines.  **Variation** (`varieties` block) — a variety is a delta of ordered `sound_changes` + suppletive overrides; **`language varieties`** / **`lect`** (render in a dialect, `kata` → `kada`) / **`dialects`** (the dialectology table).  **Borrowing** (`loan_phonology` block) — **`language borrow`** adapts a donor word by perceive (nearest native sound) + repair (epenthesis/deletion), `tras` → `tulasu`.  **Areal features / Sprachbund** (`contact` block) — **`language areal`** overlays convergence (✓ / → / +); `family-tree` gains horizontal contact edges.  **Speech communities** — places carry a `--variety`, characters a `--native-variety`; **`language ecology`** (+`--svg` atlas) and **`language idiolect`** render a character's own dialect.  **Grammar book** gains Variation + Contact sections.  **Advisory AI** — `propose-dialect` / `propose-loans` / `areal-check` (the AI proposes, the engine validates, `--yes`-gated).  Developer's guide gains Part VI (*A Language in a World*) and Part XI (*Scripting Your Language* — a gentle Bund intro + full API reference).  Deterministic core, advisory AI, zero new deps.  Tests 1533 → 1548. |
| **1.3.21** | 2026-06   | [`1.3.21.md`](1.3.21.md)          | **Scripting the ConLang Suite from Bund.**  Opens the whole ConLang Suite to Bund, Inkhaven's scripting layer — one script can define, inspect, generate, AI-author, and typeset an entire constructed language, interchangeable with the JSON/CLI path (reference [`CONLANG.md`](../CONLANG.md)).  New **`ink.lang.*`** tree (~37 words, also `lang.X`): **define a whole language** (`init`/`add_word`/`define` write the same HJSON blocks the book stores); **inspect every layer** (generate_word/syllabify/ipa/stress/tone/transliterate/gloss/paradigm/derive/agree/sentence/relative/complement/coordinate/stats/audit/query/gaps/sound_change/cognates/family_tree/names/prose/poem — results as native Bund dicts/lists); **mutate** (remove_word/derive_add/grammar_set/idiom_add/metaphor_add); **AI generation** (compose/reconstruct/realism_check/generate_lexicon — advisory); **produce files** (dictionary/grammar_book/font_build/glyph_lint/glyph_draft).  Native `lang.dict` builder aliased to `word`/`rule`/`phoneme`.  Classified into the scripting policy (store_read allowed; store_write/ai_write/fs_write default-denied); AI words advisory; sandboxed paths.  Book gains a *Scripting (Bund)* section + pastel-green "What you learned" recaps.  Zero new deps.  Tests 1531 → 1533. |
| **1.3.20** | 2026-06   | [`1.3.20.md`](1.3.20.md)          | **Complement clauses, and a deeper developer's guide.**  A focused follow-on to 1.3.19's syntax engine (reference [`CONLANG.md`](../CONLANG.md)).  **Complement clauses** (**`language complement`**) build a sentence whose object is a whole clause ("I know *that the bird sees the stone*") — the matrix subject/verb wrap an embedded clause via an optional complementizer; since the complement fills the matrix object slot, word order places it (post-verbal in SVO, pre-verbal in a verb-final language) and the embedded clause still case-marks its object.  Completes the syntax-depth set (sentence → negation → questions → relative → coordination → complement).  **Book** — new dedicated *interchange* chapter (Standard Format / Toolbox / FieldWorks / Lexique Pro, PolyGlot, ConWorkShop, CAT tools / XLIFF, Anki, linguex, with a CSV round-trip), plus a whole-book depth pass (20 new glossary terms; worked circumfix/ablaut/reduplication, sonority, tone-output, and family-tree examples; stale notes fixed), and a typographic fix keeping section headings off the bottom of a page.  Deterministic core, backward compatible.  Zero new deps.  Tests 1529 → 1531. |
| **1.3.19** | 2026-06   | [`1.3.19.md`](1.3.19.md)          | **The ConLang Suite: syntax, interchange & creative text.**  Makes a constructed language *speak* and lets it *travel* (reference [`CONLANG.md`](../CONLANG.md)).  **Syntax engine** — **`language sentence`** assembles a clause from subject/verb/object, ordering by `word_order`, case-marking by `alignment`, inflecting each noun, and running agreement, with an interlinear gloss (and the grammar book now prints a worked example from the lexicon).  **Negation + polar questions** (`--negate`/`--question`) realize per the `negation`/`question` typology (particle/affix; particle/inversion/morphology), never inventing a word.  **Relative clauses** (**`language relative`**) build "the bird that sees the stone" — the embedded clause case-marks and agrees, pre- or postnominal per `relative_clause`.  **Coordination** (**`language coordinate`**) joins nouns or clauses with a conjunction.  **Interchange** — `export` gains **xliff** (CAT-tool translation memory), **linguex** (LaTeX glossed examples), **ipa-chart**; **`language import`** reads **Toolbox / MDF / Lexique Pro** SFM and **PolyGlot** (`.pgd` zip + xml), previewing until `--yes`.  **Semantic-gap finder** (**`language gaps`**) diffs the lexicon against the bundled **Swadesh-100** (every working language) or a custom concept list.  **Creative text** (**`language compose`**) generates names, grammatical prose, metered verse, and lexicon-constrained AI blessings/curses.  Deterministic core, advisory AI, backward compatible.  Zero new deps.  Tests 1490 → 1529. |
| **1.3.18** | 2026-06   | [`1.3.18.md`](1.3.18.md)          | **The ConLang Suite: morphology depth & a developer's guide.**  Deepens morphology after LANG-1 completed, and ships a beginner's book (reference [`CONLANG.md`](../CONLANG.md)).  **Non-concatenative morphology** — a morpheme can be an **infix** (`sulat` → `s-um-ulat`), a **circumfix** (`form: "ge_t"`), an **ablaut** process (SPE `rules` swapping a stem sound), or **reduplication** (`full` / `initial_cv` / …); all used in paradigm cells like affixes, with allophony at every seam.  **Affix precedence** — `precedence` orders stacked affixes by closeness to the root.  **Agreement (concord)** — an `agreement` block + **`language agree`** inflects a dependent to match its head's features (`mira` → `mirai`, *bright-PL*).  **Grammar book** now groups affixes by `category`/`value` and shows each one's kind, with an agreement section.  **New book** — *Developing a Constructed Language with Inkhaven* (`Book/CONLANG_DEVELOPMENT/`), a ~120-page guide teaching the whole suite from zero for readers new to linguistics *and* Inkhaven.  Backward compatible; deterministic core.  Zero new deps.  Tests 1490 → 1498. |
| **1.3.17** | 2026-06   | [`1.3.17.md`](1.3.17.md)          | **The ConLang Suite (Part 4: the books) — LANG-1 complete.**  Turns a constructed language into typeset books (reference [`CONLANG.md`](../CONLANG.md)).  **Grammar book** (`grammar-book --format md\|typ`) — a reference grammar from the language's data (phonology / morphology / typology / idioms / sample texts), the companion to the 1.3.16 dictionary.  **Learner's textbook** (`tutorial --format md\|typ --provider …`) — **AI-written**: the model authors a complete graded course (introduction, pronunciation guide, lessons that *explain* the grammar with worked examples, a reading, exercises), constrained to the language's actual data — the prose is generated, never hardcoded.  **Study guide** (`grammar-book --study`) — an AI-written companion that defines + explains every linguistic term the grammar uses (case, allophony, SOV, nominative–accusative alignment, …); the reference itself stays deterministic.  **A book design** — dictionary, grammar, and tutorial share a manual-style B5 layout (title page, contents, callout boxes), embed the conscript font, and compile to PDF.  **A complete worked example** (`examples/conlang/build-sample-language.sh` + checked-in `sample-output/`) builds a whole language end to end with an AI-drawn font.  AI writes Markdown, a deterministic Markdown→Typst converter + scaffold makes it always compile.  Completes RFC LANG-1 (P1–P7).  Zero new deps.  Tests 1479 → 1490. |
| **1.3.16** | 2026-06   | [`1.3.16.md`](1.3.16.md)          | **The ConLang Suite (Part 3: writing systems, fonts & output).**  A constructed script goes from hand artwork or an AI description to a real TrueType font, a Typst layout, and a typed input method — fully in-process, no external tool (reference [`CONLANG.md`](../CONLANG.md)).  **Writing systems + fonts** — **glyph preflight** (`glyph-lint`; filled-paths-only, plus a counter-mistake warning on near-white fills); **SVG → UFO → TrueType** (`font-build --format ufo\|ttf\|both`; the TTF assembles a full OpenType table set with `write-fonts`, cubics quadified, passes a fontTools round-trip); **config-driven font block** (`font-import-glyph` binds a glyph to a phoneme + codepoint, `font-build --language` compiles the script from the book); **AI text-to-SVG glyph draft** (`glyph-draft`, advisory, preflight-gated, prompts reverse-wound counters — *validated live against DeepSeek*); **spatial templates** — one engine, two binding times: `font-compose` bakes a precomposed block (Hangul square / quadrat), `spatial-typst` arranges at layout time; **input method** (`transliterate`, greedy longest-key romanized → script).  **Analysis** — `stats` (inventory balance, phoneme frequency, syllable distribution, onset/coda usage, POS spread).  **Dictionary output** — `dictionary --format md\|typ`; the Typst path is a paginated two-column A5 book embedding the conscript font with native-script headwords.  Deterministic core, thin AI layer, advisory.  **One new dependency** (`norad`; `write-fonts`/`kurbo` reuse crates already in the tree, `fontc` deliberately avoided).  Tests 1439 → 1479. |
| **1.3.15** | 2026-06   | [`1.3.15.md`](1.3.15.md)          | **The ConLang Suite (Part 2: morphology & diachronics).**  Builds two whole pillars on the 1.3.14 substrate, each reusing the engines already in place (reference [`CONLANG.md`](../CONLANG.md)).  **Morphology completed** — **auto-gloss** (`language gloss` aligned Leipzig interlinear, recognising inflected + allophony-altered forms by generating paradigms forward and matching); **derived-form proposals** (`language derive` coins new lexemes — agent nouns, diminutives — with allophony); **grammar questionnaire** (`language grammar`, a WALS-aligned catalog of 16 typological features, `--set` validated); **idioms + metaphors** (`idiom-add` / `metaphor-add` / `idioms`).  **Diachronics** — a sound change *is* an ordered context rewrite, so the engine **reuses the allophony rewrite engine**: `language sound-change` (`tap > taf`), `derive-lexicon` (evolve a proto's whole dictionary through a daughter's chain), `family-tree` + `cognates` (a proto-form's reflex in every daughter), and the AI `reconstruct` (proto-form from cognates) + `realism-check` (chain plausibility).  Everything deterministic except the two AI checks + translation; AI advisory; extend-in-place (no new chapters).  Zero new dependencies.  Tests 1428 → 1439. |
| **1.3.14** | 2026-06   | [`1.3.14.md`](1.3.14.md)          | **The ConLang Suite (Part 1: phonology, lexicon, morphology).**  Inkhaven becomes the first constructed-language workbench *inside* the writing tool (RFC LANG-1; reference [`CONLANG.md`](../CONLANG.md)), layered on the existing 1.2.13 `Language` book.  **Phonology engine** — inventory / classes / templates / syllable-aware phonotactics → **allophony** (SPE rules `k > tʃ / _ i`) → **stress** (fixed or weight-sensitive Latin) → **bidirectional multi-scheme romanization** (contextual digraph disambiguation) → **tone sandhi**; deterministic word generator; six CLI inspectors (`generate-word` / `syllabify` / `ipa` / `stress` / `romanize` / `tone`).  **Lexicon + AI generation** — **`language generate-lexicon`** with a **complete dedup gate** (forms from the deterministic generator so they always obey the phonotactics; the AI assigns meanings in the working language; rejects illegal / homophone / duplicate-meaning / `--semantic` near-synonym via embeddings); plus `audit`, rich-field `query`, `scan-manuscript` (undefined words), and Places/Characters language links (sidecar).  **Morphology** — `language paradigm` applies a paradigm's morphemes to a root and runs allophony across the affix boundaries (`kata`+DAT → `katat`).  **In the editor** — `Ctrl+B X` ConLang hub overview + `:lang:` inline lexicon insertion.  Forms obey the language, meanings come from the AI, nothing duplicates; AI is advisory.  Flagship-in-progress (P3–P7 continue across 1.3.x).  Zero new dependencies.  Tests 1369 → 1428. |
| **1.3.13** | 2026-06   | [`1.3.13.md`](1.3.13.md)          | **Breadth: every language, cancellable jobs, print & ebook polish.**  Goes *wide* after the deep world-layer cycle.  **Cancel a deep refresh** — re-press `Ctrl+V Shift+F` and each scan honours a shared cancel flag between chapters/entities, stopping in seconds (finished scans keep their sidecars).  **Full multilingual** — the detector word lists no longer masquerade as English for an uncurated language (empty + honest); **`inkhaven lang status`** prints a coverage matrix and **`inkhaven lang bootstrap <lang>`** has the LLM lexicographer produce the full detector vocabulary (lemma form) for **any** language, `--yes`-patching `inkhaven.hjson` safely; all four world-check prompts are **localized** (en/ru/fr/de/es, English-with-warning fallback, 3-tier override) and force findings into the project language; detector config moved to per-language **maps** with worked Arabic / Hungarian examples.  **Print** — **`inkhaven pdf booklet`** is a zero-config saddle-stitch booklet auto-fitting the sheet to 2× the page (any trim), and the **`a5_book`** profile imposes a proper perfect-bound A5 codex from A4 sheets.  **Ebook** — EPUB export now embeds **inline images** (`<figure>` + OPF manifest) and **popup footnotes** (EPUB3 noteref/aside).  Zero new dependencies.  Tests 1359 → 1369.  One new tutorial (73). |
| **1.3.12** | 2026-06   | [`1.3.12.md`](1.3.12.md)          | **The background deep refresh.**  **`Ctrl+V Shift+F`** runs the whole world-layer AI batch (facts check + facts scan + drift + continuity, the `inkhaven world --deep` set, **in the manuscript's language**) on a **background thread** — the editor stays fully responsive, a `⟳ deep refresh` chip tracks progress, and the open story bible / Editorial Pass rebuilds itself from the fresh findings when it lands.  It runs in-process on a **clone of the editor's DuckDB connection pool** (single-writer lock means no second open; the pool is now tunable via `embeddings.pool_size`, clamped ≥2).  **Advisory** — reads your manuscript and writes findings to `.inkhaven/*.json` sidecars only; never edits your prose (rewrites stay manual via the Editorial Pass `f`/`F`, snapshot-gated + diff-reviewed).  **Stale findings announce themselves** — each scan stamps a cheap manuscript fingerprint, and the world report / bible / `edit` show `⚠ may be stale` (warn, never hide) when the prose has moved since.  Built on a reusable background-job harness the 1.4 AI Editor will reuse.  Zero new dependencies.  Tests 1354 → 1359. |
| **1.3.11** | 2026-06   | [`1.3.11.md`](1.3.11.md)          | **Drift depth + the world report.**  Rounds out world consistency (1.3.8 hard facts, 1.3.10 soft drift).  **Drift reads pronouns** — coreference-lite recovers pronoun-only descriptions ("Mara crossed the yard. She was taller…") via a precision-favouring recency anchor (single named entity per kind; ambiguity clears it; never crosses a chapter), with **multilingual** built-in pronoun sets (en/ru/fr/de/es) keyed by the project language and a Unicode-aware word-boundary check.  **`inkhaven world`** — one consolidated consistency snapshot (established facts + internal/prose contradictions + drift + continuity coverage + named anachronisms + a health summary); complements `edit` (walkable worklist) as a world-layer snapshot; `--json` gates CI, `--deep` refreshes the AI scans, `--entity <name>` zooms in.  The same health line banners the `Ctrl+V Shift+L` story bible.  **Coverage** flags entities defined in the books but never named in the prose (a dangling cast) — also an `info` `coverage` finding in `edit`, jumping to the bible definition.  `world` also names each anachronism + chapter; `drift list --entity` scopes the preview.  Zero new dependencies.  Tests 1346 → 1354. |
| **1.3.10** | 2026-06   | [`1.3.10.md`](1.3.10.md)          | **Semantic drift.**  The *soft*-consistency counterpart to 1.3.8: two descriptions of the same entity that diverge across the manuscript without a hard fact clash (a tavern "cramped and smoky" in ch.2, "airy and bright" in ch.20).  **Embeddings retrieve, the AI adjudicates** — cosine similarity finds same-topic descriptions but can't tell contradiction from relatedness, so drift reuses the **existing on-save vector index** to pull each entity's description paragraphs (keeping only the ones that name it), then asks the model which contradict.  No new index.  **`inkhaven drift scan`** writes `.inkhaven/drift.json` (`--json` gate); **`drift list`** previews the retrieval deterministically.  Surfaces in `inkhaven edit` + the `Ctrl+V Shift+R` cockpit as the `drift` category (Warn, **jump-only** to the divergent passage); `edit --deep` runs it.  The **`Ctrl+V Shift+L`** story bible shows a ⚠ drift badge + the chapter-ordered description trail under each flagged entity (persisted in the sidecar — no embedding load in the TUI).  Tunable via the `drift` config block.  This is the 1.4 Whole-Book AI Editor bridge — it builds the retrieve-then-reason loop.  Zero new dependencies.  Tests 1339 → 1346. |
| **1.3.9** | 2026-06   | [`1.3.9.md`](1.3.9.md)              | **Finish the Editorial Pass.**  Closes the four deferrals from the 1.3.6–1.3.7 cuts, taking the cockpit to its final 1.3 form.  **Span-scoped rewrite:** `f` on a localized finding now rewrites *only* the flagged phrase and splices it back (show-don't-tell / filter-word), leaving the surrounding prose alone; echo / pacing still rewrite the whole paragraph; the diff shows the full paragraph for context.  Pure char-indexed `splice_span` + `extract_phrase`, the span category marks the phrase between `« »` and asks for just its replacement.  **Filter-words join the worklist** — the last live-overlay detector not yet in `inkhaven edit`, surfaced as `filter` findings at `info` severity (sort last, never bury sharper findings), span-`f`-rewritable.  **Anachronism underlines live** in the editor (its own amber-orange `theme.style_warning_anachronism_fg`), self-gating on the setting `year` + the master style toggle.  **`F` batch fix-all:** walks every rewritable finding in the current filter through the *same* per-item diff review — never blind-applied; `a` accept+advance, `r` skip, `Esc` stop; progress + `N applied, M skipped` summary.  Quick-help / chord descriptions / Tutorial 68 refreshed.  Zero new dependencies.  Tests 1333 → 1339. |
| **1.3.8** | 2026-06   | [`1.3.8.md`](1.3.8.md)              | **World consistency.**  A long book builds a world (climate, geography, a cast with fixed attributes, a setting in time); the tools to keep it consistent were scattered.  1.3.8 fills the four remaining gaps.  **`inkhaven facts check`** runs an AI pass over the *whole* Facts book for contradictions between the facts themselves ("winters are mild" ⟷ "the harbor freezes each January"), cached + `--json`-gateable, also surfaced in `inkhaven edit` (category `world`).  **Anachronism detection:** set `editor.style_warnings.anachronism.year` and terms postdating it (a ~35-term built-in lexicon + your additive `terms`) flag in `edit` (category `anachronism`), jumpable to the word; off until a year is set.  **The story bible** — **`Ctrl+V Shift+L`** (L for Lore) — one consolidated, navigable view: every Character with the attributes `continuity extract` tracked across chapters beneath it, plus Places / Artefacts / Facts; `Enter` jumps to source.  **Series-shared facts:** point `facts.shared_path` at a directory of one-file-per-fact text files and a series shares one canon — `facts check` layers it (local wins), `facts import` snapshots it in.  Zero new dependencies.  Tests 1328 → 1333.  One new tutorial (69). |
| **1.3.7** | 2026-06   | [`1.3.7.md`](1.3.7.md)              | **Close the loop: AI rewrite-in-place.**  The Editorial Pass (1.3.6) *found* every problem and jumped you to it; 1.3.7 lets the AI *fix* the prose-level ones.  In the **`Ctrl+V Shift+R`** cockpit, a `✎` marks the rewritable findings — **echo** (vary the over-repeated word), **pacing** (tighten an overlong paragraph), **show-don't-tell** (rewrite telling to showing) — and **`f`** opens the finding's paragraph, streams a category-specific rewrite, and pops the diff-review (`a` accept snapshot-first, `r` reject), reusing the 1.2.11 rewrite→diff→snapshot machinery.  The rewrite prompt is 3-tier-tunable (`editorial-fix-<category>`).  Judgment findings (structure / continuity / fact / weak-scene) stay jump-only.  **Show-don't-tell** also joins the worklist as a finding (the editor overlay's regex, surfaced per paragraph with a char-range location).  Zero new dependencies.  Tests 1326 → 1328. |
| **1.3.6** | 2026-06   | [`1.3.6.md`](1.3.6.md)              | **The Editorial Pass.**  The 1.3 capstone (the "editorial-pass cycle" flagged back in 1.2.22): unify every detector into one ranked, walkable revision worklist.  **`inkhaven edit`** collapses the editorial `doctor` classes (echo / pacing / continuity / naming / dropped-character / …) + `plan check`'s structural findings + the Facts-scan sidecar into one list, errors first; deterministic (reads computed sidecars, no live AI), so `--json` gates a CI build and `--only` narrows it.  **`Ctrl+V Shift+R`** is the cockpit: `↑↓` navigate, `[`/`]` filter, **`Enter` jumps to the finding's chapter/paragraph** (the new capability — location resolution from a path / chapter title → node id), `s` skips, `d` defers (persisted, fingerprinted by text so it resurfaces only when the prose changes), `D` clears.  **`edit --deep`** re-runs the AI scans (Facts / tension / continuity) then aggregates.  `edit` is *manuscript readiness*; `doctor` stays *project integrity*.  Zero new dependencies.  Tests 1321 → 1326.  One new tutorial (68). |
| **1.3.5** | 2026-06   | [`1.3.5.md`](1.3.5.md)              | **Scene craft: scaffold, sequel, second opinion.**  Deepens the scene grain 1.3.4 opened.  **Scene scaffold:** `inkhaven plan scene scaffold --chapter <slug>` (or `--all`) reads the chapter prose and proposes the goal/conflict/disaster; in the `Ctrl+V Shift+K` scene board, `g` regenerates the selected card (proposal streams to the AI pane, `L` files it).  **Sequel cards:** `inkhaven plan sequel add\|list\|set\|remove` — the reactive counterpart (reaction → dilemma → decision); one unified card model (`Scene` gains `kind`, old cards load unchanged), weak-check flips by kind (scene = no turn, sequel = no decision), plus a two-scenes-in-a-row "unprocessed disaster" hint.  **Tension second opinion:** `inkhaven plan tension rate` AI-rates each chapter's felt intensity 0–100 (cached), adding an `ai` column to `plan check` and a third sparkline to the overlay beside expected + actual — two independent readings of where the middle sags.  Zero new dependencies.  Tests 1316 → 1321. |
| **1.3.4** | 2026-06   | [`1.3.4.md`](1.3.4.md)              | **The Planning Board — the shape of the rise and fall.**  Finishes pillar B (structure).  1.3.2 diagnosed where each beat *lands*; 1.3.4 adds what the Board couldn't see — **intensity** and **scene craft**.  **Tension curve:** every beat carries an *expected* intensity (the framework's authored dramatic shape) vs an *actual* one derived deterministically from open narrative obligations (the `inkhaven tension scan` ledger + open Threads), so a sagging middle is an objective finding ("Midpoint 33% where the framework wants 65%").  `plan check` prints a TENSION section; the **`Ctrl+V Shift+K`** outline draws expected/actual `▁`..`█` sparklines under the bars.  **Scene cards:** `inkhaven plan scene add\|list\|set\|remove` — each scene's goal → conflict → disaster, with a deterministic weak-scene (no-turn) check, folded into `plan check`, the `v` scene board, and `plan analyze`.  **Outline finished:** the deferred `t` (thread-link), `Enter` (jump-to-chapter), `v` (scenes) keys.  Zero new dependencies.  Tests 1307 → 1316. |
| **1.3.3** | 2026-06   | [`1.3.3.md`](1.3.3.md)              | **The Planning Board, fluent & complete.**  Finishes the Board opened in 1.3.2.  **Fluent:** `inkhaven plan map <beat> --chapter <slug> [--threads …]` / `plan unmap` write a beat's Planning-book HJSON in place, and `plan check` now prints the **CHAPTER SLUGS** / **THREAD SLUGS** to use — no slug-hunting.  The **`Ctrl+V Shift+K`** outline is editable: `m` maps a beat from a chapter picker, `s` cycles status, `a` streams the AI analysis (`L` in the AI pane files it into Planning).  **Complete (plan-first):** `plan scaffold --premise "<logline>"` writes a concrete intention into every framework beat; `--chapters` materializes back-linked chapter shells (opt-in, guarded).  **PDF-1 follow-ups:** three new imposition profiles (`us_perfect` / `us_chapbook` / `thick`), aspect-preserving cover art (`--fit cover\|fit\|stretch`) + spine-text auto-fit, JPEG (DCTDecode) grayscale, and preflight press-hazard reporting (overprint / transparency / spot colours).  **Polish:** CLI Prompts-book prompt tier, `stale-submission` doctor scan, `I`-lift of a streamed draft, `actions/checkout@v5`.  Zero new dependencies.  Tests 1294 → 1307. |
| **1.3.2** | 2026-06   | [`1.3.2.md`](1.3.2.md)              | **The Planning Board.**  Opens pillar B — *structure*, the third axis (Timeline = *when*, Threads = *arc payoff*, Planning = the skeleton).  Leads with **diagnosis, not card-shuffling**.  `inkhaven plan init --framework save_the_cat\|three_act\|story_circle\|hero_journey\|seven_point` scaffolds a framework's beats into a new **Planning** system book (HJSON paragraphs; map a beat with `mapped_chapter` + `threads`).  **`inkhaven plan check`** is the deterministic finding — coverage gaps, per-beat **position drift** (Midpoint at 64% vs target 50%), and **act word-share pacing** ("Act 1 is 30% — long"); no AI.  **`Ctrl+V Shift+K`** renders it as a position bar per beat.  **`inkhaven plan analyze`** (and `a` in the outline) maps beats→chapters + names the sag over the 1.3.1 digest.  Thread-links surfaced + validated.  Zero new dependencies.  Tests 1286 → 1294.  One new tutorial (67). |
| **1.3.1** | 2026-06   | [`1.3.1.md`](1.3.1.md)              | **Submission track.**  Pillar A's second half — getting a finished manuscript to an agent or editor, pure-Rust with no new dependencies.  **`.docx`**: `inkhaven docx` emits a hand-rolled Shunn-format Word document (the audit rejected `docx-rs` for hard-pulling a duplicate `zip` major version); `docx` is a `Ctrl+B O` book-take.  **Package (AI)**: `inkhaven submission digest` caches a compact whole-book context (per-chapter one-line summaries + Characters/Threads), then `submission query \| synopsis [--long] \| comps \| logline` draft into a new **Submissions** system book — synopses spoil the ending, comps are Local-pinned labelled suggestions.  `Ctrl+V q` picks a generator and streams it into the AI pane (3-tier prompt resolution).  **Tracker**: `inkhaven submissions add\|list\|status\|add-note\|remove` (the `.inkhaven/submissions.json` log) + the `Ctrl+V u` modal; `add-note` is a timestamped event trail.  Five `ink.export.*` Bund words (`fs_write`-gated).  Tests 1270 → 1286.  One new tutorial (66). |
| **1.3.0** | 2026-06   | [`1.3.0.md`](1.3.0.md)              | **Print production (PDF-1).**  The first minor since the 1.2 line — a complete, self-contained **PDF production subsystem** for taking a built book to a print shop or hand-binding bench, over a pure-Rust core (`lopdf` + `barcoders`, no external apps).  **Imposition** (the marquee): `inkhaven pdf impose` reorders a book into folding signatures — perfect-bound / saddle-stitch / side-stab, creep/shingling from the paper caliper, crop/fold/registration/spine/sig# marks, configurable through HJSON `imposition:` profiles (`--dry-run` plan, `Ctrl+B Q` TUI preview, `imposed_pdf` book-take).  **Cover + spine + barcode**: `pdf cover --pages N` computes the spine from page count + paper stock, with front art, back blurb, and a validated EAN-13 `--isbn` barcode (`cover_pdf` book-take; standalone `pdf barcode`).  **Preflight**: `pdf preflight` catches print-only problems — effective image DPI via CTM tracking (the screenshot-blown-up-to-full-page case), font embedding, page-size consistency, blanks.  **Page ops**: info / extract / delete / rotate / reorder / split / merge / metadata / outline.  **Finishing**: grayscale / optimize / watermark / sample.  All mirrored across CLI (`inkhaven pdf …`), the `ink.pdf.*` Bund stdlib, config (`imposition:` / `cover:` / `preflight:`), and `Ctrl+B O` book-takes.  Two new runtime deps (`lopdf`, `barcoders` — audited, pure-Rust, the first in several cycles).  One new tutorial (65).  Tests 1190 → 1270. |
| **1.2.23** | 2026-06  | [`1.2.23.md`](1.2.23.md)            | **Stability & fixes** — the last 1.2 before the 1.3 editorial-pass cycle.  Broken-pipe on stdout (`inkhaven … \| head`) no longer writes a spurious crash report (panic-hook Step 0, no SIGPIPE reset → TUI untouched).  Whole-tree **panic-surface re-audit**: fixed three UTF-8 byte-boundary slice panics (theme-colour parse, fact-check cursor jump, doctor naming scan — all reachable on multilingual / malformed input) and routed four `store` writes through `io_atomic`.  **SQL hardening**: the JSON/blob + progress stores now bind parameters instead of string-interpolating (both `sql_escape` copies removed; adversarial round-trip test).  **Find & replace polish**: `w`/`i`/`x` toggle whole-word / ignore-case / regex inside the review modal.  **D.8**: three copies of the manuscript walk collapsed into `Hierarchy::user_book_chapters()`.  Tests 1186 → 1190.  Zero new deps. |
| **1.2.22** | 2026-06  | [`1.2.22.md`](1.2.22.md)            | **Project-wide find & replace.**  The cross-book edit Inkhaven couldn't do — rename a character / term over the whole manuscript, safely.  Lexical (literal / whole-word / opt-in regex, *not* semantic) over a linear scan; no FTS index (the `regex` crate already in-tree → zero new deps).  In the editor: `Ctrl+R` → `Ctrl+B` toggles whole-book scope → a **review modal** shows every match in context, `Space` skips individual ones, `Enter` applies the kept ones — **snapshotting each touched paragraph first** (`F6` undo).  CLI: `inkhaven replace <pat> <repl>` with `--dry-run` preview + `--yes` apply (refuses to write otherwise), `--regex` / `--substring` / `--ignore-case` / `--book` / `--include-system`.  Whole-word + user-books-only by default (no `Will`/`will` footgun, won't touch Notes/Facts).  The review-gated apply machinery is the substrate for the 1.3 editorial-pass cycle.  Also: three consolidation-audit items closed as intentional non-duplicates (documented divergence, no merge).  Tests 1169 → 1186.  Zero new deps.  One new tutorial (64). |
| **1.2.21** | 2026-06  | [`1.2.21.md`](1.2.21.md)            | **The Facts book.**  A dedicated **Facts** system book for a world's invariants (climate, geography, seasons, distances, chronology) — free-form prose like Notes — and the AI plumbing to write against them.  **Facts AI scope** (`F9`) seeds a sticky, always-Local fact-analysis chat from the whole Facts book (refreshes when it changes).  **Fact-check chord** (`Ctrl+B Shift+X`) checks the open paragraph against the facts (scope locked to local), emits `claim \| fact \| detail`, and **`Ctrl+B Shift+J`** cycles the findings jumping the cursor to each flagged claim.  **Facts search** (`Ctrl+B Shift+S`) — a semantic-search modal to ground a chat in just the relevant facts (scalable for a big book).  **`inkhaven facts scan`** sweeps every chapter for contradictions (RAG-filtered, `--json` for CI); **`facts extract`** proposes world-facts from the draft for interactive accept (cold-start solver, deduped); **`facts init [--genre]`** scaffolds the starter categories (genre-aware).  Facts join the wiki-link system (provenance → Notes/Research; dependents via `Ctrl+V K`); opt-in `⚑N` status chip.  Multilingual throughout (en/ru/de/fr/es).  Tests 1160 → 1169.  Zero new Rust deps.  One new tutorial (63). |
| **1.2.20** | 2026-06  | [`1.2.20.md`](1.2.20.md)            | **Consolidation, hardening & global themes.**  Pays down the duplication audit the 1.2.19 cycle left behind, then spends the headroom on user-facing polish.  **Live echo overlay** (`Ctrl+B Shift+K`) — the inline companion to the `echo-repetition` scan underlines, in the open paragraph, words echoing across nearby paragraphs of the chapter (open paragraph read live, no per-keystroke I/O), in its own colour (`theme.style_warning_echo_fg`).  **EPUB cover images** — drop a `cover.png`/`.jpg` next to `inkhaven.hjson` and `inkhaven epub` embeds it as the EPUB 3 `cover-image` thumbnail + opening page (zero-config).  **User-global config cascade** — `~/.config/inkhaven/config.hjson` + `conf/*.hjson` layer over each project's `inkhaven.hjson` (global wins; partial overrides; honours `$XDG_CONFIG_HOME`) so one personal theme/keybind set applies everywhere; ships `color_styles/` with 15 popular classic/dark/light schemes (Dracula, Nord, Gruvbox, Solarized, Tokyo Night, Monokai, One Dark, Material Ocean, Catppuccin, GitHub Light, Ayu Light, …).  **Hardening:** `paragraph-too-long` doctor class (read-time threshold), low-disk pre-flight warning, uncommitted-changes quit guard.  **Bug:** Russian `ё`→`е` fold added to three older stem surfaces (concordance / style-warnings / name highlighter) so `пошёл`/`пошла` group.  **Internal:** six duplication categories consolidated into shared helpers (`text::normalize_stem`, `cli::resolve_user_book`, `cli::book_walk`, `ai::stream::collect_blocking`, `typst_prose`, `is_scene_break`).  Two new tutorials (61, 62).  Tests 1121 → 1160.  One new Rust dep (`fs2`). |
| **1.2.19** | 2026-06  | [`1.2.19.md`](1.2.19.md)            | **Revision & continuity (multilingual).**  The draft-3-to-final layer — four detectors + a submission export, built multilingual across a three-tier model (AI prompts / Snowball stemmer / per-language quantity lexicons).  `echo-repetition` flags a distinctive word reused close together (stem + window; all 18 Snowball languages).  `numeric-contradiction` flags reversed directions + mismatched durations via per-language quantity lexicons (`200 leagues north` … `200 leagues south`; `three day` … `a week`) — en/fr/es bundled, others skip cleanly.  `continuity-drift` (the headline): `inkhaven continuity extract` runs an AI pass building a character-fact bible (`.inkhaven/continuity.json`), the scan flags attributes that change across chapters (eyes green→brown), stemmer-normalised so inflection doesn't false-flag.  `unresolved-tension` (opt-in): `inkhaven tension scan` tags introduced/resolved tensions, the scan flags the ones never paid off.  `inkhaven manuscript` exports a submission-ready Shunn standard manuscript format typst doc (monospace double-spaced, title page + rounded word count + running header, scene breaks as `#`).  Config: `editor.echo_*`.  Closes the deferred A.5.b + A.6.b.  Tests 1053 → 1121.  Zero new Rust deps — reuses the existing stemmer / stop-word / whatlang / AI / typst stack.  A real multilingual lesson: the Russian Snowball stemmer needed a `ё`→`е` fold + is a stemmer not a lemmatiser (noun cases collapse, some verb forms don't). |
| **1.2.18** | 2026-06  | [`1.2.18.md`](1.2.18.md)            | **Performance pass + reader experience.**  Two themes.  **I.1 perf:** a deterministic fixture generator (`inkhaven gen-fixture`), a criterion bench harness (`benches/`), timing-instrumented hotspot analysis that overturned the plan's guesses, two algorithmic wins — **lazy embedding-engine init** (cold start 507 ms → 36 ms; the fastembed model no longer loads eagerly on every `Store::open`) and a **parent→children index** that takes `Hierarchy::flatten` from O(n²) to O(n) (31.98 ms → 0.05 ms at 2k) — and a CI regression gate (`inkhaven _bench-report` + `.github/workflows/bench.yml`, fail on >20%).  **Reader experience:** `inkhaven epub` builds a standards-compliant EPUB 3 directly (in-tree `zip` + in-house typst→XHTML, no pandoc); `inkhaven audiobook` synthesises a chapter-marked `.m4b` via the TTS engine + ffmpeg; a status-bar reading-time chip (`📖 remaining / total` at `editor.reading_wpm`); and a reader-pace preview teleprompter (`Ctrl+B Shift+E`) that advances a word-by-word highlight at reading speed.  Two new HJSON knobs (`editor.reading_time_chip`, `editor.reading_wpm`).  Tests 962 → 1053.  Zero new Rust deps in the reader-experience work (`criterion` is a dev-dep; ffmpeg is a documented required external for the audiobook mux). |
| **1.2.17** | 2026-06  | [`1.2.17.md`](1.2.17.md)            | **TTS Piper transition.**  Cross-platform neural TTS replacing the 1.2.9 macOS-only `say` integration.  `editor.tts.engine: "auto"` prefers Piper if resolvable + falls back to System otherwise — macOS users see no regression.  Voices auto-download into `<project>/.inkhaven/voices/` (per-project for language-coverage isolation), Piper binary into `~/.cache/inkhaven/piper-<plat>/` (user-scoped since it's identical across projects).  Voice picker modal on `Ctrl+B Shift+V` with catalog browsing + on-the-fly filter + Enter-to-download.  Headless `inkhaven tts` CLI surface: `engine` / `binary status\|download` / `voice list\|download\|remove` / `catalog refresh` / `test "<phrase>"`.  11 new HJSON knobs (`engine`, `voices_dir`, `auto_download`, `catalog_url`, `catalog_ttl_hours`, `binary_path`, `auto_download_binary`, `cache_max_voices`, `play_command`, `sample_rate_hz`, `auto_gitignore`).  LRU eviction caps the project voice cache at 5 by default.  Idempotent `.gitignore` append on first download.  Stale-catalog + offline fallbacks so synthesis with already-downloaded voices keeps working when the network goes away.  Zero new Rust deps (curl + tar subprocess pattern matches `tui::say`).  Tests 758 → 955 (+197).  Apple Silicon limitation documented: upstream Piper ships x86_64 code in the `aarch64` tarball — mac arm64 users stay on `engine: "system"` for now.  Single-feature cycle. |
| **1.2.16** | 2026-06  | [`1.2.16.md`](1.2.16.md)            | **Author intelligence + polish.**  Headline: manuscript intelligence dashboard (`Ctrl+V Shift+J`) — synthesis pane unifying word count + structure + threads + comments into one view, `e` exports atomic snapshot to `<project>/journal-<UTC>.md`.  Narrative-audit detectors in `inkhaven doctor --scan`: `dropped-character`, `pacing-collapse`, `stalled-thread`, `naming-inconsistency` (Levenshtein over canonical multi-word names).  Worldbuilding glossary chip (`<N>C·<N>P·<N>A`) in status bar (toggle: `editor.show_glossary_chip`).  Carryovers landed: snippet picker placeholders (`{char_lookup}` / `{place_lookup}` / `{artefact_lookup}`) + `bund:` prefix; language CLI exports (`grammar`, `phrasebook`, `csv` round-trip) + `language define-rule` with `$EDITOR`; Bund stdlib expansion (`ink.review.list/add_comment/resolve`, `ink.thread.list`); DB-side health checks (`PRAGMA integrity_check` + HNSW parity + tree-integrity).  Amber backup chip (`backup.amber_threshold`) so users see freshness drift before the warn fires.  Tantivy references purged from active docs (search has been HNSW-only since the in-tree storage migration).  Tests grew across all phases; zero new dependencies. |
| **1.2.15** | 2026-06  | [`1.2.15.md`](1.2.15.md)            | **Stability + self-healing + security hardening.**  Panic-survivability layer: custom panic hook flushes every dirty buffer to `<path>.inkhaven-rescue` atomically + writes `inkhaven-crash-<UTC>.hjson` with panic context + project state + recent action ring; `inkhaven recover` walks the manifest with y/N/diff per buffer.  Stability sweep across `src/tui`, `src/store`, `src/cli`, helper modules + every user-data save path upgraded to atomic via the new `crate::io_atomic` helper — 62 panic sites neutralised; 5 critical-data writes made atomic; lock-poisoning recovery on every shared mutex.  Background health monitor (tokio task) with project-root / backup-freshness / rescue-orphan checks at independent cadences, status-bar chip (`✓ ✎ ⚠ ✗`), per-class auto-repair opt-in, `.inkhaven/health.log` audit trail with size rotation.  Project doctor: `inkhaven doctor --scan/--autofix/--json/--class`, kebab-case scan classes including the new `bdslib-only` (recoverable disk drift), TUI panel on `Ctrl+B Shift+0`.  Security hardening from a full audit: path-traversal patches in recover CLI + HJSON config; `ink.fs.*` sandboxed to project root; Bund script auto-load gated by `<project>/.inkhaven/trust` + `scripting.trust_decision`.  New `Documentation/SECURITY_WARNING.md` discloses known + unknown risks and limitation of liability.  Tests 565 → 695 (+130).  Zero new dependencies. |
| **1.2.14** | 2026-05  | [`1.2.14.md`](1.2.14.md)            | **Plot intelligence + inline comments + quick wins.**  New `Threads` system book (`Ctrl+V Shift+H` picker + swim-lane weave view, `Ctrl+V Shift+A` AI audit, `Ctrl+V Shift+D` deterministic thread doctor modal, `inkhaven thread add/list/doctor/export` CLI).  Inline comments with sidecar JSON storage (`Ctrl+V c` add — span-anchored with char-offset UTF-8 safety, `Ctrl+V Shift+C` project-wide panel with `(N/M in ¶)` dense indicator + `a` AI digest, `inkhaven comments list/resolve/reopen/delete/export` CLI).  Project templates (`inkhaven init --template <name>` + `inkhaven template list`) — 14 scaffolds total including 5 Russian (novel / long-story / scifi / lore / utopia) + 3 international (epic-fantasy / mystery / french-novel).  HJSON-driven snippet expansion with `{date}`/`{slug}`/`{author}`/`{cursor}` placeholders on Space-trigger.  AI continuation drafting (`Ctrl+V d`) + inline footnote (`Ctrl+V f`).  Project word-count goal modal (`Ctrl+V Shift+G`) with 30-day projection.  Style-transfer rewrite (`Ctrl+V y`) from a recent-paragraph picker. |
| **1.2.13** | 2026-05  | [`1.2.13.md`](1.2.13.md)            | **The Language book — a first-class invented-language workbench.**  New `Language` system book with `Meta` / `Dictionary` / `Grammar` / `Phonology` / `Sample texts` chapters; tree-pane scaffolders (`b` on Language scaffolds the 5-chapter shell, `+` under each chapter seeds the right schema-aware HJSON template).  Lexicon overlay + cursor-footer chip in the manuscript editor (`theme.language_word_fg`).  AI translation flow: `Ctrl+B Q` translates the open paragraph INTO an invented language (envelope composes Meta + Grammar + Phonology + RAG-filtered Dictionary + Sample-texts register anchors); `Ctrl+B Shift+Q` reverses direction for roundtrip-drift testing.  Full CLI surface: `inkhaven language init / add-word / import / remove-word / list / doctor / export` with `--format json|anki|dictionary-twocol`.  CSV bulk-import with pre-flight alphabet + phonology validation.  Two tutorials (49 end-to-end + 50 CSV deep-dive) + sample CSV. |
| **1.2.12** | 2026-05  | [`1.2.12.md`](1.2.12.md)            | **Fullscreen split view.**  Four-phase rework that gave two paragraphs full editor chrome side by side.  Universal `Shift+Enter` pin (any pane), `Ctrl+V Shift+B` sibling-book lookup (`manuscript-en/03-rain` → `manuscript-ru/03-rain`), `F12` critique-compare across panes, snapshot-as-secondary draft-vs-current workflow.  Plus the concordance export CLI, HJSON-editor inline LLM review (`Ctrl+R` inside `Ctrl+B 0`), per-detector style-warning underline overrides, and the doc-extractor polish that made every config field show its source comments. |
| **1.2.11** | 2026-05  | [`1.2.11.md`](1.2.11.md)            | **Multilingual prompts.**  Three-phase resolver work (string → directory → per-language prompt fragments) so the AI prompts adapt to the project's working language.  AI sentence-rhythm rewrite (`Ctrl+B Shift+M`) pairs with the rhythm gauge.  Concordance Enter-jump (concordance modal now jumps the editor cursor to the selected paragraph).  AI-diff modal wrapping for long diffs.  Two bootstrap CLIs: `inkhaven bootstrap-sdt` (per-language stop-word + filter-word seeds) and `inkhaven bootstrap-prompts` (per-language prompt seeds).  Config-TUI polish trio: `F3` file picker for path fields, expanded enum widget set, HSL slider with live preview. |
| **1.2.10** | 2026-05  | [`1.2.10.md`](1.2.10.md)            | **Standalone editors for `inkhaven.hjson` and `prompts.hjson`.**  `inkhaven config` — schema-aware TUI editor: auto-derived schema from `Config::default()`, build-time `///` doc-comment extraction so every field has docs, comment-preserving surgical save, `.config-backups/` rollback, per-field annotations (Ctrl+A) + comment inspector (Ctrl+I), map-entry add/delete for `llm.providers`, typed widgets (bool / int / float / string / colour with live preview / path / enum / list).  `inkhaven prompts-editor` — four-pane workbench (list + editor + AI response + AI prompt input) where the LLM acts as a prompt-engineering reviewer; Ctrl+B G lifts the response into the editor; Ctrl+R rollback to `.prompts-backups/`.  Both editors auto-populate from embedded defaults on first launch.  Two new tutorials (44 prompts-editor, 45 config-tui). |
| **1.2.9** | 2026-05   | [`1.2.9.md`](1.2.9.md)              | **Prose-craft tools for novelists.** Inline style-warning overlays (filter words, repeated phrases, show-don't-tell — all multilingual + Snowball-stemmed) under one `Ctrl+B Shift+F` toggle. New modals: project-wide concordance (`Ctrl+B Shift+L`), sentence-rhythm gauge (`Ctrl+B Shift+H`), writing-streak heatmap (`Ctrl+B Shift+G`). New status-bar POV / character chip (`Ctrl+B Shift+P`). Scene-break navigation (`Ctrl+B <` / `>`). TTS read-aloud (`Ctrl+B S`) + save-as-audio file (`Ctrl+B Shift+R`) on macOS. AI-driven show-don't-tell scan (`Ctrl+B Shift+T`). `inkhaven doctor` gains `--voices`, `--tts-test`, `--filter-words-snippet`. Six new tutorials (38-43). |
| **1.2.8** | 2026-05   | [`1.2.8.md`](1.2.8.md)              | **Shell, config editor, and the surface gets sharper.** Embedded nushell pane (`Ctrl+Z o`) running in-process. HJSON config editor (`Ctrl+B 0`) with syntax highlight + restart-required banner. Help book renders as markdown via pulldown-cmark. `inkhaven export-timeline` CLI (SVG / PNG / Typst). Scrivener `<CustomMeta>` date import. Mouse wheel everywhere. Ctrl+Q opt-in confirm. Multi-slot kill-ring + Shift-letter chord-matcher fix. |
| **1.2.7** | 2026-05    | [`1.2.7.md`](1.2.7.md)               | **Polish + plumbing.** Timeline gains two-level Tab/Enter navigation, Space track collapse, span-aware ↑/↓ event select, grid stripes, F12 full critique, per-book session persistence, book-slug prefix, and selection-aware `Ctrl+V Shift+E`. Around it: `Ctrl+B U` paragraph undelete (single-slot kill-ring), `Alt+←`/`Alt+→` visited-paragraph back/forward, `Ctrl+V Shift+P` recent-¶ picker, `Ctrl+Shift+M` mouse-capture toggle for native terminal copy, passive external-change auto-reload, snapshot dedupe, status-bar today widget gets colour, F8 from any pane. Internally: `src/tui/app.rs` refactor 26,605 → 13,939 LOC across 21 new sibling/child modules (zero behavioural delta). Fixes: Ctrl+S no longer jumps the cursor home; clippy clean. 4 new tutorials (32-34) plus 1.2.7 polish section on 31. |
| **1.2.6** | 2026-05   | [`1.2.6.md`](1.2.6.md)               | **Tools for the working novelist.** Tag triad (project-wide picker, rename, `export --tag`, tree pips, `ink.tag.*`, Scrivener keyword import). Diagnostic UX (gutter `●`, F8 list, Ctrl+V N/Shift+N, Ctrl+F12 AI explain, `hook.on_diagnostic`). AI as a partner (F12 critique, per-paragraph memory, diff modal). Snapshot annotations (F5 prompt, F6 picker `✎` rendering). Story view split (Ctrl+V w paragraph mini + Ctrl+V Shift+W book). Render preview live zoom. **Story timeline (1.2.6)** — calendar-aware events; `Ctrl+V e` picker; `Ctrl+V Shift+E` new event from any pane; `Ctrl+V Shift+T` swim lanes with auto-fit on open, scope nav, and Up/Down event-step navigation; `Ctrl+V Shift+I` edit timing; y/Y/Ctrl+Y AI critique; seven `ink.event.*` Bund words + 2 hooks. F11 → Ctrl+F12 (macOS workaround). Seven new tutorials (25 — 31). New **Book of Inkhaven** companion volume. |
| **1.2.5** | 2026-05   | [`1.2.5.md`](1.2.5.md)               | **Typst goes in-process** — `typst_compile.engine = "inprocess"` runs `typst::compile + typst-pdf` inside inkhaven (no shell-out, bundled fonts, `@preview` package fetch). Phase-1 `typst-syntax` parse diagnostics on save/idle; opt-in semantic diagnostics via full compile. `Ctrl+V R` renders the open paragraph to a floating PNG preview with page navigation (←/→) + save-current (S) + save-all (A). `Ctrl+V N` jumps the cursor to the next diagnostic. Esc cancels in-flight compiles; autosave fires before Ctrl+B A/B/O. New `inkhaven doctor` CLI. Embedded logo banners the credits pane. |
| **1.2.4** | 2026-05   | [`1.2.4.md`](1.2.4.md)               | Wiki-links + backlinks (Ctrl+V A/I/L/K), navigation pack (Ctrl+V P/B/M, AI Up history), snapshot diff (F6 V) + pre-restore safety snapshot, per-paragraph word targets + auto-promote, active-time tracking, per-book bar chart, `inkhaven export --status`, `inkhaven stats`, Scrivener importer, tree multi-select + bulk T/O, save-as picker, theme persistence, Bund stdlib gaps closed (`ink.fs.*`, `ink.editor.replace_all`, `ink.search.load`, `ink.ai.poll`, `ink.ai.send_blocking`), F-keys in keybind table, startup splash, Windows CI re-enabled. |
| **1.2.3** | 2026-05   | [`1.2.3.md`](1.2.3.md)               | Multi-format export (markdown / TeX via tylax / EPUB) + `--book-name`, writing-progress subsystem (Ctrl+V G modal, status-bar widget), similar-paragraph side-by-side mode (Ctrl+V S), Bund output pane + Ctrl+Z ? script picker + `ink.input`, dynamic Quick Help. |
| **1.2.1** | 2026-05   | [`1.2.1.md`](1.2.1.md)               | bdslib + tree-sitter-typst absorbed in-tree (crates.io-publishable), Bund scripting (`ink.*` stdlib, hook points, `.bund` Script nodes, Scripts system book), data-driven keymap with HJSON + Bund rebinding, `Ctrl+B M` cycle-type, dirty-flag sync. |
| **1.1**  | 2026-05    | [`1.1.md`](1.1.md)                   | Images first-class, Book assembly / build / take, HJSON-driven `settings.typ`, six LLM providers, AI full-screen + typewriter layouts, document-status workflow, HJSON data nodes, 1000+ commits of polish. |
| **1.0.3** | 2026-04    | (tag-only — see GitHub Releases)     | First public binary release: Linux x86_64 + macOS aarch64. |
| 1.0.2 / 1.0.1 / 1.0.0 | 2026-04 | (tag-only — release-pipeline iteration) | Build / matrix-shaping commits, no user-facing change between them. |

## Reading order

If you're upgrading from an earlier version, read the notes for
every version between the one you came from and the one you're on,
in order. Each release-notes file is self-contained but assumes
you've read the previous one's "Breaking changes" section, if any.

## What we *don't* put here

- Per-commit changelogs — `git log` is canonical for that.
- Internal refactors with no user-visible effect.
- Bugfixes that simply restore advertised behaviour (those land in
  point releases without notes; major behavioural changes get
  notes regardless of size).
