Skip to content

Make document search on demand - #2199

Merged
BigSimmo merged 11 commits into
mainfrom
codex/document-search-toggle-pr
Aug 21, 2026
Merged

Make document search on demand#2199
BigSimmo merged 11 commits into
mainfrom
codex/document-search-toggle-pr

Conversation

@BigSimmo

@BigSimmoBigSimmo commented Aug 20, 2026

Copy link
Copy Markdown
Owner

Summary

  • Replace the always-visible document search composer with a closed-by-default Search document action across phone and desktop layouts.
  • Add autofocus, Escape/close reset, stale-request protection, highlight clearing, scroll preservation, focus restoration, and accurate aria-expanded/aria-controls state.
  • Remove Add to scope from the document viewer and release phone/desktop footer space whenever document search is closed.
  • Update DOM and Chromium coverage so document-viewer journeys explicitly open and close search.

Verification

  • npm run verify:pr-local

Verification not run: the current-head attempt was superseded by focused checks; the pre-push static lint/typecheck phase was capacity-blocked by another worktree's exclusive Playwright lease.

  • npm run verify:ui when UI, routing, styling, browser behavior, reduced-motion, or forced-colors behavior changed

npm run verify:ui was partial before the current-main replay: build passed; 468 passed, 2 skipped, and 6 broad-suite journeys failed under heavy host contention. Every changed document-viewer phone/PWA/search journey passed. The only overlapping failure occurred before the new composer opened and passed 1/1 when rerun alone.

  • npm run verify:release before release or handoff confidence claims

Not run: release confidence was not requested.

Focused evidence:

  • npm run format — passed on the pushed PR head; no files changed.
  • npm run test -- tests/document-viewer-shell.dom.test.tsx tests/document-detail-performance.test.ts tests/header-scroll-hide-contract.test.ts tests/ui-overlay-css-contract.test.ts — 4 files, 58/58 passed on the current-main PR head.
  • npm run test:e2e -- tests/ui-smoke.spec.ts --project=chromium --grep "search regressions avoid fetch errors and open viewer hits" — 1/1 passed on the pre-replay commit with the same source diff.
  • Seven targeted Chromium document-viewer journeys at phone and desktop sizes — all passed across the initial run and focused reruns.
  • npm run verify:phone-chrome -- --full=always --files ... — partial before replay: phone contracts 133/133 passed; changed browser selection 174/175 passed. The lone calculator failure passed on untouched baseline and later in the full UI run.
  • Current-head npm run typecheck — blocked before execution by DATABASE_HEAVY_RUN_ADMISSION_BUSY; the same source diff typechecked successfully before replay.
  • Physical Safari and installed-device PWA acceptance — not run.

Risk and rollout

  • Risk: Localised document-viewer interaction and responsive footer-reserve change. Search API, indexed-result ranking, routes, database, and retrieval contracts are unchanged.
  • Rollback: Revert commit f69003e98.
  • Provider or production effects: None.
  • RAG impact: none; no RAG, retrieval, ranking, scoring, or answer-generation code changed.

Clinical Governance Preflight

  • Source-backed claims still require linked source verification before clinical use
  • No patient-identifiable document workflow was introduced or expanded without explicit governance approval
  • Supabase target remains Clinical KB Database (sjrfecxgysukkwxsowpy)
  • Service-role keys and private document access remain server-only
  • Demo/synthetic content remains clearly separated from real clinical sources
  • Source metadata, review status, and outdated/unknown-source behavior remain conservative
  • Deployment classification/TGA SaMD impact was checked when clinical decision-support behavior changed (not applicable: viewer interaction only)

Notes

  • The branch was replayed cleanly onto current origin/main; main advanced once more with an unrelated database live-drift commit before push and does not overlap this diff.
  • No live-provider call, deployment, migration, or production data access was performed.

Summary by CodeRabbit

  • New Features

    • Added a dedicated mobile document search composer with clear open and close controls.
    • Added Escape-key support, focus restoration, and automatic search reset when closing or reopening.
    • Replaced the “Add to scope” action with document search.
    • Improved accessibility states for search controls.
  • Bug Fixes

    • Prevented stale search results from appearing after closing or changing documents.
    • Restored footer layout and spacing correctly after search closes.

@supabase

supabaseBot commented Aug 20, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project sjrfecxgysukkwxsowpy because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@coderabbitai

coderabbitaiBot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your current included review allowance is based on your included PR review attempts over the past 7 days.

Next review available in:7 minutes

Limit details: You’ve used the included review currently available. Your 87 included PR review attempts over the past 7 days set your current allowance at 1 review per hour.

