PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m2s
PR Checks / Backend Smoke (pull_request) Successful in 8s
PR Checks / Build Backend (no push) (pull_request) Successful in 11s
PR Checks / Build Frontend (no push) (pull_request) Successful in 44s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 55s
Three staging-gate failures, two of them one real bug. After a search, the results-page bar still holds the term in its input, so on every render the query was >= 2 characters and the suggestion list opened again — on top of the very results the search had just produced. Playwright reported it as "<li role=option ...> intercepts pointer events" while trying to click the first result; a reader would simply have found their first result unclickable. Both the school-detail and hero-map journeys failed on it, and neither is about autosuggest. Suggestions now answer typing, not the mere presence of a value: `hasTyped` gates the hook, is set on change, and is cleared when a search is submitted or a suggestion is chosen. A pre-filled input makes no request and shows no list. Third failure was my test, not the product. An unphased place page renders one table per phase, and an all-through school legitimately appears in both — so the page's school links were never one alphabetical run. The assertion collected them all together and only passed because no town it picked had held an all-through school. When the data gave Abbots Langley one, Breakspeare School appeared in the primary table and again in the secondary, and the test failed on correct behaviour. It now checks each table separately, and passes against the data that broke it. Guards: a jest test that a pre-filled input neither fetches nor opens (verified by reverting — it is the only one that fails), and an E2E journey that submits a search and then requires the first result to be clickable, which is the reader-facing version of the same thing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015mWQnpye9F299NVRCCSRvj