fix(cache): replay reuses settled screens, one settle policy, entries that never churn, named derived-value reasons

Merged
OK
1mo ago
+3058-1232
Two-action stepbeforeafter
deterministic twin67 ms67 ms
replay417 ms154 ms
  • Replay took two settled captures it did not need: a second look at the screen the start capture had just settled, and a re-capture of the end screen for anchors it already held. Both are gone; the one settle before acting stays.
  • How far the screen settles after each action kind is one exhaustive SETTLE_AFTER table (src/agent/settle-policy.ts) the live loop and the replay both read, and one SettleMode (raw | after-change | held-still) threaded from replay to the observation feed, converted to a wait exactly once.
  • A step the cache replayed whole never rewrites its entry (staged entries are a write | keep union, one switch decides write and eviction), and a re-recording of the same flow is not written when only the summary and the measured end wait differ. Two consecutive replays of the web benchmark leave every entry byte-identical.
  • A typed value counts as read off the screen only when it equals a node's whole name or text, or is a digit-bearing token the screen shows as a word; a plain word the model composed replays. step.cache.derived names the rule (whole-node, minted-token, date, pixels) in the report and on the recorded gap; schema and fixture updated.
  • Tests: record-and-replay through the model path for relocation by position, anonymous twins, placeholder and row; unique() in a value, a path segment, an encoded query; volatile anchors; start-path and route identity; a hand-off on a renamed control; --repeat-each; seven Chromium runs, the rest at unit altitude. A speed test compares flow to flow and asserts replay within 3x of the deterministic twin and under the recording. The core fixture app is a routes table over six page modules (1067 lines to 125). Changeset e2e patch.
  • Rebased onto main after #478 and #479 merged. One fixture drift fixed on the way: the canvas page moved into tests/helpers/fixture-pages/canvas.ts from a copy older than main and had lost the tap-count repaint the pixel-tools test reads; the eight lines are back and all 15 of those tests pass.

Devin Review