Render layering: ratatui chrome over libghostty pane interiors

evolving Architecture & operations

Render layering: ratatui chrome over libghostty pane interiors

TL;DR. phux-client uses two renderers on disjoint screen regions. libghostty paints pane interiors on the hot path so kitty graphics, sixel, OSC 8, and the Kitty key protocol pass through unchanged. ratatui paints the chrome (status bar, dividers, modals); the layers composite rather than interleave. A crate split makes the boundary compiler-enforced.


Per ADR-0020, phux-client uses two renderers for disjoint screen regions. libghostty paints pane interiors on the hot path — kitty graphics, sixel, OSC 8 hyperlinks, and the Kitty key protocol all pass through unchanged. ratatui paints the chrome: status bar, pane dividers, borders, modals, future tab bar. The layers composite rather than interleave; chrome carves skip-cell rectangles for pane rects so libghostty owns those cells exclusively.

The ratatui dependency is scoped to a single crate, phux-client (under src/render/, submodules chrome and overlay). The pane-interior substrate — pane mirror, predict layer, layout math, and multi-pane composition — lives in a separate crate, phux-client-core, which carries no ratatui dependency. The boundary is therefore enforced by the compiler: a use ratatui in the substrate fails to build because the crate cannot name it. This replaced the original scripts/check-ratatui-boundary.sh grep guard. The attach loop stays in phux-client (it composites chrome over panes, so it legitimately depends on both the chrome and the substrate).