Skip to content

feat(navigation): one shared home page, mode-routed search - #1744

Merged
BigSimmo merged 24 commits into
mainfrom
claude/mode-routing-search-pages-jabe17
Aug 8, 2026
Merged

feat(navigation): one shared home page, mode-routed search#1744
BigSimmo merged 24 commits into
mainfrom
claude/mode-routing-search-pages-jabe17

Conversation

@BigSimmo

@BigSimmoBigSimmo commented Aug 8, 2026

Copy link
Copy Markdown
Owner

Summary

  • One shared home page./ is now the common home for every one of the 13 modes — the "How can I help?" hero with the composer. The mode pill at the top no longer navigates: it only decides where the composer sends you when you submit. Picking DSM keeps the page exactly where it is and swaps the placeholder to "Search DSM diagnoses or criteria…"; submitting then lands on /dsm/search?q=…. Previously each mode pick ran router.push(appModeHomeHref(mode)) and replaced the whole page, so the app had 13 front doors and no single home.
  • The routing table barely moved.appModeHomeHref already mapped (mode, query) to each mode's search destination, so this is not a routing rewrite. Tools keeps opening its own home (/tools?q=…&run=1) because it has no search route — the requested exception falls out for free. Factsheets routes to its existing /factsheets/search.
  • ask() gained a navigation branch. It previously navigated for documents only; every other mode ran executeSearch in place. That was safe only while "/ plus a namespaced mode" was unreachable, which is now the normal state — without this, submitting in DSM would have silently run an in-dashboard search. The branch reuses isDashboardModeHref, so answer/prescribing/documents fall through unchanged and every namespaced mode navigates.
  • Mode selection no longer navigates. On the shared home it rewrites ?mode= with history.replaceState (no push, so Back still leaves home rather than stepping through mode picks) and lets the existing render-time URL sync own searchMode — never an optimistic state set, per the hero-vs-dock rule in docs/search-chrome-behaviour.md. Off the home, a query in play is carried into the newly picked mode instead of being dropped.
  • Bare /?mode=X renders the home with X preselected; a submitted deep link (q plus run=1) still resolves to the mode's own search surface. This is a deliberate meaning change for bare ?mode= bookmarks.
  • The last selected mode is remembered per browser, seeded only once on a cold / visit so a shared or reloaded ?mode= link never flips after hydration.
  • Documents and Medication gained real homes at /documents and /medications. They were the only two modes without their own route, so the shared home would otherwise have left their content — the Documents "Start here" panel with Recent documents / Browse library / Open a source PDF, and the Medication home — unreachable. /medications was previously a 307 alias for /?mode=prescribing.
  • The sidebar gained a "More modes" group (Forms, Differentials, DSM, Specifiers, Formulation, Therapy) in both the expanded panel and the collapsed rail, keeping every mode home reachable now that the pill does not open them.

Two bugs were caught by the Chromium journeys that the unit suite could not see, and are fixed here:

  1. The remembered-mode seed re-fired on every searchMode change and rewrote ?mode= back, silently undoing in-app mode changes that do not touch the URL — "Add document" bounced straight back to Answer. It now seeds at most once per mount and never reads searchMode.
  2. /medications is listed in alwaysStandaloneShellPathPrefixes, a documented set of routes that must never mount ClinicalDashboard (that exclusion is what fixed duplicate page-root data-testids under CI load). The new mode home therefore rendered header and composer over an empty body. It now owns its own body, exactly as /tools and /services do.

Verification

Verification not run: npm run verify:pr-local and UI verification not run: npm run verify:ui — both stop at check:installed-lock-parity before executing anything, because this container ships Playwright 1.62.0 against a locked 1.62.1. That mismatch is pre-existing and unrelated to this diff, and npm ci cannot repair it here (Node is 24.13.0 while jsdom@30.0.1 requires ^24.15.0 under engine-strict). No manifest or lockfile was modified to work around it.

Everything those two gates would have run was therefore run directly, and the browser evidence is real rather than skipped:

  • Chromium journeys — the full PR set, via the repo's own runner and isolated production server (npm run test:e2e:pr, with PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH pointed at the container's Chromium, since its bundled rev 1194 predates the rev 1234 the packaged versions expect): 406 passed, 2 failed (11.5m).

    • Both remaining failures were verified to fail identically on a clean worktree at the base commit bc33d41, so neither is caused by this diff: ui-pwa.spec.ts "has a browser-valid manifest…" (Chromium reports installability error in-incognito) and ui-smoke.spec.ts "document viewer puts the PDF preview first with pinned evidence after it on mobile". This diff touches no manifest, service-worker, icon, or document-viewer file.
    • For context, this started at 17 failures; every one attributable to the change is fixed.
  • Unit suite: Test Files 522 passed | 1 failed (523) / Tests 5608 passed | 1 failed | 4 skipped (5613). The single failure is tests/pr-handoff-stop.test.ts, which also fails on a clean checkout of the base commit.

  • npm run lint: clean. npx tsc --noEmit: clean (exit 0).

  • npm run sitemap:check, docs:check-index (all 50 repository roots/modules/routes … indexed), docs:check-inventory, check:design-system-contract (53 components and 7 guidelines), check:outstanding-issues (275 rows … unique ids): all pass.

  • npm run format was run and committed.

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

