minimalReplace (frontend/src/pages/my-words/interaction/editor.ts) shrinks a paragraph rewrite to its changed middle, then grows the needle leftward until the first occurrence is the intended one:
// Hosts replace the FIRST occurrence; grow the needle leftward until the
// first occurrence is the intended one (e.g. second "aa" in "aa b aa").
while (start > 0 && oldText.indexOf(oldStr) !== start) {
That disambiguation is computed with case-sensitive indexOf, but wordEditorAPI.applyEdit searches with matchCase: false. So in a paragraph containing Cat … cat, a needle grown to be unambiguous under indexOf can still be ambiguous to Word, and Word replaces the earlier occurrence — a silent edit in the wrong place.
Narrow: it needs a paragraph with the same text differing only in case, and the grown needle to stay short enough to still collide. Pre-existing; not related to #587, which changed how the model's needles are located, not how host-derived ones are.
Fix
Either make the disambiguation loop match the host's semantics (compare case-insensitively when growing), or — better — remove the assumption entirely by resolving a range instead of a needle, per #589.
minimalReplace(frontend/src/pages/my-words/interaction/editor.ts) shrinks a paragraph rewrite to its changed middle, then grows the needle leftward until the first occurrence is the intended one:That disambiguation is computed with case-sensitive
indexOf, butwordEditorAPI.applyEditsearches withmatchCase: false. So in a paragraph containingCat … cat, a needle grown to be unambiguous underindexOfcan still be ambiguous to Word, and Word replaces the earlier occurrence — a silent edit in the wrong place.Narrow: it needs a paragraph with the same text differing only in case, and the grown needle to stay short enough to still collide. Pre-existing; not related to #587, which changed how the model's needles are located, not how host-derived ones are.
Fix
Either make the disambiguation loop match the host's semantics (compare case-insensitively when growing), or — better — remove the assumption entirely by resolving a range instead of a needle, per #589.