Answer page: replace the source capsule, sheets and table column with a rail and a drawer - #2362
Conversation
… a rail and a drawer The answer page carried four separate places to check a source: a "Sources" capsule opening a popover on desktop and a sheet on phone, a five-tab Evidence sheet, a Clinical notes sheet, and a sticky table column on wide screens. That is four mental models for one question — where did this come from? — and the design study found it is why the page reads as busy rather than trustworthy. Replace all four with one source rail under the answer and one drawer behind every row. The rail lists each cited document with its index badge, title, page, support level and review status; the drawer carries that document's support statement, cited passage, tables, images, and the route back to the original PDF. Implements the four owner decisions recorded in the handover on 2026-08-24. New modules answer-source-rail.tsx, answer-source-drawer.tsx and the shared leaf answer-source-rows.ts. The drawer is built on the existing ui/sheet, so the portal, focus trap, late focus return and phone/desktop split are the ones every other product overlay uses. AnswerSupportSummaryCard becomes the answer-level strip: the priority/safety row, an evidence-gaps disclosure from renderModel.warnings, and a "Report a problem" disclosure wrapping the existing AnswerFeedbackPanel. Gaps and feedback are statements about the answer rather than about any one document, so they stay on the card instead of following per-source content into the drawer. The safety findings sheet is unchanged and still reachable: answerSupportPriority returns a safety priority ahead of everything else and its trigger lives in this card. The quote cards' follow-up action moved into the drawer with the passage it asks about, rather than being dropped with the sheet that used to host it. A table whose chunk matches no cited source falls to the first source, and an answer carrying tables with no cited source at all renders them in place, so no table can become unreachable. compactCitations now collapses the rail to a chip that expands on tap. The zero-source "No direct source found" warning stays worded in every mode. Four defects the gates caught, fixed rather than worked around: - the rail's <ol> tripped the ui-smoke guard that the primary answer must read as prose and not a bullet list, so it uses the role="list" idiom the capsule preview used for the same reason - both new disclosures pointed aria-controls at ids absent while collapsed - the row's aria-label replaced its own text, silencing the support level and review status; the accessible name now restates both - a table with no cited source had no drawer to live in A short phone answer is taller than it was, because the rail lists sources inline where the capsule was one chip. The row was compacted so title and metadata share a single 48px tap target, and the two phone-geometry guards now measure the rail as real content the same way they already measure the also-matches panel and the answer-card support label. The flat 8px unexplained-overflow allowance is unchanged. Old code is left in place rather than deleted: source-preview-popover.tsx, sourceCapsuleDisplay, ClinicalNotesChecklistPanel and MobileEvidenceSheetContent all stay pinned by their existing tests. Their removal is staged separately, after the threshold-scan question is re-checked against real answers. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AP3MXGx1bGeEBmFKYkeLA8
This pull request has been ignored for the connected project Preview Branches by Supabase. |
Warning Review limit reachedNext included review available in 46 minutes. View limit detailsLimit details: You’ve used the included review currently available. Your 103 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. Review configuration: ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (13)
Comment |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 3 potential issues.
Bugbot Autofix prepared fixes for all 3 issues found in the latest run.
- ✅ Fixed: Feedback hidden on clean answers
- The support card now mounts whenever onSubmitFeedback is wired, so a clean high-trust answer still shows Report a problem.
- ✅ Fixed: Duplicate rail IDs break focus
- Prior-turn rails no longer emit drawer return-focus ids, and each rail list uses a unique useId so getElementById restores the live row.
- ✅ Fixed: Images attach to wrong source
- Images now follow the table rule: attach by matching chunk id, otherwise only the first source, never every row that shares a document.
You can send follow-ups to the cloud agent here.
Reviewed by Cursor Bugbot for commit ded3adc. Configure here.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit:ded3adcbf4
ℹ️ 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".
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
BigSimmo
commented
Aug 24, 2026
@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 claude/answer-page-redesign-review-4ufdl5 at starting commit ded3adc; 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:claude/answer-page-redesign-review-4ufdl5, 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. |
CI triageCI failed on this PR. Automated classification of the 2 failed job(s):
Compared with main CI run #13803 (failure). Classification is evidence routing, not permission to ignore a failure. Exact quarantined Playwright identities remain governed by the flake ledger. |
This request touches a high-risk clinical source-rendering path and requires xhigh reasoning effort under the repository’s reasoning-effort policy. Please select xhigh in the Cloud reasoning control, then resubmit the same request with the exact marker:
No repository inspection, edits, tests, commits, pushes, thread replies, or resolutions were performed. |
…ent. Keep Report a problem on clean high-trust answers, stop prior-turn rails from stealing drawer focus restore, and attach images by chunk with an unmatched-S1 sink.
The three `clinical table mobile expansion` cases were rewritten for the drawer in the previous change but never re-run on their own; the full Chromium sweep found them red. Two causes, both mine: The test opened the first rail row and expected a table there, but a table hangs off the source it was cited from, which is not necessarily the best match. It now searches the rows the way the sibling `demo answer flow` test already did. Its focus-trap assertions looked the full-screen table dialog up by name. That became ambiguous once the nested dialog opened inside the source drawer, because the drawer is a dialog too and carries the document's name — so the lookup could resolve to the drawer instead. They now use the handle `openMobileTableFullscreen` already returns; the assertions are unchanged. Also adds a case pinning that evidence gaps stay answer-level: they are listed on the support card rather than against any one cited source. The three source fixes for the review findings landed on this branch concurrently from the Cursor autofix agent. Its versions are equivalent to the ones written here and its `showInlineSupportCard` condition is the better of the two — it names the rows that would render rather than hard-coding true — so they are kept as pushed rather than duplicated. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AP3MXGx1bGeEBmFKYkeLA8
Uh oh!
There was an error while loading. Please reload this page.