Not a release handoff, and it is provider-backed.

  • npm run eval:retrieval:quality

RAG impact: no retrieval behaviour change — no file under src/lib/rag/**, clinical-search, retrieval-selection, ranking-config, answer-ranking, the eval harness, or the golden fixture is touched. classifyPullRequestFiles reports ragRanking: false. Only which URL the composer navigates to changed; retrieval, ranking and answer generation are untouched.

  • npm run check:production-readiness

No clinical workflow, privacy, environment, Supabase, source-governance, or deployment behaviour changed.

Risk and rollout

  • Risk: the change is concentrated in ClinicalDashboard.tsx, which owns the answer flow, document search, the medication workspace, and the Tools and Favourites hubs in one large component. The shared home is inserted as a single branch above that chain, which shadows five existing branches. It is gated strictly on "home route and nothing submitted", so every submitted path still reaches exactly the branch it reached before. The second risk is behavioural rather than structural: bare /?mode=X changes meaning from "redirect to /X" to "home with X preselected", so an existing bookmark of a bare ?mode= URL now lands on the shared home instead of the mode page. Submitted deep links are preserved.
  • Rollback: revert the commits on this branch. No migration, no generated clinical data, and no persisted state beyond one additive localStorage key (clinical-kb-last-app-mode), which is read defensively and falls back to Answer for any absent, malformed, or retired value.
  • Provider or production effects: None.

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

This change is navigation only. It alters which URL the shared composer routes to and which surface / renders; it does not touch retrieval, ranking, answer generation, answer verification, citation rendering, source governance, or document access scoping. Owner-scoping and private-scope handling are unchanged, and the conservative source-only degradation path is untouched.

Notes

  • The diff is wider than "one home page" suggests because /?mode=documents and /?mode=prescribing were hardcoded in the sidebar, the tools catalogue, and a number of Playwright specs. Those are mechanical repoints to the new /documents and /medications homes, but they are worth an eye at review.
  • Two pre-existing environment problems in this container, neither caused by this diff and neither committed: tailwind-merge was declared in package.json but absent from node_modules (restored at its locked 3.6.0), and npm ci cannot complete here because Node is 24.13.0 while jsdom@30.0.1 requires ^24.15.0 under engine-strict. No manifest or lockfile was modified.
  • therapy-compass still reaches its search page through a server redirect() rather than the helper's path swap. That asymmetry predates this change and is left alone.

Generated by Claude Code

Summary by CodeRabbit

  • New Features
    • Added dedicated /documents and /medications home pages.
    • Mode selection now remains on the shared home until a search is submitted.
    • Added a “More modes” sidebar section for additional clinical tools.
    • Preserves selected modes and search context across navigation.
    • Updated Medication PWA shortcut and related navigation links.
  • Documentation
    • Updated sitemap and design-system coverage for the new routes.
  • Bug Fixes
    • Improved routing for submitted searches and standalone mode pages.

The mode pill at the top of the screen was a navigation control: picking a
mode ran router.push(appModeHomeHref(mode)) and replaced the whole page, so
the app had 13 front doors and no single home.
`/` is now the common home for every mode — the "How can I help?" hero with
the composer. The pill no longer navigates; it only decides where the
composer sends you on submit. Picking DSM keeps the page and swaps the
placeholder; submitting lands on /dsm/search?q=…
appModeHomeHref already mapped (mode, query) to the right search destination,
so the routing table is essentially unchanged. Tools keeps opening its own
home (/tools?q=…&run=1) because it has no search route — the requested
exception falls out for free.
Main changes:
- Mode selection stops navigating. On the shared home it rewrites `?mode=`
with history.replaceState (no push, so Back still leaves home) and lets the
existing render-time URL sync own searchMode — never an optimistic set, per
the hero-vs-dock rule in docs/search-chrome-behaviour.md. Off the home, a
query in play is carried into the newly picked mode instead of dropped.
- ask() gains a navigation branch. It previously navigated for documents
only; every other mode ran executeSearch in place, which was safe only
while `/` plus a namespaced mode was unreachable. That is now the normal
state, so submitting in DSM would otherwise have run an in-dashboard search.
- showAnswerHome becomes showSharedHome, gated on the pathname rather than
the mode, and sits at the top of the mode-content chain.
- Bare /?mode=X renders the home with X preselected; a submitted deep link
(q plus run=1) still resolves to the mode's own search surface.
- The last selected mode is remembered per browser, seeded only on a cold `/`
visit so a shared or reloaded ?mode= link never flips after hydration.
- Documents and Medication gain real homes at /documents and /medications.
They were the only modes without their own route, so the shared home would
otherwise have left their content unreachable. /medications was previously
a 307 alias for /?mode=prescribing.
- The sidebar gains a "More modes" group for the six modes it never listed,
keeping every mode home reachable now that the pill does not open them.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wa7MTVhAJMztFMMhzJf2J4
`/?mode=tools&q=…` without run=1 now prefills the shared home's composer
rather than rendering Tools content on `/`, so this journey asserts the
launcher from its canonical surface instead.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wa7MTVhAJMztFMMhzJf2J4
…e change
The cold-`/` seeding effect re-fired whenever `searchMode` changed and rewrote
`?mode=` back to the remembered mode, silently undoing in-app mode changes that
do not touch the URL — openDocumentsDrawer sets the mode directly, so "Add
document" bounced straight back to Answer.
Guard it with a ref so it seeds at most once per mount, and drop `searchMode`
from the dependencies entirely so an in-app change can never retrigger it.
Caught by the Chromium journeys (ui-accessibility, ui-formulation); both specs
are green again — 23 passed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wa7MTVhAJMztFMMhzJf2J4
…ey updates
/medications is in alwaysStandaloneShellPathPrefixes, so ClinicalDashboard never
mounts there — that exclusion is what stopped the duplicate page-root testids
under CI load, so the route must render its own body like /tools and /services
do. Without it the new mode home rendered header and composer over empty content.
Also retargets the remaining journeys that assumed a mode's content lives on `/`:
/?mode=tools now prefills the shared home, so Tools assertions use /tools, and
the tablet rail expects the new "More modes" group instead of asserting the
specialist catalogues are absent.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wa7MTVhAJMztFMMhzJf2J4
The "Medications" breadcrumb built its href with the drug slug as a query, which
resolved to /?mode=prescribing&q=<slug>. That was the Medication home before this
change; it is now the shared home, so the breadcrumb landed on `/` with the drug
name prefilled instead of on Medications. Drop the query so it resolves to
/medications.
Also fixes the Documents deferred-requests journey: waitForDemoDashboardReady
looks for "Open answer options", but the actions trigger is named for the active
mode, which is Documents on that route.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wa7MTVhAJMztFMMhzJf2J4
…lur in the journey
ClinicalDashboard owns the body on /documents (dashboardOwnedModeHomePaths), so
it owns composer placement too, exactly as it does on `/`. Declaring a shell hero
on top of that gave the route two hero owners. Drop the shell-side placement.
The deferred-requests journey also needed a real dismissal: Escape closes the
scope popover but leaves the composer's command dropdown open, and that dropdown
overlays the home actions beneath it. Blur the composer the way a user would.
Previously the test switched mode after scoping and that re-render reset the
composer for free; the Documents home is now its own route.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wa7MTVhAJMztFMMhzJf2J4
@supabase

supabaseBot commented Aug 8, 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 8, 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 recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in:8 minutes

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

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 15194c3f-08b1-4ea5-a1b6-0d1a38770b48

📥 Commits

Reviewing files that changed from the base of the PR and between 6d1099b and e53d105.

📒 Files selected for processing (12)
  • docs/branch-review-ledger.md
  • docs/design-system/adoption-manifest.json
  • docs/site-map.md
  • scripts/generate-site-map.ts
  • src/app/(search-app)/medications/page.tsx
  • src/app/(search-app)/page.tsx
  • src/components/ClinicalDashboard.tsx
  • src/components/clinical-dashboard/master-search-header.tsx
  • src/lib/document-flow-routes.ts
  • tests/app-modes.test.ts
  • tests/audit-navigation-auth-regressions.test.ts
  • tests/ui-smoke.spec.ts
📝 Walkthrough

Walkthrough

The change adds standalone /documents and /medications routes. Shared mode selection now preserves bare mode URLs, remembers the last mode, and redirects submitted searches to mode-specific destinations. Navigation, PWA links, route metadata, adoption records, and tests are updated.

Changes

Mode routing and home surfaces

Layer / File(s)Summary
Standalone route contracts
src/app/(search-app)/documents/..., src/app/(search-app)/medications/..., src/app/(search-app)/page.tsx, src/lib/app-modes.ts, src/lib/search-route-ownership.ts, src/lib/legacy-home-redirect.ts
Documents and Medications now have standalone home routes. Bare mode URLs remain on the shared home. Submitted searches redirect to owned search destinations.
Shared dashboard mode flow
src/components/ClinicalDashboard.tsx, src/components/clinical-dashboard/global-search-shell.tsx, src/components/clinical-dashboard/use-home-mode-seed.ts, src/components/clinical-dashboard/use-last-app-mode.ts, src/components/clinical-dashboard/clinical-dashboard-payloads.ts
The dashboard supports shared mode selection, remembered modes, query preservation, pathname-aware rendering, and dashboard-owned search navigation.
Navigation and prefetch surfaces
src/components/clinical-dashboard/ClinicalSidebar.tsx, src/components/clinical-dashboard/master-search-header.tsx, src/components/clinical-dashboard/medication-record-page.tsx, src/components/clinical-dashboard/use-app-preferences.ts
Sidebar links, additional mode links, breadcrumbs, landing preferences, and prefetching use the updated mode destinations.
Coverage and adoption validation
tests/*, docs/site-map.md, docs/design-system/*, docs/codebase-index.md, docs/branch-review-ledger.md
Tests and generated records cover standalone routes, shared mode behavior, responsive navigation, prefetching, sitemap entries, and adoption totals.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
participant User
participant GlobalSearchShell
participant ClinicalDashboard
participant Router
User->>GlobalSearchShell: Select an app mode
GlobalSearchShell->>ClinicalDashboard: Preserve mode and query context
ClinicalDashboard->>Router: Replace shared mode URL or push search destination
User->>ClinicalDashboard: Submit a search
ClinicalDashboard->>Router: Navigate to the mode-owned search route
Loading

Possibly related PRs

Suggested labels:codex

Suggested reviewers:claude

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 39.53% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Title check✅ PassedThe title clearly summarizes the primary change: a shared home page with mode-routed searches.
Description check✅ PassedThe description follows the template and documents scope, verification results, risks, rollback, governance checks, and reasons for skipped gates.
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 claude/mode-routing-search-pages-jabe17

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

@BigSimmo

Copy link
Copy Markdown
OwnerAuthor

@cursoragent Work the current open PR end-to-end. Confirm the PR number and GitHub head first from context. If more than one open PR could apply, stop and say which one you would use and why.

Fetch and start from the remote tip that matches that GitHub head. If the named branch ref is missing or stale, use the PR head ref. Preserve unrelated local WIP, including any local-only ledger commits; do not discard dirty work, and do not treat a local-ahead commit as the reviewed tip. Do not merge the PR, force-push, rebase, or arm auto-merge unless I explicitly ask. No provider-backed gates without separate approval. If you cannot push or resolve threads, diagnose and comment only; if inline replies fail, resolve when possible and put dispositions in the summary comment. If auto-merge is already armed, push only for a real blocker, and avoid pushes that would cancel in-flight required CI unless the push itself clears that blocker.

If the PR is already merged or closed: confirm the head and merge commit, note required-CI outcome, post one summary, and stop.

Goal: deep review plus Bugbot, fix actionable issues with the smallest correct changes, clear merge / required-CI / thread blockers, run strong local offline verification, push fixes, append the review ledger, and post one PR summary. Prefer thoroughness over speed. Regenerate large assets only when a fix requires it; then run the asset check and keep compatibility aliases byte-identical where the repo uses them.

Snapshot the GitHub head SHA: tip, base, behind/ahead, mergeable state, merge-tree versus origin/main (real conflict versus behind-but-clean), required checks on that tip including Production UI when selected, advisory separately, unresolved actionable threads. Missing checks while dirty are not green. If the tip moves mid-work, re-snapshot and continue from the new head.

Ledger-lookup against that GitHub head under the heavy review-and-fix scope for this PR. Already reviewed at this head with clean merge-tree, green required checks, and no new actionable threads → summarize, comment, stop unless I asked for a fresh superseding pass. Follow the repo review protocol.

Unblock once: real conflict → merge origin/main (prefer main’s shared queues; keep this PR’s notes); behind-but-clean → one sync, late if required CI is in flight; clean → leave. Labels like skip-branch-sync do not block a manual sync needed to clear a real blocker. No sync thrash. After any sync or push, re-snapshot tip, merge-tree, and required checks before declaring done. Dedupe the ledger if a merge touched it.

Review high-confidence delta risks only. Separate PR-introduced defects from pre-existing re-emitted debt. For generated assets, review contracts, aliases, cache, and manifests—not every generated line. If protected RAG or ranking surfaces are touched, say so before editing; fix PR-body policy text only when wrong or missing. Ignore bot noise. No nit spam or broad rewrites. Escalate verification by touched risk: clinical / RAG / privacy / migrations / auth → domain check plus production-readiness when warranted; UI / phone-chrome / routing / styling → ensure plus phone-chrome or UI gates when warranted; generated assets or docs inventory/links → asset or docs checks when warranted.

Fix P0/P1 always; clear scoped P2 when locally provable; else disposition and resolve. Required-check failures on this tip only; ignore advisory. Prefer reverting a bad autofix commit. After fixes: format and commit before push; smallest targeted proof; repo cheap gate; repo PR-local gate. No release, lighthouse, live eval, or live provider gates without approval.

Push only this PR’s fix commits. Append ledger for the final GitHub head under the heavy scope. Never push a ledger-only tip—include ledger in a real fix push, or leave a no-change ledger append local and unpushed.

One PR comment: tip, sync/merge-tree, fixed versus dispositioned, threads, required CI, decisive local gate lines, residual risks; merge left to me. Inline only for remaining human-needed P0/P1.

Stop when merge-tree is clean on the current GitHub tip, actionable threads are clear, required checks are green or clearly in progress, heavy gates for scope passed, summary posted, merge left to me.

@cursor

cursorBot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Taking a look!

Open in WebOpen in Cursor

Comment threadsrc/components/ClinicalDashboard.tsx

@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:3a0bdd6246

ℹ️ 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/ClinicalDashboard.tsx Outdated
@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 claude/mode-routing-search-pages-jabe17 at starting commit 468cc3f; 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/mode-routing-search-pages-jabe17, 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.

@BigSimmo
BigSimmo enabled auto-merge (squash) August 8, 2026 15:39
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Already looking forward to the next diff.

Reviewed commit:468cc3fce8

ℹ️ 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

Copy link
Copy Markdown
OwnerAuthor

@cursoragent Unblock the current open PR. Confirm the PR number and GitHub head first from context. If more than one open PR could apply, stop and say which one you would use and why.

Fetch and start from the remote tip that matches that GitHub head. If the named branch ref is missing or stale, use the PR head ref. Preserve unrelated local WIP; do not discard dirty work; do not treat a local-ahead commit as the reviewed tip. Do not merge the PR, force-push, rebase, or arm auto-merge. No provider-backed gates without approval. If you cannot push or resolve threads, diagnose and comment only; if inline replies fail, resolve when possible and put blocker dispositions in the summary comment. If auto-merge is already armed, push only for a real blocker and avoid cancelling in-flight required CI unless the push clears that blocker.

If the PR is already merged or closed: confirm outcome, post one summary, and stop.

Primary job: clear mergeability and required-CI blockers on this tip. Do a full product review only if needed to explain or fix a blocker. Stay light otherwise—no broad verification suites or Playwright unless needed to prove one concrete unblock fix.

Snapshot the GitHub head: tip, behind/ahead, mergeable state, merge-tree versus origin/main (real conflict versus behind-but-clean), required checks on that tip including Production UI when selected, and unresolved threads that block merge or required CI. Missing checks while dirty are not green. Tip moved → re-snapshot.

Ledger-lookup against that GitHub head under an unblock/fix scope for this PR. If already handled at this head for unblock work, merge-tree clean, required checks green, and no blocking threads: summarize, comment, stop.

Unblock once: real conflict → merge origin/main with the smallest correct resolution (prefer main’s shared queues; keep this PR’s notes); behind-but-clean → one sync, late if required CI is in flight; clean → leave. skip-branch-sync and similar labels do not block a manual sync needed to clear a real blocker. No sync thrash. After any sync or push, re-snapshot tip, merge-tree, and required checks before declaring done. Dedupe the ledger if a merge touched it.

Fix only what blocks required checks or mergeability on this tip. Ignore advisory red unless it reveals a real required failure. Prefer the smallest safe fix; if a bot/autofix commit caused the break, prefer revert. Prove with the smallest targeted check only. Format and commit before push.

Push only blocker-fix commits. Append ledger for the final GitHub head under the unblock scope. Never push a ledger-only tip.

One PR comment: tip, sync/merge-tree, what blocked and what you fixed or dispositioned, required CI status, residual risks; merge left to me.

Stop when merge-tree is clean on the current GitHub tip, no blocking threads remain for merge/required CI, and required checks are green or clearly in progress.

@cursor

cursorBot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

PR #1744 tip 7c19b35a is already unblocked for mergeability — nothing further to push.

Tip7c19b35a (matches remote)
vs main0 behind / 11 ahead, merge-tree clean
GitHubMERGEABLE · auto-merge armed · BLOCKED only until required CI finishes
ThreadsBoth resolved

The dirty/conflict signal in the prompt was for stale tip 7245446a. That was cleared by the earlier main sync already on this tip.

Required CI: mergeability/policy/SAST/gitleaks green; main CI run 31265563526 still pending. No push (would only cancel in-flight work). Ledger unblock row left local/unpushed.

Merge left to you when CI goes green.

Open in WebOpen in Cursor

cursoragentand others added 2 commits August 8, 2026 15:50
…e homes
Unsubmitted /documents mounts ClinicalDashboard with autoRunSearch always true,
so every composer keystroke fired search. Gate it on run=1 like bare /. Also
point the PWA Medication shortcut and settings landing at real mode homes,
restore /medications?q&run=1 deep links to prescribing results, and let settings
landing win over remembered-mode seeding on cold /.
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
@cursor

cursorBot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

PR #1744 review-and-fix summary

Tip:7c19b35a52c9e2139adf701082f3bafea7124fc6 (claude/mode-routing-search-pages-jabe17)
Base:origin/main @ fc399e230 behind / 11 ahead, git merge-treeclean (GitHub MERGEABLE; BLOCKED only on required checks in flight). Auto-merge is armed; merge left to you.

Sync

  • One behind-but-clean sync after main landed #1737 (false DIRTY cleared). No further sync thrash.

Fixed (pushed in ef895b87, retained through sync)

SevIssueFix
P1/documents always set autoRunSearch=true, so composer keystrokes fired /api/searchGate autoRunSearch on run=1 for dashboard-owned mode homes (isDashboardOwnedModeHomePath)
P2PWA Medication shortcut still opened /?mode=prescribing (shared home, not Medication home)Manifest → /medications?focus=1
P2Settings landing lost to remembered-mode replaceState race; landing also targeted bare /?mode=Landing navigates to /documents or /tools; last-mode seed skips when landing is set
P2/medications?q=&run=1 deep links no longer reached prescribing results after removing the blanket 307Server redirect to prescribing results when submitted

RAG/ranking surfaces: not touched.

Threads (inline replies FORBIDDEN for this token — dispositions here; threads resolved)

  1. Codex P2 landing vs last-modefixed at ef895b874302c9d3d80f77e4a4a7eecae8e2535d.
  2. Sentry/Bugbot tools query lossno-change: /tools?q= is filled by the shared shell SearchCommandProvider / ClinicalDashboard ToolsHub; covered by tests/ui-tools.spec.ts.

Required CI

  • Restarted on the synced tip; in progress at comment time (PR mergeability already green). Advisory ignored.

Local gates (decisive)

  • npm run verify:pr-local on fix tip PASSTest Files 524 passed (524) / Tests 5614 passed | 4 skipped (5618).
  • Focused ownership/manifest/audit vitest: 68 passed.
  • Not run (no approval): verify:release, live evals, provider checks.

Residual risks

  • Shared-home behavioural change for bare /?mode=X bookmarks remains intentional product risk (called out in PR body).
  • Review ledger row for this tip is local/unpushed (to avoid a ledger-only tip after the main sync); working tree has pr-1744 heavy review-and-fix @ 7c19b35a.

Merge left to you.

@cursor

cursorBot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

PR #1744 unblock summary

Tip:7c19b35a52c9e2139adf701082f3bafea7124fc6 (matches remote)
Base:origin/main @ fc399e230 behind / 11 ahead
Merge-tree: clean · GitHub MERGEABLE (BLOCKED only while required CI settles) · auto-merge armed

What blocked (stale context)

The reported PR mergeability dirty failure was on previous tip 7245446a after main advanced with #1737. That is already cleared: this tip includes the main sync merge (7c19b35a).

What I did this pass

  • Confirmed tip/remote match; no push (would only cancel in-flight CI; no remaining mergeability blocker).
  • Merge-tree left clean; no further sync.
  • Threads: both already resolved (Codex landing fixed in ef895b87; Sentry tools-query dispositioned no-change).
  • Ledger: local pr-1744 unblock row for 7c19b35a left unpushed (no ledger-only tip).

Required CI

  • PR mergeability / PR policy / SAST / Gitleaks: pass
  • Main CI run 31265563526: pending on this tip (jobs not yet started / queued)
  • Advisory ignored

Residual

Wait for required CI (incl. Production UI when selected) to finish on 7c19b35a. No code unblock remaining.

Merge left to you.

@github-actions

github-actionsBot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

CI triage

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

  • Production UI (2)needs 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 #9220 (cancelled).

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

…lity budget
Merge origin/main (ledger auto-resolved). Move dashboard payload types,
constants, and clinicalQueryModeOptions into clinical-dashboard-payloads.ts
and the cold-/ mode seed effect into use-home-mode-seed.ts so
ClinicalDashboard.tsx stays within the 4140-line no-growth budget (4124).
Update the route-ownership contract test to pin the extracted hook.
@BigSimmo
BigSimmo disabled auto-merge August 8, 2026 16:56
@BigSimmo
BigSimmo requested a balanced review from CopilotAugust 8, 2026 17:00
…search state
Co-authored-by: BigSimmo <87357024+BigSimmo@users.noreply.github.com>
auto-merge was automatically disabled August 8, 2026 17:32

Head branch was pushed to by a user without write access

@BigSimmo
BigSimmo enabled auto-merge (squash) August 8, 2026 17:35
After /?mode=differentials&q=…&run=1 redirects to /differentials, assert the
results surface (not the home template), the mode chrome, and the submitted
query heading. Matches the adjacent submitted-route smoke test.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 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/design-system/adoption-manifest.json`:
- Line 1959: Update the adoption manifest entry for the medications route so it
no longer lists ClinicalDashboard, since the route is standalone and renders
MedicationsHomeClient. If the manifest requires a sanctioned pattern, replace it
with the actual pattern mounted by that route.
In `@docs/site-map.md`:
- Line 28: Update the route descriptions in the site map: describe /medications
as the Medication mode home rather than a blanket redirect, set the Documents
mode-page index route to /documents, and describe /?mode=documents as the shared
root home with Documents preselected. Apply these corrections to the entries
around lines 28, 50–76, and 1105 while preserving the rest of the route
documentation.
In `@src/app/`(search-app)/page.tsx:
- Around line 39-43: Preserve the complete parsed search navigation context when
rewriting mode URLs: in src/app/(search-app)/page.tsx#L39-L43, pass it to
appModeHomeHref; in src/app/(search-app)/medications/page.tsx#L34-L39, retain
focus and all supported navigation parameters; and in
src/components/clinical-dashboard/use-home-mode-seed.ts#L38-L42, retain focus
and the same navigation context when adding the remembered mode.
🪄 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: c1aa39bc-604a-41e3-8a12-d2beb2ff9ed5

📥 Commits

Reviewing files that changed from the base of the PR and between 3e1357f and 6d1099b.

📒 Files selected for processing (41)
  • docs/branch-review-ledger.md
  • docs/codebase-index.md
  • docs/design-system/ADOPTION.md
  • docs/design-system/adoption-contract.json
  • docs/design-system/adoption-manifest.json
  • docs/site-map.md
  • src/app/(search-app)/documents/documents-home-client.tsx
  • src/app/(search-app)/documents/page.tsx
  • src/app/(search-app)/medications/medications-home-client.tsx
  • src/app/(search-app)/medications/page.tsx
  • src/app/(search-app)/medications/route.ts
  • src/app/(search-app)/page.tsx
  • src/app/manifest.ts
  • src/components/ClinicalDashboard.tsx
  • src/components/clinical-dashboard/ClinicalSidebar.tsx
  • src/components/clinical-dashboard/clinical-dashboard-payloads.ts
  • src/components/clinical-dashboard/global-search-shell.tsx
  • src/components/clinical-dashboard/master-search-header.tsx
  • src/components/clinical-dashboard/medication-record-page.tsx
  • src/components/clinical-dashboard/use-app-preferences.ts
  • src/components/clinical-dashboard/use-home-mode-seed.ts
  • src/components/clinical-dashboard/use-last-app-mode.ts
  • src/lib/app-modes.ts
  • src/lib/legacy-home-redirect.ts
  • src/lib/search-route-ownership.ts
  • src/lib/search-shell-props.ts
  • src/lib/tools-catalog.ts
  • tests/app-modes.test.ts
  • tests/audit-navigation-auth-regressions.test.ts
  • tests/design-system-adoption.test.ts
  • tests/favourites-auth-gate.dom.test.tsx
  • tests/mode-menu-prefetch.dom.test.tsx
  • tests/pwa-manifest.test.ts
  • tests/search-pins-menu.dom.test.tsx
  • tests/search-results-band-adoption.test.ts
  • tests/search-route-ownership.test.ts
  • tests/site-map.test.ts
  • tests/ui-route-coverage.spec.ts
  • tests/ui-smoke.spec.ts
  • tests/ui-stress.spec.ts
  • tests/ui-tools.spec.ts
💤 Files with no reviewable changes (1)
  • src/app/(search-app)/medications/route.ts

Comment threaddocs/design-system/adoption-manifest.json
Comment threaddocs/site-map.md Outdated
Comment threadsrc/app/(search-app)/page.tsx Outdated
Resolve ui-smoke deferred-requests conflict by retaining the Documents
home click-away dismiss (shared-home PR) and main's closed-suggestions
assertion, without switching modes on /documents.
@cursor
cursorBot disabled auto-merge August 8, 2026 17:38
@cursor
cursorBot enabled auto-merge (squash) August 8, 2026 17:39
@BigSimmo

Copy link
Copy Markdown
OwnerAuthor

@cursoragent Unblock the current open PR. Confirm the PR number and GitHub head first from context. If more than one open PR could apply, stop and say which one you would use and why.

Fetch and start from the remote tip that matches that GitHub head. If the named branch ref is missing or stale, use the PR head ref. Preserve unrelated local WIP; do not discard dirty work; do not treat a local-ahead commit as the reviewed tip. Do not merge the PR, force-push, rebase, or arm auto-merge. No provider-backed gates without approval. If you cannot push or resolve threads, diagnose and comment only; if inline replies fail, resolve when possible and put blocker dispositions in the summary comment. If auto-merge is already armed, push only for a real blocker and avoid cancelling in-flight required CI unless the push clears that blocker.

If the PR is already merged or closed: confirm outcome, post one summary, and stop.

Primary job: clear mergeability and required-CI blockers on this tip. Do a full product review only if needed to explain or fix a blocker. Stay light otherwise—no broad verification suites or Playwright unless needed to prove one concrete unblock fix.

Snapshot the GitHub head: tip, behind/ahead, mergeable state, merge-tree versus origin/main (real conflict versus behind-but-clean), required checks on that tip including Production UI when selected, and unresolved threads that block merge or required CI. Missing checks while dirty are not green. Tip moved → re-snapshot.

Ledger-lookup against that GitHub head under an unblock/fix scope for this PR. If already handled at this head for unblock work, merge-tree clean, required checks green, and no blocking threads: summarize, comment, stop.

Unblock once: real conflict → merge origin/main with the smallest correct resolution (prefer main’s shared queues; keep this PR’s notes); behind-but-clean → one sync, late if required CI is in flight; clean → leave. skip-branch-sync and similar labels do not block a manual sync needed to clear a real blocker. No sync thrash. After any sync or push, re-snapshot tip, merge-tree, and required checks before declaring done. Dedupe the ledger if a merge touched it.

Fix only what blocks required checks or mergeability on this tip. Ignore advisory red unless it reveals a real required failure. Prefer the smallest safe fix; if a bot/autofix commit caused the break, prefer revert. Prove with the smallest targeted check only. Format and commit before push.

Push only blocker-fix commits. Append ledger for the final GitHub head under the unblock scope. Never push a ledger-only tip.

One PR comment: tip, sync/merge-tree, what blocked and what you fixed or dispositioned, required CI status, residual risks; merge left to me.

Stop when merge-tree is clean on the current GitHub tip, no blocking threads remain for merge/required CI, and required checks are green or clearly in progress.

@cursor

cursorBot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

PR #1744 tip e53d105c is already unblocked for mergeability — nothing further to push.

Tipe53d105c (matches remote)
vs main0 behind / 24 ahead, merge-tree clean
GitHubMERGEABLE · auto-merge armed · BLOCKED only until required CI finishes
Threads0 unresolved

No sync or code fix this pass — a push would only cancel in-flight CI. Required CI run 31270228126 is pending on this tip. Summary comment posted; ledger left local/unpushed.

Merge left to you when CI goes green.

Open in WebOpen in Cursor

cursoragentand others added 4 commits August 8, 2026 17:40
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
… docs
Include run=1 when Medication search updates the URL so refresh keeps results
instead of the shared home. Preserve queryMode/scope/focus on submitted
root and /medications redirects. Point Documents home and Medication site-map
metadata at the real mode homes and clear the false ClinicalDashboard
adoption hit on /medications.
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
@cursor

cursorBot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

PR #1744 review + conflict summary

Tip:e53d105c125d026a1ee4dc2aef160489ea8b73a3
Base:origin/main0 behind, git merge-treeclean (MERGEABLE). Merge left to you.

Previous CI failure (answered)

On tip 9ec80338, required CI failed in Production UI (2):

  • Test: dashboard differentials selection stays on the shared home; submitted links open Differentials
  • Failure: waited for differentials-home + heading "Differentials", but a submitted q+run=1 lands on search results (differentials-search-results), so owner count stayed 0
  • Fixed earlier in 6d1099b4 (assert search-results owner + query ribbon)

Merge conflicts

Real conflict vs #1711 in tests/ui-smoke.spec.ts (Documents defer-requests blur vs listbox guard) was already resolved on the tip before this pass; merge-tree remains clean.

Review findings fixed this pass

SevIssueFix
P2Medication submit wrote /?mode=prescribing&q=…withoutrun=1, so refresh returned to shared homesetMedicationSearchQuery now passes run: true
P2Submitted / and /medications redirects dropped queryMode/scope/focusPass readSearchNavigationContext through
P2Sitemap/adoption still described /medications as a redirect; Documents home constant was bare /?mode=documentsGenerator + DOCUMENTS_MODE_HOME_ROUTE=/documents + regen

CodeRabbit threads for those docs/context items: resolved.

Local gates

  • Focused vitest (app-modes / audit / site-map): 39 passed
  • tsc: clean
  • sitemap:check + design-system adoption: pass
  • Not run (no approval): verify:release, live evals, full Playwright

Residual

  • Ledger row left local/unpushed (avoid ledger-only tip).
  • Intentional product risk: bare /?mode=X bookmarks now mean shared home with mode preselected.

Merge left to you when required CI finishes.

@cursor

cursorBot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

PR #1744 unblock summary

Tip:e53d105c125d026a1ee4dc2aef160489ea8b73a3 (matches remote)
Base:origin/main @ e8adde1b0 behind / 24 ahead
Merge-tree: clean · GitHub MERGEABLE (BLOCKED only while required CI settles) · auto-merge already armed

What blocked

Nothing on this tip for mergeability or review threads. Prior dirty/conflict signals were behind-but-clean and are already cleared on this head.

What I did this pass

  • Confirmed tip/remote match; merge-tree clean vs origin/main.
  • No push — would only cancel in-flight required CI; no remaining mergeability/code blocker.
  • Unresolved review threads: 0 (7 resolved).

Required CI

  • PR mergeability / PR policy / Gitleaks / Semgrep / GitGuardian: pass
  • Main CI run 31270228126: pending on this tip (jobs not yet started / queued)
  • Advisory ignored

Residual

Wait for required CI (incl. Production UI when selected) to finish on e53d105c. No code unblock remaining. Ledger row left local/unpushed (no ledger-only tip).

Merge left to you.

@BigSimmo
BigSimmo disabled auto-merge August 8, 2026 17:54
@BigSimmo
BigSimmo enabled auto-merge August 8, 2026 17:54
@BigSimmo
BigSimmo merged commit a503c22 into mainAug 8, 2026
122 checks passed
@BigSimmo
BigSimmo deleted the claude/mode-routing-search-pages-jabe17 branch August 8, 2026 18:05
cursorBot pushed a commit that referenced this pull request Aug 8, 2026
…mode (#1760)
* fix(navigation): keep focus and search context when seeding the home mode
The cold-`/` seed rewrote the URL with `appModeSelectionHref(lastAppMode)` and
nothing else, so a visit carrying `focus=1` or scope/queryMode context lost it.
Seeding only runs when the URL names no mode or query, but those params can
still be present, and dropping them silently discarded a requested composer
focus and any scoped-search context.
Carry the parsed navigation context through, reusing readSearchNavigationContext
the same way the root and /medications routes already do.
Raised by CodeRabbit on PR #1744. The two sibling sites it flagged
(`(search-app)/page.tsx`, `medications/page.tsx`) already preserve the context;
this was the only one left.
The contract test pinned the old single-line replaceState call, so it now pins
the behaviour instead: replaceState rather than push, plus the context being
carried. Its fixed 1800-character slice window is gone too — the window had
already stopped covering the effect once the doc comment grew, which is exactly
how a source-contract test goes quietly blind.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wa7MTVhAJMztFMMhzJf2J4
* issues: record the web-container Node floor (#285), the pr-handoff-stop false regression (#286), and a third #255 reproduction
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wa7MTVhAJMztFMMhzJf2J4
* ledger: record the PR #1760 handoff for the home-mode seed follow-up
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wa7MTVhAJMztFMMhzJf2J4
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
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.

5 participants

@BigSimmo@claude@cursoragent