Your organization has reached its usage spending cap. Adjust your spending cap in the billing tab.

How can I continue?

Wait for the limit to reset, then comment @coderabbitai review or push new commits to the PR.

An organization admin can change what happens after included review limits in Billing.

How do review limits work?

CodeRabbit enforces per-developer PR review limits within each organization.

For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 69ad7d4c-dffb-485e-be82-6f7c7acb6fc3

📥 Commits

Reviewing files that changed from the base of the PR and between 175c641 and 536747b.

📒 Files selected for processing (2)
  • docs/branch-review-records/e5aed82f89e308e20fae2728a7601d6f36d8d946da7b21e5adf1163a061a530a.record.md
  • tests/ui-visual-baseline.spec.ts

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 5d56594c-d8c6-4cc1-837f-58cd7fc607b7

📥 Commits

Reviewing files that changed from the base of the PR and between 31b02fd and 175c641.

📒 Files selected for processing (6)
  • src/components/DocumentViewer.tsx
  • src/components/document-viewer/document-overview-landing.tsx
  • tests/document-viewer-shell.dom.test.tsx
  • tests/helpers/phone-scroll.ts
  • tests/ui-phone-scroll-page-owned.spec.ts
  • tests/ui-smoke.spec.ts

Included review availability: 0 reviews are currently available. Your included PR review attempts over the past 7 days set your current allowance at 1 review per hour.


📝 Walkthrough

Walkthrough

Document search now uses a dedicated mobile footer composer. Document actions and overview actions open it. Closing resets search state, handles Escape, restores focus, and updates phone footer layout.

Changes

Document search composer

Layer / File(s)Summary
Search action contract and entry points
src/components/DocumentViewer.tsx, src/components/document-viewer/document-overview-landing.tsx
“Add to scope” was removed. Mobile and desktop actions now open “Search document” with expanded-state accessibility attributes.
Composer lifecycle and phone layout
src/components/DocumentViewer.tsx
The composer now manages open and close state, focus restoration, Escape handling, search resets, stale-response cleanup, footer ownership, and mobile spacing.
Search and phone behavior validation
tests/document-viewer-shell.dom.test.tsx, tests/helpers/phone-scroll.ts, tests/ui-phone-scroll-page-owned.spec.ts, tests/ui-smoke.spec.ts
Tests cover on-demand opening, focus behavior, state cleanup, stale responses, action replacement, and phone footer behavior.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk:⚪ Minimal · up to 175c6

This PR makes a localized document-viewer search interaction change, with focused tests and changed journeys passing; no actionable merge-blocking risk remains after normal checks and review.

Sequence Diagram(s)

sequenceDiagram
participant User
participant DocumentActionsMenu
participant DocumentViewer
participant PhoneSearchComposer
User->>DocumentActionsMenu: Select Search document
DocumentActionsMenu->>DocumentViewer: Open document search
DocumentViewer->>PhoneSearchComposer: Render and focus search input
User->>PhoneSearchComposer: Press Escape or select close
PhoneSearchComposer->>DocumentViewer: Close document search
DocumentViewer->>DocumentActionsMenu: Restore focus
Loading

Suggested reviewers:cursoragent

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 6 files.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Title check✅ PassedThe title clearly and concisely describes the main change: making document search available on demand.
Description check✅ PassedThe description covers the required summary, verification evidence, risk, rollback, RAG impact, and governance sections with explicit notes for incomplete checks.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/document-search-toggle-pr

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actionsBot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

CI triage

CI failed on this PR. Automated classification of the 2 failed job(s):

  • Unit coverageneeds investigation: inspect the failing step and uploaded diagnostics; rerun only after classifying the cause.
  • PR requiredneeds investigation: inspect the failing step and uploaded diagnostics; rerun only after classifying the cause.

Compared with main CI run #12711 (success).

Classification is evidence routing, not permission to ignore a failure. Exact quarantined Playwright identities remain governed by the flake ledger.

@chatgpt-codex-connectorchatgpt-codex-connectorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit:f69003e982

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment threadsrc/components/DocumentViewer.tsx
@BigSimmo

Copy link
Copy Markdown
OwnerAuthor

