Skip to content

ios: fill's synthesized-replacement route lands a corrupted value (traced: 11 chars requested, 7 observed, frozen) #2080

Description

@thymikee

A fill on the penalized coordinate route committed a value that is neither the requested text nor a prefix of it, and stayed that way. The commit wait caught it — #1995 working as designed — but it turns an expensive lane red on unrelated PRs, which is the #1874 symptom from a third mechanism.

The trace

From the iOS smoke lane of PR #2059 (run 33067586234), a PR that changes one workflow file, one test and vitest.config.ts — nothing reachable from the runner.

Step: agent-device fill id="field-email" ada@example (11 characters).

AGENT_DEVICE_RUNNER_TEXT_ENTRY_ROUTE route=synthesized-first-responder-replacement
[DEBUG-1874] synthesize posted 11 chars status=0 tookMs=1084
[DEBUG-1874] wait start expectedLen=11 route=replacement
[DEBUG-1874] poll t=1102ms observedLen=7 expectedPrefixLen=1
[DEBUG-1874] poll t=2395ms observedLen=7 expectedPrefixLen=1
[DEBUG-1874] poll t=3717ms observedLen=7 expectedPrefixLen=1
[DEBUG-1874] poll t=5097ms observedLen=7 expectedPrefixLen=1
[DEBUG-1874] wait outcome=notObserved elapsedMs=6293 route=replacement

Read it as: the field settled at 7 characters sharing exactly one character with ada@example, and never moved again. Four polls over ~4 s at a stable length. status=0 — the synthesize call reported success.

This is the dropped-middle-character family already documented in awaitSynthesizedReplacementCommitOutcome ("ada@example" -> "aexample", "Ada Lovelace" -> "Avelace"), reproduced in CI with a trace attached.

What it is not

Why it is worth its own issue

#1874 tracks "why does the input pipeline throttle". This is a different defect with a different signature: the characters are not late, they are wrong, and the value is stable. Grouping them would put two mechanisms behind one needs-info.

The immediately useful next step is to learn what the 7 characters actually were. The cadence log is value-free by design (#1924), so the corrupted string is not in any artifact — a one-off local reproduction on the penalized route, or a temporary opt-in that logs the observed value under a test-only flag, would say whether the loss is leading, middle or trailing, which points at RunnerSynthesizedTextEntry.replaceText's select-all-then-type sequence versus the per-character pacing above it.

Related: #1995 (the verification that caught this), #1924 (honest reporting), #1874 (same symptom, different mechanism).


Generated by Claude Code

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions