fix(therapy): restore the shared search command surface on the Therapy home - #2160
Conversation
…y home Therapy was the only one of the 15 app modes with no entry in `searchCommandSurfaceByMode`. `UniversalSearchCommandSurface` early-returns on a null config, so Therapy silently lost four shared affordances rather than one: the phone "Try this / Tap to search" ticket, the sm+ rotating hint line, the sm+ prompt-chip row, and the entire desktop command dropdown. This affected both the shared home `/` in Therapy mode and the standalone `/therapy-compass` home. Add the missing entry, with `remoteSearchEnabled: false` — Therapy reads the local generated catalogue, and `tests/search-command-surface.test.ts` already pinned that expectation (it passed only because the config was null). Every example was run through the real scorer against the 205-record catalogue so the ticket cannot advertise a query the catalogue has no answer for. Two adjacent deviations found while auditing, both low-risk: - `/therapy-compass` was the only standalone mode home not declaring `desktopSearchPlacement: "hero"`, leaving it on a different composer code path from its twelve peers in the portal-fallback case. - The standalone home hard-coded a magnifier as its identity medallion, so the same mode showed a different glyph depending on the door. It now derives from APP_MODE_ICON, matching nav, the mode picker and the shared home. Also correct two comments that cited "therapy-compass has no entry" as load-bearing rationale; the real reason that empty state offers no example is that no `onTryExample` handler is wired, which is unchanged here. Pin whole-set coverage so no future mode can silently lose the command surface. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W5HsA9TpWxAN6KbqFAx7GA
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (16)
Included review availability: 0 reviews are currently available. Your included PR review attempts over the past 7 days set your current allowance at 1 review per hour. 📝 WalkthroughWalkthroughThe PR adds Therapy Compass search configuration, hero placement, canonical icon usage, exhaustive search-surface tests, updated empty-state comments, and nine outstanding-issue inbox records from a mode-home audit. ChangesTherapy Compass search integration and audit records
Estimated code review effort: 3 (Moderate) | ~20 minutes Merge Risk: ⚪ Minimal · up to This PR restores Therapy’s shared search controls and aligns its standalone home presentation without changing retrieval, clinical content, permissions, or deployment behavior; no actionable merge-blocking risk remains after normal checks and review. Possibly related PRs
Suggested labels: 🚥 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. |
…uests Eight merge-safe inbox requests recording the deviations found while auditing the mode homes for the Therapy fix in this PR. The low-risk ones are already fixed in the preceding commit; these are the remainder, which need either an owner decision or their own visual-baseline work: - competing title systems (sharedHomePresentation vs hard-coded standalone) - three more homes overriding the canonical APP_MODE_ICON glyph - three standalone homes with no loading.tsx, invisible to the contract test - /tools phone dock suppressing the patient-identifiable-information warning - /favourites rendering two different homes for one mode - bespoke composer slots skipping the invariant-15 SSR height reservation - placeholder/heading/doc-index copy drift - suggestion data duplicated across three sources Each is an immutable request file; docs/outstanding-issues.md itself is untouched, so this cannot conflict with a concurrent ledger write. Run npm run issues:reconcile from a serialized ledger branch after this lands. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W5HsA9TpWxAN6KbqFAx7GA
…consistency-c14whb' into claude/therapy-lightweight-home-consistency-c14whb
CI triageCI failed on this PR. Automated classification of the 2 failed job(s):
Compared with main CI run #12433 (success). Classification is evidence routing, not permission to ignore a failure. Exact quarantined Playwright identities remain governed by the flake ledger. |
Lighthouse budget: diagnosis and action
This is caused by this PR, and the measurement is correct — but it is convergence, not a regression. The committed baseline for Therapy was recorded while Therapy was the one mode with no
Every mode that already carries the ticket sits at the same level — dsm's own baseline is Action: the baseline is refreshed through the sanctioned path, not hand-edited — Follow-up, deliberately not in this PR: the ~0.035 shift is real and pre-existing on every ticket-bearing mode home. The ticket renders inside the mode-home composer slot, whose reserve ( Generated by Claude Code |
The Lighthouse budget failure on this PR traced to a shared defect rather than the Therapy change alone: the mode-home composer slot reserves the composer's height but not the suggestion ticket and rotating hint that UniversalSearchCommandSurface renders above it, so the portal attaching post-hydration shifts content on every ticket-bearing mode home. Evidence from this PR's own run — mobile-dsm baseline CLS 0.0353, mobile-forms 0.088, mobile-root 0.016, while mobile-therapy-compass sat at 0.000 purely because Therapy rendered no ticket at all. Restoring it moved Therapy to 0.032, in line with its peers. Fixing the reserve would take every mode home toward zero, but it touches a shared token across all 15 homes and needs verify:phone-chrome plus Lighthouse and visual baseline re-adoption, so it is filed rather than bundled into a low-risk consistency fix. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W5HsA9TpWxAN6KbqFAx7GA
…herapy-lightweight-home-consistency-c14whb
Correction: the baseline refresh does not fix this, and I am not committing itMy previous comment said Therapy had converged on a stable ~0.032 CLS and that refreshing the baseline would resolve the failure. The refresh run disproves that, so the plan changes.
What is actually happening, measuredInstrumenting
Why the obvious fix is not in this PRRaising the phone token to 10.125rem would make the phone reserve exact, because the phone ticket is a fixed-height row. The Decision needed from the ownerThis PR restores the shared command surface on Therapy, which is correct and is what was asked for. It also moves Therapy onto the shared reserve defect, so Generated by Claude Code |
Baseline refresh cannot fix this — closing that route outFollowing up on my two earlier comments, with the result of the second refresh. The two code paths disagree systematically, twice each:
The graded gate reliably sees the shift; the refresh reliably does not. So a refreshed baseline would record Note this is also a gap in the refresh tooling itself, independent of this PR: a baseline generator that cannot reproduce what the grader measures cannot correct a stale cell on this route. The only real fixThe shift is a shared, pre-existing defect, measured locally at 390px:
I did not ship that change: it touches shared chrome on all 15 mode homes, and I could not run local browser verification to prove it. It is filed as an inbox request in this PR with the measurements. Owner decision: land this PR and accept a red Generated by Claude Code |
|
This looks like an expected side effect of the fix itself rather than a bug: before this PR, I didn't try to fix this by touching the ticket's rendering — reserving space or changing when it mounts on a hunch, without being able to run the actual Lighthouse measurement locally, risks trading a real regression for a guessed one. If the CLS bump is the accepted cost of restoring the feature, the mobile-therapy-compass baseline needs a deliberate refresh (the same kind of pass #2167 just did for the visual baselines) rather than a code change here — but that's a call for you to make, not something to wave through silently. Generated by Claude Code |
Summary
searchCommandSurfaceByMode(src/lib/search-command-surface.ts).UniversalSearchCommandSurfaceearly-returns on a null config, so Therapy silently lost four shared affordances rather than the one that was reported: the phone "Try this / Tap to search" ticket, thesm+"Smart search · Try …" rotating line, thesm+prompt-chip row, and the entire desktop command dropdown (recents, cross-mode chips, typeahead). This affected both the shared home/in Therapy mode and the standalone/therapy-compasshome. The new entry setsremoteSearchEnabled: falsebecause Therapy reads the local generated catalogue —tests/search-command-surface.test.tsalready pinned that expectation and passed only because the config was null. Every example was run through the real scorer (scoreTherapyCandidate) against the 205-record catalogue, so the ticket cannot advertise a query the catalogue has no answer for: trauma-focused CBT 188 matches, behavioural activation 30, insomnia 4./therapy-compass(src/lib/search-shell-props.ts). It was the only standalone mode home not settingdesktopSearchPlacement: "hero", which left it on a different composer code path from its twelve peers in the portal-fallback case. Gated onisStandaloneModeHome, so sub-routes are unaffected.src/components/therapy-compass/screens/home-screen.tsx). It hard-coded a magnifier as the mode's identity medallion, so the same mode showed a different glyph depending on which door the clinician came through — the shared home, nav and the mode picker all render the compass fromAPP_MODE_ICON. It is now derived from that record rather than chosen locally.search-results-header-band.tsxandsearch-results-header-band.dom.test.tsxthat cited "therapy-compass has no entry" as load-bearing rationale. The real reason that empty state offers no example is that noonTryExamplehandler is wired at the call site, which this PR does not change. Test coverage is widened to pin the whole mode set, so no future mode can silently lose the command surface the way Therapy did.Verification
npm run verify:pr-localFull unit suite inside that gate:
Test Files 680 passed (680)/Tests 7371 passed | 4 skipped (7375).UI verification not run: the container's Playwright browser revision is 1194 against the 1234 this install expects (the known installed-lock drift), so
verify:uicannot run here and browser proof is delegated to CI Production UI. Functional browser evidence was captured instead against the pre-installed Chromium and the running dev server, at 390px and 1280px:/therapy-compassat 390px — ticket visible, readingTRY THIS | trauma-focused CBT | Tap to search; tapping it fills the composer with exactly the suggested query./therapy-compassat 1280px — ticket correctly hidden (phone-only), rotating hint line and prompt-chip row visible, exactly one visible composer./?mode=therapy-compassat 390px — the surface in the original report; the ticket now renders in the same position as the Answer and Calculators homes.Hero glyph resolves to
lucide lucide-compass, no longer the magnifier.npm run eval:retrieval:quality— not applicable: no retrieval, ranking, selection, chunking, or scoring behaviour changed. This PR adds display-only suggestion strings.npm run check:production-readiness— not applicable: no clinical workflow, privacy, environment, Supabase, source-governance, or deployment behaviour changed.RAG impact: no retrieval behaviour change — this adds display-only example and suggestion strings to the command-surface catalogue and touches no ranking, retrieval, selection, or ordering code.
classifyPullRequestFilesreturnsragRanking: falsefor this diff.Risk and rollout
tests/__screenshots__/linux/therapy-compass-home.pngis captured at desktop 1280×900 clipped to#main-content, so it legitimately changes here (newsm+hint row, compass glyph) and needs re-adoption from the CI artifact vianpm run design-system:baselines:adopt— deliberately not regenerated locally, since the spec warns that laptop font hinting turns every later run red.git revertthe change commit. No migration, no data change, no generated asset regenerated.remoteSearchEnabled: false.Clinical Governance Preflight
Clinical KB Database(sjrfecxgysukkwxsowpy)The Therapy catalogue-wide review disclosure (
TherapyReviewNotice) and the per-record review badges are untouched; this PR adds no clinical claim and changes no source, review status, or document-access behaviour.Notes
A cross-mode consistency audit was run alongside this fix, as requested. The low-risk findings are fixed above; the remainder are reported for separate decisions. The most significant:
sharedHomePresentation(src/lib/ui-copy.ts) drives/; standalone homes hard-code their own. Its own doc comment claims each entry "mirrors the mode's own standalone home … so a clinician sees the same words whichever door they came through", which is not true today — Documents/Clinical Documents, Forms/Clinical Forms, Therapy/Therapy Compass, and five more. Product copy decision, so not auto-fixed.Users, forms usesFileText— identical to the Documents tile — and dictionary usesBookOpen.loading.tsx(/medications,/calculators,/dictionary) despite chrome invariant 18 requiringModeHomeRouteLoading;tests/mode-home-loading-contract.test.tslists only ten routes, so the contract test cannot catch it./toolson a phone is the only mode home with no visible "Do not enter patient-identifiable information." line — it is the sole route using the footer dock, and that path suppresses the notice. This matches the documented exception indocs/search-chrome-behaviour.md, but the docs do not record that the exception costs the governance copy. Worth a decision for a clinical product./favouritesand/?mode=favouritesrender visibly different homes for the same mode; Tools and Favourites are bespoke homes whose hand-rolled composer slots also skip the SSR height reservation that chrome invariant 15 exists to enforce.h2and noh1), suggestion data duplicated across three unrelated sources, anddocs/site-map.md's mode index covering 11 of 15 modes.🤖 Generated with Claude Code
https://claude.ai/code/session_01W5HsA9TpWxAN6KbqFAx7GA
Summary by CodeRabbit
New Features
Documentation
Tests