Finding 1: accepting a FileStyleSummary drops the GPU minimap vertex
cache -- theme recolors and diagnostic republishes arrive at an
unchanged generation, and the cache keys only on (generation, dims,
scroll), so stale strokes survived until an edit/resize/scroll. The
daemon payload-suppresses identical summaries, so the invalidation
is precise. GPU test drives two same-generation summaries;
hand-bitten by reverting the single invalidation line (script-bite
is vacuous here: fix and test share main.rs).
Finding 2: lua_to_style propagates every Table::get error -- the
lookups run __index, so a raising metatable previously parsed as an
all-default style and the merge SUCCEEDED, committing valid siblings
against the Q#TH6 all-or-nothing contract. Boolean fields keep Lua
truthiness by design (mlua bool), so only raising lookups fail the
transaction. Acceptance reproduces the reviewer's trap shape;
runtime bite vs pre-fix mod.rs.
Finding 3: SemanticRenderState::for_peer records the negotiated
version; below v16 no ThemeFacts is produced and no ui.diag.* face
folds into the FileStyleSummary marks -- the summary is an ungated
pre-v16 channel, and a v15 peer must not get face-derived minimap
colors while its other severity surfaces stay unthemed. The summary
cache key zeroes its face-epoch component for such peers. Acceptance
drives v15/v16 producers side by side; compile-fail bite disclosed
(the test needs for_peer, absent pre-fix).
Finding 4: framing revision 5 weakens the canonical-severity claim
to what is true -- the daemon-RESOLVED color is canonical, while the
GPU's built-in squiggle/sign/counter defaults are historical bright
RGBs that differ from the minimap's converted Indexed marks, a
pre-existing divergence kept because unset faces must render
byte-identically to before.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VoiEyuPjoBhvwACf8HAnLB
Arc 4 stage 1 (docs/theme-faces-framing.md, revision 4). Faces are
theme entries under the reserved ui/ui.* namespace -- zero new Lua
API. Theme::face() resolves with the dotted-prefix walk but never
falls back to default_style; each face applies owns-surface within
its stage-1 component mask, identical on both frontends.
Substrate: two monotonic theme mutation counters (syntax/face) with
transactional set/merge/clear/default (parse before locking, commit
all-or-nothing, bump from the prior value); the StyleGate and the
minimap summary key on the counters -- fixing the pre-existing bug
where a mid-session pmacs.theme.set never re-shipped StyleSpans --
with the summary gaining payload-equality suppression that still
advances its key on computation.
Wire: InstanceMessage::ThemeFacts appended after CompletionPopup
(postcard discriminants are ordinal; a byte pin guards placement),
PROTOCOL_VERSION 15 -> 16, daemon-gated >= 16, one authoritative
table per attachment (None-seeded baselines), TUI silent-drop arm.
Grid: paint_frame resolves ui.modeline / ui.statusline /
ui.minibuffer(.candidate) / ui.gutter / ui.selection faces;
SearchView and DiagnosticView take the theme handle through the real
attachment paths (EditorCore injection, install_diag threading); the
canonical severity color resolves ui.diag.* with the Default ->
built-in policy that keeps the minimap presence encoding sound.
GPU: exact-name face table applied per draw with the Q#TH5 Default
mapping (plain text / window bg, reverse swap), local/peer wash
split, candidate-dropdown glyph site, and the status-band
shaping-cache invalidation without which a diag-face recolor with
constant counts kept stale counter colors.
Tests: 18-test acceptance suite (grid, wire, daemon gate, atomicity,
monotonicity, late join), 7 GPU headless tests incl. decoded vertex
colors, units for the face walk / transactional commits / producer
caches; protocol pins for v16 + the CompletionPopup byte pin.
Bites vs 3cbb9de (scripts/bite): semantic_render.rs (8 runtime test
failures), editor.rs (5 runtime), daemon.rs (v15 gate, runtime);
lua_bindings/mod.rs, pmacs-gpu/main.rs, search.rs, diag.rs, and
highlight.rs bite as compile failures (weaker evidence, disclosed).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VoiEyuPjoBhvwACf8HAnLB