# Inkhaven 1.2.12 — in flight

1.2.11 was the "multilingual prompts" release — three
phases of resolver work plus the AI sentence-rhythm
rewrite, concordance Enter-jump, AI-diff wrapping, the
two bootstrap CLIs (SDT + prompts), and the config-TUI
polish trio (F3 file-picker / new enums / HSL slider).
1.2.12 picks up the carryovers that didn't fit and the
new ground 1.2.11 surfaced.

This document is a living scratchpad — entries land
here as the work lands.  Each item starts as a one-
line plan; gets fleshed out when the corresponding
feature ships; gets a chord / config / hook callout
when relevant.

## Planned themes

### Carryovers from 1.2.11

  * **Apply prompts-editor critique back into the
    main TUI's flows.**  The prompts-editor's
    reviewer-LLM is the deepest review surface we
    have; the main TUI's `Ctrl+B 0` HJSON editor
    is the most exposed.  Wiring the same
    review-as-you-edit shape into the in-app
    HJSON editor would close the loop.

  * **Build-time doc-comment extraction polish.**
    The current extractor handles `Option<T>` /
    `Vec<T>` / `HashMap<K, V>` descents; nested
    `Option<HashMap<K, V>>` shapes still don't
    flow through cleanly.  Audit + fix.

  * **Concordance export — `inkhaven export
    concordance`.**  CSV / JSON variants of the
    Ctrl+B Shift+L modal data for use in
    spreadsheets / analysis pipelines.

  * **Mouse-driven scene-break selection.**  Drag
    from one break-line to the next selects the
    scene.  Pairs with the existing Ctrl+B </>
    scene-break navigation.

  * **Show-don't-tell theme audit.**  Per-detector
    underline style override (DIM / BOLD /
    REVERSED / NONE), since the teal underline
    reads differently on different terminal
    palettes.

### Split view — the still-deferred 1.3 work

1.3 has been "next release" since 1.2.5.  It keeps
slipping because each polish cycle finds enough
single-pane work to fill itself.  If 1.2.12 is
genuinely quiet, the split-view rework lands here.

### Other candidates

  * Refresh `Documentation/INKHAVEN_CHEAT_SHEET.typ`
    with the 1.2.11 chord additions
    (`Ctrl+B Shift+M`, `Ctrl+B Shift+N`).
  * GitHub Release object follow-up — the 1.2.11
    tag is pushed but the Release UI object wasn't
    created (gh CLI auth lacked `workflow` scope at
    release time).  Either backfill it or
    automate via `.github/workflows/release.yml`.

## Implementation log

### Split view — Phase A (foundation)

Plumbing for the fullscreen two-paragraph split-view
layout.  No user-visible change beyond a new
`Shift+F4` chord that toggles a flag.  Three new
state pieces: `App.split_view: bool` (the layout
flag), `App.picker_target: PaneTarget` (where the
next picker pick lands — defaults to Primary; Phase
B wires the routing), and a renderer dispatch
branch that switches to a 50/50 horizontal editor
split when `split_view` is true AND
`secondary.is_some()`.  Existing `F4` (same-
paragraph snapshot split) and `Ctrl+F4` (accept
snapshot) are untouched — the new chord is
additive.  `pin_secondary_by_uuid` and
`drop_secondary` helpers exist as Phase B targets.
Two new tests lock the binding contract
(`existing_f4_and_ctrl_f4_bindings_remain_untouched`,
`pane_target_defaults_to_primary`).

### Split view — Phase B (Shift+Enter pins to secondary)

The user-visible payoff.  Every paragraph picker
now routes a `Shift+Enter` accept to the split-
view secondary slot instead of replacing the
primary:

  * Tree-pane Enter (same paragraph node the tree
    is currently selected on).
  * Fuzzy paragraph picker (`Ctrl+V P`).
  * Recent-paragraph picker (`Ctrl+V Shift+P`) —
    shares the fuzzy picker's modal shape, so wiring
    one covered both.
  * Bookmark picker (`Ctrl+V M`).

