callstack / callstack/agent-device
ios: fill's synthesized-replacement route lands a corrupted value (traced: 11 chars requested, 7 observed, frozen)
- Dominant language
- TypeScript
- Stars
- 4.6k
- Forks
- 299
- Avg merge
- 10h 14m
- Merged PRs (30d)
- 537
Description
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](https://github.com/callstack/agent-device/pull/2059) ([run 33067586234](https://github.com/callstack/agent-device/actions/runs/33067586234/job/98501576566)), 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
- **Not a throttle.** `expectedPrefixLen` is flat at 1 for the whole wait. A throttled burst walks the prefix upward; this one never progressed after the first observation.
- **Not the #2035 deadline.** The wait behaved correctly: progress at the first poll only, then condemned 3 s later (the 6293 ms total includes the ~1.1 s placeholder read that precedes the poll loop).
- **Not the placeholder collision** fixed in #2035. `field-email`'s placeholder is now `Type your email`; the filled value shares nothing with it.
- **Not the failing PR's doing.** #2059 touches CI configuration only.
## 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](https://claude.com/claude-code)_
Contributor guide
Assessment
This issue has not been assessed yet.