Answer page: symbol off, one number per claim, no safety rail, one panel - #2388
Merged
Conversation
Everything /mockups/answer-chat-perfected-v2 argues for, applied to the live answer surface after the clinical owner approved the look and chose "direction B" for the block beneath the answer (2026-08-26). Written up in docs/answer-page-redesign-handover.md §12.6–§12.8. The assistant shield tile and its grid column are gone from plain-answer-response, the matching ps-[var(--answer-message-gutter)] is gone from the bare AnswerCard header, and the token itself is deleted. The tile was decorative and its column cost about 2.75rem of every line of a clinical answer on a 390px phone. There are two speakers here, the person's turn is already a right-aligned bubble, and what identifies the assistant turn is the verification line above it. maxMarksPerCluster is 1. Checked before changing, not assumed: resolveClaimMarks already counts the remainder into overflow, +N renders it, every source it counts is on the rail below at full tap size, and that rail is where a Review due or Outdated badge lives — per the 2026-08-24 decision that staleness is carried by the row and the drawer and never by the mark. The test now derives its overflow expectation from the cap rather than hard-coding it. The safety card loses its warning-coloured top rule, which spanned a card that also holds Evidence gaps and Report a problem and so coloured two controls carrying no state. Colour moves into the icon tile plus a severity chip built from the finding's own label, now returned as severityLabel rather than run into the citation string. The row still renders whenever priority is set; it is the only route to the safety-findings sheet. Direction B under the answer: AnswerFollowUpSuggestions gains layout="rows" and renders on every width, CrossModeLinksSection gains variant="line", and questions sit above matches. Two second copies go with it — the composer dock no longer receives composerFollowUpSuggestions on the answer mode, and the dashboard no longer renders UniversalSearchAlsoMatches there. Both repeated content already on screen. Pinned so neither returns by accident. cleanCitationTitle now inserts the missing space in "Guideline(EMHS)". Every citation label passes through it, so the safety card, rail cards, drawer and print are fixed together. Display only. Verified: npm run test (871 files, 10502 passed, 1 skipped); npm run verify:ui 520 passed (18.1m) exit 0 — a first run found five failures, all this diff's, one a real aria-controls defect I introduced and four pinning the old layout, each diagnosed and fixed rather than re-run; eslint and tsc clean; check:design-system-contract passed with no ratchet moved (colour-only status indicators 0, status-coloured numerals 0); repo-wide prettier clean. check:production-readiness still fails on pre-existing release-mode privacy debt unrelated to this diff (#HVTYAT) — reported, not suppressed. 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. |
BigSimmo
approved these changes
Aug 26, 2026
BigSimmo
enabled auto-merge (squash)
August 26, 2026 04:53
BigSimmo
pushed a commit
that referenced
this pull request
Aug 27, 2026
… panel Direction B from /mockups/answer-loading-redesign, applied to the live surface after the clinical owner chose it (2026-08-27). `AnswerProgressStepper` is gone. It was a filled accent panel carrying a 36px icon tile, a five-circle stepper with connecting rails, a scrolling ECG trace, a per-second elapsed counter and a Processing details disclosure — roughly 210px of the loudest chrome in the product, occupying the answer's own position for the four to twelve seconds before every answer, on a surface that PRs #2386 and #2388 had just spent their whole argument quietening. It narrated the orchestrator's five stages, which the reader is not operating, and it never showed a single source. `AnswerProgress` replaces it with one status line plus the arriving source rail. The rail is the substantive half. The evidence preview already crossed the stream boundary before the prose — trimmed, owner-scoped, governed, consumed by the client — and was being rendered as a SECOND full panel below the stepper, with its own icon tile, heading and three-column card grid. Two loud blocks in the answer's position, both removed when the answer arrived. It is now a horizontal rail of small cards drawn to look like the source rail the arrived answer renders, mounted inside AnswerProgress rather than beside it, so nothing is removed and nothing jumps when the answer lands. Cards carry a dot, not a number. The preview is the top slice of retrieval in retrieval order; the final list is rebuilt from what the answer cites and re-capped by trust. A number assigned during the wait can point at a different document once the answer lands, which is the precise failure the citation design exists to prevent. Pinned by a DOM test, and stated in the rail's accessible name for a reader who never sees the dot. Checked while building, not assumed: `isDeliverableVerifiedUnit` pins evidence_preview to sequence 0 and rejects a repeat, so the preview crosses once, complete — it cannot accrue card by card. And it is gated behind NEXT_PUBLIC_RAG_INCREMENTAL_EVIDENCE_PREVIEW_RENDER (#100 Phase 1), off by default, so today the line carries the accrual alone via resultCount and the rail is simply absent rather than a placeholder. Improvements beyond the mockup: - Retrieval counts passages and selection counts sources, never one noun for both. Collapsing them is how a reader believes two dozen documents are behind an answer that cites three. Pinned in tests/answer-progress.test.ts. - `fallback` says "Assembling the answer from the sources directly" while it is happening. Twenty of thirty answers in the 2026-08-18 blinded read were source_only; the wait is the honest place to set that expectation. - Processing details became "How this answer was built", shown only after a retrying/fallback/cached run. The old disclosure held the same five stages for every question, which is why nobody opened it. - The elapsed counter is gone. In its place one threshold at 10s appends "taking longer than usual" and does not tick. Nothing can be done with the number while the search is healthy; re-drawing it every second in the position the eye rests on is what made the wait the subject. - SearchProgressBanner (library/document modes) loses its filled accent band and spinning Loader2 for the same line. Fill is how this app marks a hazard. - AnswerSkeleton drops its own status line. Found in the browser, not in a test: it renders in the answer's body slot directly under AnswerProgress, so the screen showed "Writing the answer…" above "Reading your question…". There is now exactly one place that says what is happening. - The completion dot is not green. A status hue that nothing else on the element repeats is a colour-only signal, and it was redundant beside a line already reading "Answer ready in 3s". Caught by check:design-system-contract. Motion. The ECG trace, its two animation tokens, its keyframes and its compositor rules are deleted; the indicator is a 5px dot breathing on opacity. That choice is what holds the contract ui-phone-motion.spec.ts exists for, after Reduce Motion set the trace to opacity 0 and left a dead panel on a physical iPhone: a stopped dot is a complete, correct bullet, where a stopped spinner is a fragment of a circle. The animation stays in globals.css rather than a motion-safe: utility because html[data-motion="full"] must be able to opt back in over the OS, which a Tailwind media variant cannot express. tests/answer-activity-trace-css.test.ts pinned the deleted component, so it is replaced by tests/answer-progress-indicator-css.test.ts carrying the same regression forward against the dot — including an assertion that the trace stays deleted, since a partial revival is how the original defect shipped. docs/search-chrome-behaviour.md's physical-iPhone rubric named the ECG strip by class and would have sent a tester hunting for markup that no longer exists; docs/design-system/COMPONENTS.md named the component in its live-region adoption note. Both updated — the second found by check:dead-code-candidate, which is the gate doing its job. Verified: verify:cheap exit 0 — 37 gates enforced, design-system contract passed (1021 production files, no ratchet moved), 886 test files / 10733 tests passed; Playwright chromium answer-progress-ui-smoke + ui-phone-motion 9 passed, ui-universal-search 20 passed; driven in a real browser at 390px through scoping → retrieving → retrieved(24) → ranking(4 AU, 2 WA) → generating and past the 10s threshold, and again with the preview flag on to confirm six real cards render, link to /documents/<id>?page=&chunk=, and carry no numbers. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012kHT2YKCNnUrVckTaJW6ga
14 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The production half of the answer-page work approved in #2386. Everything here was drawn in
/mockups/answer-chat-perfected-v2first and signed off by the clinical owner on 2026-08-26, including "direction B" for the block beneath the answer.answer-clinical-iconshield tile and its grid column are gone fromplain-answer-response, the matchingps-[var(--answer-message-gutter)]is gone from the bareAnswerCardheader, and--answer-message-gutteris deleted fromglobals.css. The tile was decorative (aria-hidden) and its column cost ~2.75rem of every line of a clinical answer on a 390px phone. There are two speakers on this surface, the person's turn is already a right-aligned bubble, and what identifies the assistant turn is the verification line above it — information rather than decoration.maxMarksPerClusteris1. Nothing is hidden:resolveClaimMarksalready counted the remainder intooverflow,+Nrenders it, and every source it counts sits on the rail immediately below at full tap size. That rail is also where aReview dueorOutdatedbadge lives, per the 2026-08-24 decision that staleness is carried by the row and the drawer and never by the mark — so the one signal that must not be lost was never on the mark to begin with. This was checked in the code before the cap was changed, not assumed.border-t-2 border-t-[color:var(--warning)]spanned a card that also holdsEvidence gapsandReport a problem, colouring two controls that carry no state. Colour moves into the icon tile plus a severity chip built from the finding's own label, whichanswerSupportPrioritynow returns asseverityLabelrather than running into the citation string. The row still renders wheneverpriorityis set — it remains the only route to the safety-findings sheet.AnswerFollowUpSuggestionsgainslayout="rows"(one question per full-width row) and renders on every width;CrossModeLinksSectiongainsvariant="line"(one collapsed row with a preview, opening to the rail it always was); questions sit above matches. Two second copies go with it: the composer dock no longer receivescomposerFollowUpSuggestionson the answer mode, and the dashboard no longer rendersUniversalSearchAlsoMatchesthere. Both repeated content already on screen — the same three questions truncated onto one scrolling line, and a mode-level restatement of the record-level matches directly above it.cleanCitationTitlenow inserts the missing space inGuideline(EMHS). Every citation label passes through that function, so the safety card, rail cards, drawer and print are fixed together. Display only — the stored title is untouched.Verification
npm run test— 871 test files passed (871); 10502 passed | 1 skipped. Includes the repinnedtests/answer-follow-up-chips.dom.test.tsxwiring contract, a new bracket-spacing case intests/citations.test.ts, andtests/answer-claim-marks.test.tswith its overflow expectation derived from the cap rather than hard-coded.npm run verify:ui— full Chromium project set. First run: 5 failed, 515 passed (18.8m). All five were this diff's, none were flakes, and each was diagnosed rather than re-run: one real ARIA defect I introduced (aria-controlspointed at a panel that only existed while expanded — caught by the smoke suite's DOM-integrity audit, fixed by keeping the panel mounted and hidden, withuseIdso two instances cannot collide), and four pinning the old layout, repinned to assert the same content through the new one. Re-run green — figures quoted below.npx eslinton all nine changed source files — exit 0.npx tsc --noEmit— no diagnostics.npm run check:design-system-contract— passed (1012 production files); no ratchet moved.Status-colour boundary: colour-only status indicators 0; status-coloured numerals 0; image inversions 0.npm run formatthen repo-widenpx prettier --check .— "All matched files use Prettier code style!"answer-clinical-iconin the DOM,answer-follow-up-suggestionspresent on a phone for the first time,cross-mode-links-line-triggerpresent,universal-also-matchesabsent,answer-support-cardstill rendering, zero page errors.Risk and rollout
+1instead of two numbers. The reasoning is in the Summary and inanswer-claim-marks.ts: the remainder is counted, the rail below lists every source at full tap size, and review status was never carried by the mark. Second is the removal of two duplicate surfaces; both were second copies of content still on screen, and the mode-level panel still renders on the tools, documents, services and forms result kinds.git revertthe commit. The change is additive-to-optional in shape — every removed element is a render-site deletion rather than a data change, so reverting restores the previous surface exactly.src/lib/rag/**, no retrieval RPC, no ranking surface, no eval harness, no golden fixture.src/lib/answer-claim-marks.tsmaps recorded claims onto already-ranked rail rows for display; it does not select, score or order sources.Clinical Governance Preflight
Clinical KB Database(sjrfecxgysukkwxsowpy)isDemoMode()boundary as before, and no branch here distinguishes demo from live content.Review dueandOutdatedbadges are rendered by the rail card and the drawer, not by the mark, per the recorded 2026-08-24 decision; the stale-evidence banner and the answer-level cautions are untouched; and the+Nnever lets a supporting source go uncounted.Notes
docs/answer-page-redesign-handover.md§12.6–§12.8, which is where a future session will look before touching this surface again.Generated by Claude Code