The dispatch goes through a new
`App::dispatch_picker_accept(id,
pin_to_secondary: bool)` helper that surfaces
pin failures on the status bar (e.g. trying to pin
the paragraph that's already in the primary slot).
Picker footer hints + opening status echoes
updated to advertise the new chord.  One new test
(`shift_modifier_drives_pin_to_secondary`) locks
the contract that the SHIFT modifier flag is what
drives the routing.

The natural workflow: `Ctrl+V P` (or `Ctrl+V M`),
filter to the paragraph you want beside the
current one, `Shift+Enter`, then `Shift+F4` to
view the split.

499 tests pass (was 498 — +1).  Zero new
dependencies.  Phase C adds per-pane chrome
(focus highlights, Tab swap behaviour); Phase D
adds the translation-workflow sibling-book picker.

### Split view — Phase C (per-pane chrome polish)

Three UX-polish wins on top of Phases A + B:

  * **Mode-aware secondary editor title.**
    `draw_secondary_editor` shows `(split)` instead
    of `(similar)` when `split_view` is on; the
    cursor's L/C coordinates are now in the title
    too so the user can read the secondary cursor's
    position without Tabbing into it.  Handy in
    translation work where you scroll the secondary
    to keep pace with the primary.
  * **Mode-aware Tab status echo.**  The Tab
    handler at the editor pane already swaps focus
    between `opened` and `secondary` when the
    secondary is populated; the status message now
    says `split: right editor focused` /
    `split: left editor focused` when the layout
    is split-view, and `similar: …` when the layout
    is the existing Ctrl+V S similar-mode.  Same
    Tab dispatch path covers both modes.
  * **Autosave already covered.**  The audit during
    Phase A confirmed `tick_autosave` already walks
    both `opened` and `secondary` slots from 1.2.4
    similar-mode.  Phase A inherits that behaviour
    for split-view at zero cost.  A
    compile-time-only test
    (`save_doc_is_callable_against_secondary_slot`)
    locks the surface so future refactors that drop
    the secondary autosave branch fail at compile
    time.

Two new tests:
`tab_swap_toggles_secondary_focused_flag` and the
`save_doc` surface check.

501 tests pass (was 499 — +2).  Zero new
dependencies.

**Phase C deferred** — full per-overlay parity
between primary and secondary (search highlights,
style-warning detectors, lexicon highlights, grammar-
correction overlays, tag overlays).  The primary's
`draw_editor` runs every overlay pass; the
secondary's `draw_secondary_editor` keeps the
minimal title + textarea + slug-path footer.  In
practice this is OK for the translation /
side-by-side workflows the split view targets —
the user reads the secondary, edits the primary
— but a future commit could thread the overlay
passes through.  Treating that as polish, not a
correctness gap.

### Split view — Phase D (translation workflow + critique-compare)

The translation-workflow payoff.  Closes the
SPLIT_VIEW.md proposal.

**`Ctrl+V Shift+B` — sibling-book lookup.**  Given
the open paragraph's slug, walks the project's
hierarchy for paragraphs with the same slug under
a *different* top-level book.  Three cases:

  * **Zero matches** — status message names the
    slug we tried, so the user knows whether to
    rename or pick differently.
  * **Exactly one match** — auto-pin to the
    `secondary` slot via the Phase B
    `dispatch_picker_accept(id, true)` helper.
    Status echoes the matched slug-path so the
    user can confirm at a glance.
  * **Two or more matches** — open the fuzzy
    paragraph picker pre-filtered to those
    entries.  `Shift+Enter` still pins (Phase B
    routing), so the natural flow is
    `Ctrl+V Shift+B` → optional filter →
    `Shift+Enter` → `Shift+F4`.

Excludes the open paragraph's own book from the
candidate set (you don't want to pin yourself).
The book ancestor is identified via the existing
`Hierarchy::ancestors` walk; same primitive the
concordance system-book filter uses.

Primary use case: translation manuscripts where
the source lives at `manuscript-en/03-rain` and
the target at `manuscript-ru/03-rain`.  One
chord pins them side-by-side.  Also covers
mirror-book setups (`research-notes/X` vs
`scenes/X`) and any other parallel slug
convention.

**`critique-compare` embedded prompt.**  Seventh
embedded prompt, five-language match (en / ru /
es / de / fr).  Routes through the Phase A
multilingual resolver via the standard
`Prompts book → prompts.hjson → embedded` cascade.
Asks the LLM to compare two paragraphs
substantively — what overlaps, what diverges,
which one lands the beat harder, with attention
to tone / rhythm / imagery precision.  Explicitly
covers two scenarios:

  * **Translation review** — left = source,
    right = translation; does the translation
    carry the meaning, voice, and register?
  * **Draft comparison** — left = old draft,
    right = new; which is stronger, what should
    the next revision pass carry from weaker to
    stronger?

**F12 dispatch updated.**  `start_critique` now
picks `critique-compare` when split-view is on
AND both `opened` and `secondary` are populated
with distinct, non-empty paragraphs.  Falls back
to the existing `critique-changes` / `critique-edit`
routes when those conditions aren't met (e.g.
split-view is on but secondary is empty → falls
back to single-paragraph critique-edit).  The
prompt envelope wraps both bodies as
`── Left (`title`) ──` / `── Right (`title`) ──`
fences so the LLM can refer to them
unambiguously.

**Bootstrap CLI updated.**  `EMBEDDED_PROMPTS`
table in `src/cli/prompts.rs` gains the
`critique-compare` row.  Forcing-function test
(`embedded_prompts_table_covers_every_named_resolver_path`)
bumps to expect 8 entries — adding a new embedded
prompt without adding it to the bootstrap fails
the test, so `inkhaven prompts bootstrap <lang>`
generates a translation for the new prompt by
default.

One new test:
`critique_compare_default_prompt_covers_five_languages`
locks the 5-language match shape (every language
returns distinct non-empty content; unknown codes
fall back to English).

502 tests pass (was 501 — +1).  Zero new
dependencies.

**Split-view cycle complete** — Phases A/B/C/D all
shipped in 1.2.12:

  * Phase A — foundation: chord (`Shift+F4`),
    state fields, renderer dispatch, helpers,
    binding-contract tests.
  * Phase B — picker routing: `Shift+Enter` pins
    to the secondary slot from tree-pane Enter,
    fuzzy paragraph picker, bookmark picker,
    recent-paragraph picker.
  * Phase C — UI polish: mode-aware secondary
    title and Tab status echo, autosave audit.
  * Phase D — translation workflow: sibling-book
    lookup chord + `critique-compare` embedded
    prompt + F12 routing.

What's intentionally out of scope (per
`SPLIT_VIEW.md §9`): N>2 panes; independent tree
pane per side; per-side AI pane; persistent
layout across sessions; mouse-driven split-bar
drag.
