Preserve contextual back navigation and recent answers - #1788
Conversation
📝 WalkthroughWalkthroughThe PR adds versioned, submission-bound answer-thread persistence with expiration and owner resolution. It also adds contextual browser-history navigation with deterministic fallbacks across dashboard, breadcrumb, differential, document, and therapy views. ChangesAnswer-thread persistence
Contextual back navigation
Supporting behavior updates
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant ClinicalDashboard
participant useAnswerThreadBootstrap
participant AnswerThreadStorage
participant usePersistedAnswerThread
ClinicalDashboard->>useAnswerThreadBootstrap: provide owner and answer-thread state
useAnswerThreadBootstrap->>AnswerThreadStorage: load matching submission snapshot
AnswerThreadStorage-->>useAnswerThreadBootstrap: return normalized persisted thread
useAnswerThreadBootstrap-->>ClinicalDashboard: restore turns, answer, metadata, and display state
ClinicalDashboard->>usePersistedAnswerThread: provide updated thread state
usePersistedAnswerThread->>AnswerThreadStorage: save version-2 snapshot
sequenceDiagram
participant PageBackControl
participant ContextualBackLink
participant BrowserHistory
participant NextRouter
PageBackControl->>ContextualBackLink: activate back control
ContextualBackLink->>BrowserHistory: check available history
alt history available
ContextualBackLink->>BrowserHistory: go back
else no history
ContextualBackLink->>NextRouter: replace fallback route
end
Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint install failed: dependency version conflict. Check your lock file or package.json. Comment |
This pull request has been ignored for the connected project Preview Branches by Supabase. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit:5d7c87a1ab
ℹ️ 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.
There was a problem hiding this comment.
Pull request overview
This PR updates the app’s “back” navigation to prefer returning to the immediately preceding browser-history entry (with a deterministic in-app fallback for direct entry), and introduces tab-scoped sessionStorage restoration of exact-match completed answer threads for up to 12 hours. It also adds/updates privacy copy and strengthens automated coverage around navigation and restoration behavior.
Changes:
- Introduce
ContextualBackLink+navigateContextuallyBackand adopt it across page-level back/crumb controls. - Replace v1 answer-thread persistence with a v2, owner-scoped, TTL-bounded sessionStorage format (including signature matching, migration, sizing limits, and purge-on-invalid behavior).
- Expand DOM + Playwright smoke coverage and add a repo-wide contract test to keep page-level left-arrow semantics consistent.
Reviewed changes
Copilot reviewed 30 out of 30 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| tests/ui-smoke.spec.ts | Adds browser-journey coverage for contextual back behavior and answer-thread restoration without extra answer requests. |
| tests/privacy-ui.test.ts | Updates navigation mocking and asserts new privacy copy related to tab-scoped answer snapshots. |
| tests/patient-safety-plan-privacy.dom.test.tsx | Updates navigation mocking for replace-based fallback and adds Navigation API availability simulation. |
| tests/navigation-back-button.dom.test.tsx | Adds focused DOM tests for history-back vs replace fallback and modified-click/keyboard semantics. |
| tests/medication-record-page.dom.test.tsx | Mocks router back/replace for components now using contextual navigation. |
| tests/information-page-shell.dom.test.tsx | Mocks router back/replace for breadcrumb/back affordances. |
| tests/in-page-nav-header.dom.test.tsx | Extends next/navigation mock to include router back/replace for new back-link behavior. |
| tests/forms-information-disclosure.dom.test.tsx | Mocks pathname + router back/replace to support updated back-link behavior in forms pages. |
| tests/forms-back-navigation.dom.test.tsx | Mocks pathname + router back/replace for forms back navigation. |
| tests/form-priority-facts.dom.test.tsx | Mocks pathname + router back/replace to support updated navigation behavior. |
| tests/form-confirm-callout.dom.test.tsx | Mocks pathname + router back/replace to support updated navigation behavior. |
| tests/factsheet-save.dom.test.tsx | Mocks pathname + router back/replace to support updated factsheet navigation behavior. |
| tests/factsheet-detail-header.dom.test.tsx | Mocks pathname + router back/replace to support updated factsheet navigation behavior. |
| tests/contextual-back-navigation-contract.test.ts | Adds a contract test ensuring production left-arrow usage routes through contextual history-back semantics. |
| tests/answer-thread-storage.test.ts | Expands unit coverage for v2 storage format, TTL, migration, sizing, owner isolation, and signature matching. |
| src/lib/answer-thread-storage.ts | Implements v2 persisted answer thread format with owner scoping, signature checks, TTL bounds, migration, and sizing guards. |
| src/components/ui/page-header.tsx | Adds history-aware breadcrumb behavior via ContextualBackLink. |
| src/components/therapy-compass/screens/detail-screen.tsx | Replaces button-based back behavior with contextual back-link semantics. |
| src/components/navigation-back-button.tsx | Changes navigation behavior to history-back with replace fallback via navigateContextuallyBack. |
| src/components/information-page-shell.tsx | Projects information-page breadcrumbs onto DS Breadcrumb with history-back semantics. |
| src/components/in-page-nav/in-page-nav-header.tsx | Uses ContextualBackLink for the in-page header back control. |
| src/components/DocumentViewer.tsx | Uses ContextualBackLink for “Back to documents” to preserve originating search history. |
| src/components/differentials/differential-stream-workspace.tsx | Uses contextual back-link for returning to differentials home while preserving history. |
| src/components/differentials/differential-presentation-workflow-page.tsx | Uses contextual back-link semantics for the differentials workflow back controls. |
| src/components/differentials/differential-compare-queue-page.tsx | Uses contextual back-link semantics for compare-queue navigation. |
| src/components/contextual-back-link.tsx | Adds the core contextual back-link implementation (history-back with fallback, preserving modified click semantics). |
| src/components/ClinicalDashboard.tsx | Integrates persisted answer-thread restoration and signature-matched snapshotting into the dashboard lifecycle. |
| src/components/clinical-dashboard/use-persisted-answer-thread.ts | Adds a hook to persist/clear answer-thread snapshots in a bounded, metadata-driven way. |
| src/app/privacy/page.tsx | Updates privacy copy to explicitly document tab-scoped answer snapshot retention/expiry and non-offline behavior. |
| docs/design-system/adoption-manifest.json | Updates design-system test linkage to include the new breadcrumb/back behavior coverage. |
Suppressed comments (1)
src/lib/answer-thread-storage.ts:230
savePersistedAnswerThreadreturnsfalseon storage failures (quota exceeded / blocked / unexpected throw) but leaves any previously stored thread intact. That can cause an older completed answer to be restored later even though a newer snapshot failed to persist. Consider best-effort clearing the stored thread on failure to avoid stale/incorrect restoration.
} catch {
return false;
}
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/components/ClinicalDashboard.tsx (1)
666-686: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winA transient
nullowner purges the persisted thread.
resolveAnswerThreadOwnerIdreturnsnullwhileauthStatusis"loading". When the status flips to"loading"during a token refresh or a session revalidation,answerThreadOwnerIdbecomesnull,previousOwnerIdis still the real owner, and line 673 callsclearPersistedAnswerThread(previousOwnerId). The stored thread is deleted even though the account did not change. When the status returns to"authenticated", nothing can be restored.Skip the clear when the new owner id is
null, and only treat a transition between two resolved owners as an owner change.🛡️ Proposed fix
useEffect(() => { const previousOwnerId = previousAnswerThreadOwnerIdRef.current; - previousAnswerThreadOwnerIdRef.current = answerThreadOwnerId; activeAnswerThreadOwnerIdRef.current = answerThreadOwnerId; + // A null owner means "not resolved yet" (authStatus === "loading"), not a+ // different account. Keep the last resolved owner so a refresh does not+ // purge the thread.+ if (!answerThreadOwnerId) return;+ previousAnswerThreadOwnerIdRef.current = answerThreadOwnerId; if (!previousOwnerId || previousOwnerId === answerThreadOwnerId) return; clearPersistedAnswerThread(previousOwnerId); - if (answerThreadOwnerId) clearPersistedAnswerThread(answerThreadOwnerId);+ clearPersistedAnswerThread(answerThreadOwnerId);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/ClinicalDashboard.tsx` around lines 666 - 686, Update the owner-transition effect using answerThreadOwnerId and previousAnswerThreadOwnerIdRef so cleanup and state reset occur only when both the previous and current owner IDs are resolved and differ. Skip clearPersistedAnswerThread and related reset logic when answerThreadOwnerId is null, preserving the persisted thread during transient authentication loading.
🧹 Nitpick comments (1)
src/components/ClinicalDashboard.tsx (1)
860-869: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoffRef reads feed the effect dependency array.
latestTurnandmetadataare read from refs during render. A ref mutation does not schedule a render, so the persistence effect observes a new ref value only when an unrelated state update re-renders the component. The current call sites set the refs immediately beforesetAnswer, so the ordering works today, but the coupling is implicit and easy to break.Consider holding the snapshot metadata in state, or passing an explicit revision counter that changes with each ref mutation.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/ClinicalDashboard.tsx` around lines 860 - 869, Update the usePersistedAnswerThread call in ClinicalDashboard so latestTurn and metadata changes are represented by render-triggering state or an explicit revision counter, rather than relying on reading mutable refs during render. Ensure the persistence effect reruns immediately for every ref mutation, including the updates performed before setAnswer, while preserving the existing persisted values.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/app/privacy/page.tsx`:
- Around line 46-48: Update the privacy text near the completed answer-thread
retention statement to remove the inaccurate claim that the tab-only copy is
never available offline, and instead describe that it is confined to the current
browser tab and not synchronized or shared. Update the matching assertion in the
privacy UI test to expect the revised wording.
In `@src/components/ClinicalDashboard.tsx`:
- Around line 698-711: Prevent restored snapshots from overwriting current
persisted state: in src/components/ClinicalDashboard.tsx lines 698-711, assign
only latestSubmissionSignature and expiresAt from persisted to
latestAnswerSnapshotMetadataRef.current; in
src/components/clinical-dashboard/use-persisted-answer-thread.ts lines 51-58,
replace the metadata spread with explicit latestSubmissionSignature and
expiresAt fields so payload state always comes from current values.
In `@src/components/differentials/differential-presentation-workflow-page.tsx`:
- Around line 745-763: Update both ContextualBackLink controls in
src/components/differentials/differential-presentation-workflow-page.tsx lines
745-763 by replacing min-h-10 with min-h-12. Also add min-h-12 to the back-link
class list in src/components/therapy-compass/screens/detail-screen.tsx lines
38-44.
In `@tests/contextual-back-navigation-contract.test.ts`:
- Around line 33-41: Update the test around productionArrowFiles so it validates
every page-level left-arrow instance rather than passing when any
contextual-navigation token exists in the file. Inspect each arrow’s enclosing
JSX/props and require ContextualBackLink, navigateContextuallyBack, or
history-back behavior for each non-exempt control, while preserving
internalArrowControls exemptions.
In `@tests/navigation-back-button.dom.test.tsx`:
- Around line 96-106: Update the modified-click test around ContextualBackLink
to capture the click event’s defaultPrevented state in the window listener
before cleanup, then assert it is false after dispatching the Ctrl-click. Keep
the existing href and router interaction assertions unchanged.
---
Outside diff comments:
In `@src/components/ClinicalDashboard.tsx`:
- Around line 666-686: Update the owner-transition effect using
answerThreadOwnerId and previousAnswerThreadOwnerIdRef so cleanup and state
reset occur only when both the previous and current owner IDs are resolved and
differ. Skip clearPersistedAnswerThread and related reset logic when
answerThreadOwnerId is null, preserving the persisted thread during transient
authentication loading.
---
Nitpick comments:
In `@src/components/ClinicalDashboard.tsx`:
- Around line 860-869: Update the usePersistedAnswerThread call in
ClinicalDashboard so latestTurn and metadata changes are represented by
render-triggering state or an explicit revision counter, rather than relying on
reading mutable refs during render. Ensure the persistence effect reruns
immediately for every ref mutation, including the updates performed before
setAnswer, while preserving the existing persisted values.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 01d9974a-4954-4a9a-8cb7-779387811a18
📒 Files selected for processing (30)
docs/design-system/adoption-manifest.jsonsrc/app/privacy/page.tsxsrc/components/ClinicalDashboard.tsxsrc/components/DocumentViewer.tsxsrc/components/clinical-dashboard/use-persisted-answer-thread.tssrc/components/contextual-back-link.tsxsrc/components/differentials/differential-compare-queue-page.tsxsrc/components/differentials/differential-presentation-workflow-page.tsxsrc/components/differentials/differential-stream-workspace.tsxsrc/components/in-page-nav/in-page-nav-header.tsxsrc/components/information-page-shell.tsxsrc/components/navigation-back-button.tsxsrc/components/therapy-compass/screens/detail-screen.tsxsrc/components/ui/page-header.tsxsrc/lib/answer-thread-storage.tstests/answer-thread-storage.test.tstests/contextual-back-navigation-contract.test.tstests/factsheet-detail-header.dom.test.tsxtests/factsheet-save.dom.test.tsxtests/form-confirm-callout.dom.test.tsxtests/form-priority-facts.dom.test.tsxtests/forms-back-navigation.dom.test.tsxtests/forms-information-disclosure.dom.test.tsxtests/in-page-nav-header.dom.test.tsxtests/information-page-shell.dom.test.tsxtests/medication-record-page.dom.test.tsxtests/navigation-back-button.dom.test.tsxtests/patient-safety-plan-privacy.dom.test.tsxtests/privacy-ui.test.tstests/ui-smoke.spec.ts
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.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
…-back-answer-cache-05ea-1 # Conflicts: # src/components/in-page-nav/in-page-nav-header.tsx
Keep signature-mismatched snapshots for forward restore, store only metadata on restore, preserve guest threads across initial signed-out auth, correct privacy copy and tap targets, and mock usePathname after the main in-page-nav merge.
…-back-answer-cache-05ea-1
ClinicalDashboard exceeded the 4140-line no-growth gate after the contextual-back/answer-cache work. Move owner/bootstrap restore into useAnswerThreadBootstrap and merge latest main.
CI triageCI failed on this PR. Automated classification of the 2 failed job(s):
Compared with main CI run #9606 (cancelled). Classification is evidence routing, not permission to ignore a failure. Exact quarantined Playwright identities remain governed by the flake ledger. |
…-back-answer-cache-05ea-1
Production UI (2) timed out waiting for Breadcrumb/Medications exact inside medication-page-*; MedicationNavHeader exposes aria-label "Back to medications" outside that test id. Align with the in-page-nav Playwright contract from #1781 and guard the quick-links block against the old selector.
…ards Controlled sr-only template radios could miss native label activation after scroll-into-view on Production UI shard 1. Select from label click as well, and force-check the radio in the Playwright journey.
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
tests/in-page-nav-playwright-contract.test.ts (1)
23-26: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winValidate source-block boundaries before slicing.
If the closing test title is renamed or removed,
indexOfreturns-1.source.slice(start, -1)then includes almost all remaining source text. An unrelated later test can satisfy these assertions.
tests/in-page-nav-playwright-contract.test.ts#L23-L26: Assert that both marker indexes exist and that the closing index is greater than the opening index before creatingprescribingBlock.tests/in-page-nav-playwright-contract.test.ts#L39-L42: Apply the same boundary validation before creatingquickLinksBlock.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/in-page-nav-playwright-contract.test.ts` around lines 23 - 26, Validate both opening and closing marker indexes, including that the closing index is greater than the opening index, before creating prescribingBlock in tests/in-page-nav-playwright-contract.test.ts lines 23-26. Apply the same boundary validation before creating quickLinksBlock at lines 39-42, failing the test rather than slicing with invalid indexes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/branch-review-ledger.md`:
- Around line 873-879: Restore any relocated medication-search records to their
original historical positions in the branch-review ledger; do not edit or delete
existing rows. Add only genuinely new records via npm run ledger:append, and use
--supersede only when intentionally replacing a record through that command.
- Line 843: Update the affected branch-review ledger records to explicitly
declare provider-backed check status for the reviewed HEAD, including exact
current-HEAD gate results; when no provider-backed check ran, add the exact
statement “No provider-backed check ran.” Apply this consistently to the visible
2026-08-09 record and the additionally referenced records.
- Around line 853-862: Add an explicit provider-check status correction for the
PR `#1788` ledger entries using npm run ledger:append, stating whether
provider-backed checks ran or were skipped. Do not modify the existing PR `#1788`
rows; append the correction through the ledger command only.
In `@src/components/clinical-dashboard/use-answer-thread-bootstrap.ts`:
- Around line 89-102: In the owner-change reset block of the bootstrap hook,
before the queued state reset, clear autoRunSearchSignatureRef.current, reset
answerTurnSeqRef.current, and reset restoredThreadFromStorageRef.current. Keep
the existing persisted-thread cleanup and queued UI state reset unchanged so the
next owner starts with independent bootstrap and auto-run state.
---
Outside diff comments:
In `@tests/in-page-nav-playwright-contract.test.ts`:
- Around line 23-26: Validate both opening and closing marker indexes, including
that the closing index is greater than the opening index, before creating
prescribingBlock in tests/in-page-nav-playwright-contract.test.ts lines 23-26.
Apply the same boundary validation before creating quickLinksBlock at lines
39-42, failing the test rather than slicing with invalid indexes.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: b7a53bf0-2885-4182-8d7f-5c1dc93ce6a3
📒 Files selected for processing (23)
docs/branch-review-ledger.mddocs/design-system/adoption-manifest.jsonsrc/app/privacy/page.tsxsrc/components/ClinicalDashboard.tsxsrc/components/DocumentViewer.tsxsrc/components/clinical-dashboard/use-answer-thread-bootstrap.tssrc/components/clinical-dashboard/use-persisted-answer-thread.tssrc/components/differentials/differential-presentation-workflow-page.tsxsrc/components/formulation/formulation-builder-page.tsxsrc/components/in-page-nav/in-page-nav-header.tsxsrc/components/therapy-compass/screens/detail-screen.tsxsrc/lib/answer-thread-storage.tssrc/lib/supabase/client.tsxtests/answer-thread-storage.test.tstests/factsheet-detail-header.dom.test.tsxtests/in-page-nav-header.dom.test.tsxtests/in-page-nav-playwright-contract.test.tstests/medication-record-page.dom.test.tsxtests/navigation-back-button.dom.test.tsxtests/privacy-ui.test.tstests/ui-formulation.spec.tstests/ui-smoke.spec.tstests/use-answer-thread-bootstrap.test.ts
💤 Files with no reviewable changes (1)
- src/components/DocumentViewer.tsx
🚧 Files skipped from review as they are similar to previous changes (15)
- src/components/differentials/differential-presentation-workflow-page.tsx
- tests/factsheet-detail-header.dom.test.tsx
- tests/in-page-nav-header.dom.test.tsx
- src/components/in-page-nav/in-page-nav-header.tsx
- tests/medication-record-page.dom.test.tsx
- src/components/clinical-dashboard/use-persisted-answer-thread.ts
- tests/privacy-ui.test.ts
- tests/navigation-back-button.dom.test.tsx
- src/app/privacy/page.tsx
- tests/answer-thread-storage.test.ts
- src/components/therapy-compass/screens/detail-screen.tsx
- tests/ui-smoke.spec.ts
- src/components/ClinicalDashboard.tsx
- src/lib/answer-thread-storage.ts
- docs/design-system/adoption-manifest.json
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.
Uh oh!
There was an error while loading. Please reload this page.
Babysit / unblock progress
|
Uh oh!
There was an error while loading. Please reload this page.
Babysit / unblock summary
|
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 37 out of 37 changed files in this pull request and generated no new comments.
Suppressed comments (1)
src/components/clinical-dashboard/use-answer-thread-bootstrap.ts:92
useAnswerThreadBootstraptreats an intermediateanswerThreadOwnerId === nullas a real owner transition. That happens during auth-settling (e.g. starting a sign-in flow sets authStatus toloading), and this effect then clears sessionStorage + wipes the in-memory answer UI even if the user never actually switches accounts.
To preserve the “restore for up to 12 hours” behavior for guest sessions until an identity change is confirmed, avoid committing null into previousAnswerThreadOwnerIdRef and avoid running the clear/reset path when the new owner is null (transient state).
useEffect(() => {
const previousOwnerId = previousAnswerThreadOwnerIdRef.current;
previousAnswerThreadOwnerIdRef.current = answerThreadOwnerId;
activeAnswerThreadOwnerIdRef.current = answerThreadOwnerId;
if (!previousOwnerId || previousOwnerId === answerThreadOwnerId) return;
clearPersistedAnswerThread(previousOwnerId);
if (answerThreadOwnerId) clearPersistedAnswerThread(answerThreadOwnerId);
answerThreadBootstrappedRef.current = false;
Summary
RAG impact: no retrieval behaviour change — this changes client-side history navigation and exact-match answer restoration only.
Verification
npm run verify:pr-localnpm run verify:uiwhen UI, routing, styling, browser behavior, reduced-motion, or forced-colors behavior changednpm run verify:releasebefore release or handoff confidence claimsnpm run eval:retrieval:quality(must stay 36/36) when retrieval, ranking, selection, chunking, or scoring behavior changednpm run eval:rag -- --limit 15+npm run eval:quality -- --rag-onlywhen answer generation, the synthesis prompt, or answer post-processing changednpm run check:production-readinesswhen clinical workflow, privacy, environment, Supabase, source governance, or deployment behavior changednpm run check:deployment-readinesswhen deployment startup, hosting, or rollout behavior changedAdditional local evidence:
npm run typecheck,npm run lint,npm run format, changed-file formatting, diff checks, maintainability budgets, design-system adoption, and installed-lock parity passed.npm run eval:rag:offline: 574 tests passed; 36 golden cases across 23 suites./api/answer/streamrequest.npm run verify:cheapreached the full-unit baseline and reported 22 failures rooted in five unchanged bundle-budget fixtures plus Windowsln/temporary-cleanup failures.Risk and rollout
5d7c87a1a.Clinical Governance Preflight
Clinical KB Database(sjrfecxgysukkwxsowpy)Notes
sessionStorageonly. They are not stored inlocalStorage, synchronized across tabs/devices, cached by the service worker, sent to a backend, or available offline.ef9bb51662dbefbfd6f10778052b7180a3efb53f; currentmainadvanced by one commit before publication, with the original base still an ancestor ofmain.Summary by CodeRabbit
New Features
Bug Fixes
Documentation
Tests