# Inkhaven 1.3.14 — The ConLang Suite (Part 1: phonology, lexicon, morphology)

_Inkhaven becomes the first constructed-language workbench that lives **inside
the writing tool**. A fantasy or sci-fi author can now build a language —
phonology, lexicon, morphology — and write prose in it, with the AI as an
assistant and the author in full deterministic control of the rules. This is
the first checkpoint of a flagship that continues across 1.3.x (RFC LANG-1;
plan: [LANG-1_PLAN.md](../PROPOSALS/LANG-1_PLAN.md)). Zero new dependencies._

The suite is layered **on top of the existing 1.2.13 `Language` system book** —
the book stays the home of record, and these engines reconstruct an in-memory
model from its HJSON chapters. Reference: [CONLANG.md](../CONLANG.md).

## The phonology engine (P1)

A complete, deterministic sound system — inventory through tone:

- **Inventory + phonotactics** — phonemes (IPA + romanization), named classes,
  syllable templates, and a phonotactic validator (`max_cluster_size`,
  `no_geminate`, `forbid_bigram`, and — syllable-aware — `forbid_in_onset` /
  `forbid_in_coda` / `sonority_sequencing`). A **deterministic word generator**
  samples templates and keeps only words that satisfy every constraint:
  `inkhaven language generate-word`.
- **Syllabification** — sonority-peak nuclei + the Maximal Onset Principle:
  `inkhaven language syllabify` (`star.ka`, `al.tan`).
- **Allophony** — ordered SPE-style rules (`k > tʃ / _ i`, `d > t / _ #`,
  `∅ > ə / C _ C`) derive the surface form from the underlying:
  `inkhaven language ipa`.
- **Stress** — fixed (initial / final / penult / antepenult) or the
  weight-sensitive Latin rule: `inkhaven language stress` (`ta.ˈki.na`).
- **Romanization** — named, **bidirectional** schemes with contextual rules
  that disambiguate shared graphemes (`c` → /s/ before a front vowel, else
  /k/): `inkhaven language romanize [--reverse] [--scheme]`.
- **Tone** — register / contour systems with sandhi (Mandarin `3 3 → 2 3`):
  `inkhaven language tone --tones "…"`.

## The lexicon + AI dictionary generation (P2)

- **AI dictionary generation** with a **complete dedup gate** —
  `inkhaven language generate-lexicon --topic … --count …`. The forms come
  from the deterministic generator (so every proposal obeys the phonotactics);
  the AI assigns meanings, glossed **in your working language**. The gate
  rejects any proposal that is illegal, a **homophone** of an existing word, a
  **duplicate meaning**, or — with `--semantic` — a **near-synonym** (embedding
  cosine, so "stone" vs "rock" is caught). Nothing commits without `--yes`;
  generated entries are tagged with register + semantic domain.
- **Audit** — `inkhaven language audit` flags phonotactic violations,
  homophones, and duplicate meanings across the whole dictionary.
- **Rich entries + query** — entries carry register / domain / era / etymology
  tags; `inkhaven language query [--register] [--domain] [--era] [--pos]
  [--text]` filters by any combination.
- **Worldbuilding links** — `inkhaven language link-place` / `link-character`
  (proficiency) / `speakers`, stored in a `.inkhaven/conlang-links.json`
  sidecar (the prose Places/Characters books are never touched).
- **Manuscript scan** — `inkhaven language scan-manuscript` finds candidate
  *undefined* conlang words in your prose (words that look like the language
  but aren't in the dictionary).

## Morphology (P3, started)

- **Paradigm generation** — `inkhaven language paradigm --root … --template …`
  applies a paradigm template's morpheme sequence to a root and runs the
  allophony engine **across the affix boundaries**, emitting the surface form +
  a Leipzig gloss. So `kata` + DAT → `katat` (final devoicing), while `kata` +
  DAT + PL → `katadi` (the now-medial `d` correctly stays). The morphology
  HJSON lives in the **Grammar** chapter.

## In the editor

- **`Ctrl+B X` — the ConLang hub.** A read-only overview of every language:
  phoneme inventory, template / constraint / allophony counts, prosody,
  romanization schemes, lexicon size, and linked speakers.
- **`:lang:` inline insertion.** Type `:<language>:` (by name or ISO code) in
  the editor and a filterable lexicon picker inserts the chosen word in place
  of the trigger. (`Ctrl+B Q` translation, from 1.2.13, is unchanged.)

## Design notes

- **Forms obey the language; meanings come from the AI; nothing duplicates.**
  The deterministic generator is the single source of word *forms*; the AI only
  chooses among valid forms and assigns *meaning*; every AI proposal passes the
  dedup gate. AI features are advisory — proposal-gated, `--yes`-committed,
  glosses in the project working language.
- **Extend in place.** No parallel "Languages" book, no schema migration — the
  morphology block lives in the Grammar chapter, the phonology block in the
  Phonology chapter, the lexicon stays the existing `DictionaryEntry`
  paragraphs. The one normalized concession (per-gloss embeddings) is computed
  on demand, reusing the store's already-loaded model.
- **Pure + tested.** Every deterministic engine (validator, syllabifier,
  allophony, stress, romanization round-trip, tone sandhi, paradigm generation,
  the dedup gate) is unit/property-tested; the AI calls are thin layers.

## What's next (still in flight)

LANG-1 continues across 1.3.x: more morphology (auto-gloss, the grammar
questionnaire, derived forms), **diachronics** (sound-change engine, cognates,
family trees), **writing systems + pure-Rust font compilation** (the one
dep-heavy phase), an **analysis suite**, and a package-rich **Typst grammar
book / dictionary** export.

Tests 1359 (1.3.13) → 1428. Zero new dependencies. The whole surface is
documented in [CONLANG.md](../CONLANG.md).