Summary
answer-source-rail.tsx,answer-source-drawer.tsx, and the shared leafanswer-source-rows.ts.answer-content.tsx; the cited list is now on the page rather than one tap behind a chip.answer-result-surface.tsx. Their per-source content (claims, quotes, tables, images) is what the drawer carries; the quote cards' "ask a follow-up" action moved into the drawer with the passage it asks about.AnswerSupportSummaryCardto the answer-level strip: the priority/safety row, an evidence-gaps disclosure built fromrenderModel.warnings, and a "Report a problem" disclosure wrapping the existingAnswerFeedbackPanel. Evidence gaps and feedback are statements about the answer rather than about any one document, so they stayed on the card instead of following the per-source content into the drawer.answerSupportPriorityreturns a safety-findings priority ahead of everything else and its trigger lives inside this card, so the card renders wheneverpriorityis set. Removing it outright would have removed the only route to safety-critical source findings.compactCitationspreference at the rail: it collapses to a single chip that expands on tap. The zero-source "No direct source found" warning stays worded in every mode — compact must never hide a missing-source signal.tests/rendered-text-formatting.test.tsto scan the three new modules, so the raw-render guards that covered the capsule preview travel with the code rather than being escaped by the move.This implements the four owner decisions recorded in
docs/answer-page-redesign-handover.md§10 on 2026-08-24, and the design drawn at/mockups/answer-chat-perfected-v2. Rows aremin-h-12(48 px) throughout; they are deliberately notmin-h-11.Two things the redesign costs, both known and accepted:
Old code is deliberately left in place rather than deleted in this change:
source-preview-popover.tsx,sourceCapsuleDisplay,ClinicalNotesChecklistPanel, andMobileEvidenceSheetContentall stay on disk and stay pinned by their existing tests. Their removal is staged as a separate change in handover §8, after the threshold-scan question in §10a has been re-checked against real answers.Verification
npm run test— 834 files, 10048 passed | 1 skipped, 0 failed.docs/design-system/adoption-manifest.jsonwas regenerated withnpm run design-system:adoption:update(the Sheet consumer moved fromanswer-content.tsxtoanswer-source-drawer.tsx).npx tsc --noEmit— clean.npm run lint— clean at--max-warnings 0.npm run format— run, and the result is committed.npx prettier --check .on the pushed tree:All matched files use Prettier code style!npm run ensure— server confirmed at the URL it printed; never assumed a port.@criticaldemo answer flow reaches a source-backed answer, bothCopy control matches the visible clinical tableviewports,phone short answer stays top-aligned with no phantom scroll into black, andphone answer result keeps the edge dock and shared chrome synchronized on a short runway. The full--project=chromium --grep-invert "@quarantine|@mockup"sweep (561 tests) was still running locally when this PR was opened; its result is reported in a follow-up comment. CI's Production UI job is the authoritative run.npm run arbiter -- testreturnedRUN "test" — rag scope never defers — CI's own routing treats it as heavy, so the full suite was run rather than deferred.npm run check:dead-code-candidate -- --diff origin/mainreports FAIL with 4 refusals, and the refusals are the tool's re-export blind spot rather than deletions:sourceCapsuleDisplay,sourceStatusDotToneandsourceStatusShortLabelwere moved toanswer-source-rows.tsand re-exported fromanswer-content.tsx, which the per-file scan does not follow.tests/status-semantics.dom.test.tsxandtests/answer-preferences.dom.test.tsximport them from the original path and pass, which is the direct evidence they still resolve. The fourth,SourcePreviewContent, was module-private and its only "pin" is a mention inside a comment. Nothing was tuned to make this pass, and the gate is not wired into CI.npm run eval:retrieval:quality,npm run eval:rag,npm run eval:quality,npm run verify:release,npm run check:production-readiness— all provider-backed, and no retrieval, ranking, selection, chunking, scoring, or answer-generation code is touched by this diff.Risk and rollout
src/lib/rag/, no retrieval RPC, no ranking surface, and no golden fixture is touched.classifyPullRequestFilesreturnsragRanking: falsefor this diff.Clinical Governance Preflight
Completed because this change alters source rendering and document access on the answer surface, even though
classifyPullRequestFilesreturnsclinicalRisk: falsefor these paths.Clinical KB Database(sjrfecxgysukkwxsowpy). No Supabase configuration, migration, or client code is touched.isDemoMode()fallback as before.review_dueoroutdatedsource telling the reader to confirm the passage against a current source. Per decision 1, staleness is never encoded in the reference mark's colour alone. Unknown metadata still falls to the muted tone through the unchangedsourceStatusDotTone.Notes
aria-controlsonly while their panel is in the DOM. Pointing it at an absent id was caught byexpectDomIntegrity's broken-ARIA audit during this work, not guessed at.role="list"divs rather than an<ol>. It sits insideplain-answer-response, where a ui-smoke guard asserts the primary answer reads as prose and not as a bullet list; the source-capsule preview it replaced used the same idiom for the same reason.aria-labelreplaces the row's own text — without them a screen reader would hear the title and page but never that the document is outdated.dedupeVisualEvidenceonly filters against the primary sources when there are some). Those render in place rather than being lost with the column.answerViewModeinClinicalDashboard.tsxis write-only for now and carries a comment saying so. Its only reader was the clinical-notes panel; the state and its resets stay until that panel is removed in the follow-up, so a view mode does not have to be rebuilt from scratch.Generated by Claude Code
Note
Medium Risk
This is a full replacement of how clinicians reach cited PDFs, passages, and tables on the answer surface with no feature flag; regressions would affect verification workflows, though RAG and backend paths are unchanged.
Overview
Replaces the answer page’s four separate source UIs (Sources capsule + popover/sheet, Clinical notes sheet, Evidence sheet, and the desktop table column) with a single source rail under the prose and a shared
AnswerSourceDraweropened from each row. Shared cited-document logic lives inanswer-source-rows.ts(up to six rows); the rail and drawer both consume it so lists do not drift.NaturalLanguageAnswerdrops inline source preview chrome and wiresonOpenSourceinto the surface-owned drawer.StagedAnswerResultSurfaceremoves clinical-notes/evidence sheets and the table aside; tables, passages, images, and “ask about this passage” follow-up move into the drawer (uncited-only tables still render inline).AnswerSupportSummaryCardis trimmed to safety/priority, collapsible evidence gaps fromrenderModel.warnings, and Report a problem feedback; clinical-notes and evidence entry points are gone.ClinicalDashboardstops passing evidence-map props and makesanswerViewModewrite-only pending panel removal.Tests add
answer-source-rail.dom.test.tsx, extend formatting guards to the new modules, and retarget ui-smoke/stress flows to rail → drawer behavior (focus return, paging, tables in drawer).Reviewed by Cursor Bugbot for commit ded3adc. Configure here.