@codex resolve actionable Codex review findings for this pull request and current head using the repository instructions. This is the pull request's single automatic repair pass: do not perform a fresh review, create new standalone findings, or request another review. Work only the existing unresolved Codex threads on the current head. The only repository destination is BigSimmo/Database, and the only branch destination is the pull request head branch codex/document-search-toggle-pr at starting commit f69003e; never publish fixes to a detached or synthetic work branch and never create a stacked pull request. Use the authenticated GitHub connector to commit each approved fix to BigSimmo/Database:codex/document-search-toggle-pr, then verify that the pull request head contains the published commit before reporting success. Always fix P0 and P1 findings. For P2 and lower findings, fix only clear, scoped, low-risk issues; otherwise disposition them with a concise reason. For a fixed thread, reply with as the first line and as the second line. For a no-code disposition, use followed by . These result markers authorize the workflow to close that exact thread only after it verifies a fixed commit is the pull request head; a local-only commit is not a fix. If publication or verification fails, do not use either result marker, do not claim success, and leave the thread open with the blocker. If human input or new authorization is required, do the same. Finish only after every actionable thread is fixed or dispositioned and closed, or explicitly left open for a human decision. Do not update the branch from main, address unrelated reviews, broaden scope, or create more than one scoped fix commit. Do not use external APIs, paid services, credentials, dependency changes, or broad refactors unless explicitly authorized. Add targeted tests where behavior changes and run the narrowest relevant validation.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep them coming!

