Problem
The synthesized text-entry delivery budget added in #2904 is a parallel projection, not the cost of the plan the runner executes. Found in a thermo-nuclear review of #2904 and re-verified on merged main:
projectedSeconds / maxTextLength (RunnerTests+SynthesizedTextEntry.swift ~81-100, 117-128) re-derive the spaced split, the warmup peel and the warmup wait, all of which are decided elsewhere. Two pre-merge fix commits ("charge the delivery budget the whole type command", "charge the warmup split the type plan really makes") were drift caused by this shape.
- The type route decides the budget inside a per-chunk closure, next to a duplicate of the existing
.fallback arm (RunnerTests+TextTyping.swift ~165-205).
- The pace is owned by the ObjC bridge, and Swift reads it back through a getter (
RunnerSynthesizedTextEntry.m ~20, 68-70).
synthesizedAcknowledgeWindowSeconds in production TextEntryTiming (RunnerTests+TextEntry.swift ~74-79) is only read by tests.
- Some tests restate the formula (
RunnerTests+TextEntryPolicyTests.swift ~259-313), and the fixture parses fields no lane asserts.
Proposed shape
- Build one step array (text plus pause) per route, charge its cost as a sum over the steps, and execute that same array.
- Decide the budget once, before the loop, and reuse the existing
.fallback arm.
- Move the pace constant into
TextEntryTiming and pass it to ObjC.
- Move the test-only window into the tests.
- Keep the boundary, pace, hint and live-route lane tests; drop the formula-restating tests.
Estimated about −80 production lines. Also triage the PR bot's unaddressed per-call overhead claim against the 18 s ceiling before changing admission.
Problem
The synthesized text-entry delivery budget added in #2904 is a parallel projection, not the cost of the plan the runner executes. Found in a thermo-nuclear review of #2904 and re-verified on merged main:
projectedSeconds/maxTextLength(RunnerTests+SynthesizedTextEntry.swift~81-100, 117-128) re-derive the spaced split, the warmup peel and the warmup wait, all of which are decided elsewhere. Two pre-merge fix commits ("charge the delivery budget the whole type command", "charge the warmup split the type plan really makes") were drift caused by this shape..fallbackarm (RunnerTests+TextTyping.swift~165-205).RunnerSynthesizedTextEntry.m~20, 68-70).synthesizedAcknowledgeWindowSecondsin productionTextEntryTiming(RunnerTests+TextEntry.swift~74-79) is only read by tests.RunnerTests+TextEntryPolicyTests.swift~259-313), and the fixture parses fields no lane asserts.Proposed shape
.fallbackarm.TextEntryTimingand pass it to ObjC.Estimated about −80 production lines. Also triage the PR bot's unaddressed per-call overhead claim against the 18 s ceiling before changing admission.