# Frames for [#5385](https://github.com/facebook/astryx/pull/5385) — round 3 The decisive before/after pair behind [Review 5385](../../Review-5385) round 3, plus the sensor receipt each frame was captured under. Nothing else: one pair, one claim. **The claim these frames settle.** With `hasCreate` and `minQueryLength={3}`, does typing a two-character query offer anything? Before the fix the field sits there — no menu, no message, and Enter does nothing. After it, `Create "QA"` is offered and Enter commits it, with the search source still never called. | | frame | |---|---| | **before** — the create path as it stood at the round-2 head | ![before](https://raw.githubusercontent.com/wiki/cixzhang/astryx/assets/pr-5385/rr3__before-create.png) | | **after** — the same field at `94785a3` | ![after](https://raw.githubusercontent.com/wiki/cixzhang/astryx/assets/pr-5385/rr3__after-create.png) | ## Files | file | bytes | sha256 | |---|---|---| | `rr3__before-create.png` | 3613 | `01c4a30a4a67eb5df88f2334a1fb92552c2d77e55a7cfd35c70e2447cf40b8d0` | | `rr3__after-create.png` | 6238 | `47295ab94eee4585deb428509488e187f2ddc69a1efa21aa5d37b0bab064621b` | | `rr3__before-create.png.sensors.json` | — | `cde857abeca6da142f67a276293eb44070ea015556b10c457c7845b0e1ce0313` | | `rr3__after-create.png.sensors.json` | — | `536f586d10bc4610a1b6cba093f9c193f1d56148791714a033147401b2b86b17` | PNG checksums are of the captured bytes, unmodified. The two JSON receipts were rewritten once before publication to remove local absolute paths — `build.root` and `image.path` only. Every sensor value, every expected/observed pair and the build SHA are exactly as `captureWithSensors()` wrote them. ## Sensor receipt Written by `captureWithSensors()` before each PNG, and asserted — a mismatch throws instead of capturing. | sensor | before | after | match | |---|---|---|---| | Build SHA | `94785a3a2d31d9bea0e596d2ee58f65f6d4a5d10` | `94785a3a2d31d9bea0e596d2ee58f65f6d4a5d10` | see note | | Story | `rr-5385--tokenizer-create-gated` | same | ✔ | | Globals | `{}` | `{}` | ✔ | | Theme | `neutral` | `neutral` | ✔ | | Colour mode | `light` | `light` | ✔ | | Direction | `ltr` | `ltr` | ✔ | | Viewport | `520×420 @1` | `520×420 @1` | ✔ | | Media | forcedColors ✗ · reducedMotion ✗ · coarsePointer ✗ · hover ✔ | same | ✔ | | Target count | 1 (`input[role="combobox"]`) | 1 | ✔ | | Semantic state | `{query: "QA", focused: true, searchCalls: 0}` | same | ✔ | | Geometry | visible, `294×20` at `(49, 70)`, inside viewport | identical box | ✔ | | Fonts | `loaded` | `loaded` | ✔ | | Capture errors | none | none | ✔ | Every sensor matches. The subject's box is identical to the pixel, which is what lets the frames be read as one comparison: the field does not move, so the menu is the only difference. `searchCalls: 0` is asserted in **both** arms rather than observed and copied back. It is what makes "no fetch happened" a fact rather than a race — the probe waits 1200 ms before capturing, past the field's 150 ms debounce and the story's 600 ms source. ### The note on Build, and why it is the honest column Both receipts read the same SHA, because the arm was made by checking two files out of the previous head into the same worktree — `git HEAD` never moved, so the Build sensor cannot tell the arms apart. **A SHA proves identity, not that the experiment changed one variable.** What separates the arms is the diff, which was read hunk by hunk rather than trusted: 99 lines across `Tokenizer.tsx` and `BaseTypeahead.tsx`, every hunk the Create path — the `queryEntries` prop and its two dependency entries, `createEntries`, the `queryEntries={…}` wiring, the `fetched`/`shown` split, and the `derived` branch. It leaves `minQueryLength`, `isBelowMinQueryLength`, `setIsLoading(false)` and the ArrowDown gate untouched, which is what makes the before arm the round-2 head rather than `main`. ## How to re-run it ``` {review-root}/probe-kit/shot-5385-rr2.cjs SB_PORT= ARM=before|after {review-root}/probe-kit/probe-5385-rr2b.cjs the behaviour read behind the frames {review-root}/probe-kit/probe-5385-maxitems.cjs the maxMenuItems count, both arms ``` Story `rr-5385--tokenizer-create-gated` is a review-only scratch story with a 600 ms source; it is not part of the PR. Every shipped Typeahead and Tokenizer story resolves synchronously, which is why the in-flight states this PR touches do not exist in any of them.