Reviewed commit:f69003e982

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@BigSimmo
BigSimmo enabled auto-merge (squash) August 20, 2026 18:57
BigSimmoand others added 5 commits August 21, 2026 04:11
…emand
The document-viewer baseline target masked `.document-viewer-composer`
because the composer was always rendered and, being viewport-pinned inside a
~2900px stitched capture, redrew a band of the golden on any unrelated edit
(#278). With search now closed by default the composer is not in the DOM at
all in the state this target captures, and `assertMaskSelectors` fails a mask
that matches nothing — deliberately, so a rename cannot silently stop masking.
`classify-visual-baseline-outcome.mjs` scores that as a non-drift failure, so
the advisory Visual baselines job would have gone hard red on every main push
for a reason unrelated to pixels. The mask is now the sticky header alone;
nothing is lost, since a masked region was never compared, and the closed
composer's resting layout is now inside the golden.
The committed Linux golden drifts with this change (the overview action is
"Search document" and the desktop composer clearance is released while
closed). That is ordinary pixel drift: advisory, and adopted post-land from
the job artifact with `npm run design-system:baselines:adopt`.
Also lands the PR #2199 review-ledger record.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HoyoNN7nCUVDLaE84k6e6c
BigSimmo added a commit that referenced this pull request Aug 21, 2026
…iting a baseline that never ran the job (#2209)
* test(guard-push): make gh availability injectable so the in-flight-CI cases can run
`inFlightCiGuard` probes for the `gh` binary and fails open before either injected
fetcher is consulted. The message-formatting case injected `prViewer` and
`runFetcher` but could not inject that probe, so it only ever exercised the code
under test on a machine that happened to have `gh` installed: green in CI, red in
any bare container, for no product reason.
`ghAvailable` now joins the other two as an injectable, defaulting to the real
probe. The formatting case and the script's own `--self-test` pass it, and a new
case pins the fail-open branch itself — asserting that neither fetcher is
consulted when `gh` is absent, which nothing covered before.
No behaviour change: production callers pass no options and get `ghIsAvailable`.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HoyoNN7nCUVDLaE84k6e6c
* ci: give base-branch pushes their own concurrency group so merges stop evicting each other
`cancel-in-progress: ${{ github.event_name != 'push' }}` was added to stop a later
merge superseding an in-flight main run, and it does that. It does not stop the
other way a run dies: GitHub keeps at most ONE pending run per concurrency group,
so when merges land faster than a run completes, each newly queued main run
cancels the one already waiting. No supersession is involved, so the exemption
never sees it, and main kept landing unverified anyway.
Observed 2026-08-20: `a1c2ced`, `d745d15`, `97f6142` and `1cc0d29` were all
cancelled while a ~70-minute release-browser-matrix held the shared
`CI-refs/heads/main` group. A mobile-`/` CLS regression rode through that gap and
surfaced hours later on an unrelated PR (#2199), where it read as that PR's
failure. It is the same pattern the existing comment already documents from
2026-08-18 (23 of 30 main pushes cancelled) — the earlier fix simply treated the
wrong mechanism.
Pushes now key concurrency on `github.run_id`, exactly as workflow_dispatch and
schedule already do, so a merged commit is never queued behind or evicted by
another. `cancel-in-progress` stays: it is the line that states the intent, and it
remains the only protection if the group key ever changes.
Cost is the one the existing comment already accepts: concurrent main runs, one
per merge, each still scoped by the `changes` job.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HoyoNN7nCUVDLaE84k6e6c
* ci(triage): stop citing a main run that never ran the failing job as a baseline
CI is path-scoped, so a docs-only push to main reports `success` with Lighthouse,
Production UI and Build all skipped. The triage comment nevertheless printed
"Compared with main CI run #N (success)" and labelled the failure
"needs investigation", which reads as "main is green for this job" when main had
never measured it. That is how the mobile-`/` CLS regression was waved through on
PR #2199 — the bot cited run #12662, a docs-only merge that skipped Lighthouse
entirely — and it is the trap ledger #5DYBQQ already recorded from the other side.
The baseline's jobs are now read whatever its conclusion, not only when it failed.
A failing job the baseline did not execute is classified `unbaselined` and says so
in its own words, and the comparison sentence names the jobs that run did not
exercise. `classifyFailedJobs` takes the executed-name list as an optional fourth
argument: omitted means "could not establish", which keeps the previous
classification rather than inventing a verdict — so the `catch` path in the
workflow degrades exactly as before.
Cost is one extra paginated job listing per triage comment, on a workflow that
only runs when a PR's CI has already failed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HoyoNN7nCUVDLaE84k6e6c
* ci(triage): don't let a cancelled baseline job establish a baseline
`executedJobNames` excluded `skipped` by denylist, so every other conclusion
counted as evidence — including `cancelled`. A cancelled job completed no
verification, so a PR's Build failure would still be reported as
`needs-investigation` while citing a main run that never finished that check:
the same wrong claim the previous commit set out to remove, arrived at from a
different conclusion value. It is also the likeliest one here, since a cancelled
main run is this repo's common failure mode rather than a rarity.
Inverted to an allowlist — `success`, `failure`, `neutral` — because the two
mistakes are not symmetric. Calling a job that ran "unbaselined" only says the
comparison is silent there, which costs a reader nothing; calling a job that did
NOT run "baselined" implies main covered the failure. An allowlist therefore
fails in the harmless direction for `timed_out`, `stale`, `action_required` and
any conclusion GitHub adds later, instead of silently treating each new state as
evidence.
Self-test covers cancelled, timed_out, stale, action_required, an unrecognised
future conclusion, and the end-to-end case that a cancelled baseline job yields
`unbaselined`.
Raised by Codex review on this PR (P2).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HoyoNN7nCUVDLaE84k6e6c
---------
Co-authored-by: Claude <noreply@anthropic.com>
@BigSimmo
BigSimmo merged commit 06dc201 into mainAug 21, 2026
26 checks passed
@BigSimmo
BigSimmo deleted the codex/document-search-toggle-pr branch August 21, 2026 09:37
BigSimmo pushed a commit that referenced this pull request Aug 21, 2026
The prior commit on this branch (7455b14) misdiagnosed the CLS source:
it assumed the entrance transform on a freshly-mounted notice card was
the cause, but Chromium's Layout Instability API does not score a
brand-new element's entrance regardless of which CSS property animates
it — confirmed empirically and by review. That fix left the actual
mechanism untouched, and Lighthouse budget still failed on this
branch's head (3dbf548) after it shipped.
Reading the real failing Lighthouse mobile-root report (from CI on
PRs #2199/#2204) shows the true source: `.pwa-notice-stack`
(`layout-shifts` audit, score 0.223) captured mid-shift displaying the
install-prompt card, at the exact box the offline card previously
occupied. `.pwa-notice-stack` is `position: fixed`, so when the set of
visible cards changes while the stack is already on screen — e.g. the
offline card clears the same React commit that reveals the
connection-restored/install cards, both driven by one `online` event —
the stack's height changes while already painted, which is a real,
attributable shift.
`useSettledNoticeSignature` forces every transition between two
different non-empty card combinations through one fully-unmounted
frame, so the stack only ever grows from nothing or shrinks to
nothing, never resizes with a sibling card still on screen. Reverts
the ineffective opacity-only keyframe change and its source-contract
test from the prior commit.
Verified with scripts/measure-cls-attribution.mjs (repo tooling from
ledger #147) driving real headless Chromium: a synthetic offline→online
blip while an install prompt is pending reproduced `.pwa-notice-stack`
as a 0.163 shift source pre-fix, matching the CI magnitude; with this
fix applied under the identical trigger, `.pwa-notice-stack` no longer
appears as a shift source at all.
RAG impact: no retrieval behaviour change — this only touches PWA
notice-stack rendering and its entrance animation, no rag/, retrieval,
or ranking surface.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@BigSimmo@claude