docs/solutions/logic-errors/2026-04-04-slate-v2-placeholder-ime-proofs-must-commit-on-compositionend.md
The first real-browser slate-v2 placeholder IME proof started red for the
right reason:
At first the example reconciled the editor from native input on every
composition step.
That looked reasonable and was wrong.
It turned transient composition text into committed document state, so the DOM ended up as the concatenation of every IME step instead of the committed text.
insertCompositionText input broke the live
composition region and appended each next IME step.insertText input was also bullshit on the
clean path.
Once transient composition input stopped forcing rerenders, Chromium finished
with compositionend and no later commit-friendly input event.Treat transient composition and committed text as different phases:
input events while event.isComposing is trueinsertCompositionText / deleteCompositionTextcompositionendinput for non-IME text entryThat made the proof surface behave honestly:
すし with selection 0.0:2|0.0:2IME composition text is not stable document truth.
During composition, the browser owns a temporary native region and may rewrite it several times before commit. If the proof surface copies that transient DOM back into Slate on each step, it destroys the composition lifecycle it is trying to measure.
compositionend is the first trustworthy point on this Chromium path where the
final committed text is already in the DOM and can be translated back into the
editor model without duplicating intermediate steps.
For slate-v2 browser proof surfaces on IME-sensitive placeholder paths:
input event will arrive after IMEcompositionend as the commit boundary unless the concrete browser
proof shows a different contractIf a proof surface reconciles on every composition input, it is testing its own bad input policy instead of the editor seam.