Skip to content

Complete Specifiers/Formulation separation (review of #672)#674

Merged
BigSimmo merged 6 commits into
mainfrom
claude/pr-672-specifiers-formulation-3n123f
Jul 14, 2026
Merged

Complete Specifiers/Formulation separation (review of #672)#674
BigSimmo merged 6 commits into
mainfrom
claude/pr-672-specifiers-formulation-3n123f

Conversation

@BigSimmo

@BigSimmo BigSimmo commented Jul 14, 2026

Copy link
Copy Markdown
Owner

Summary

Reviews and completes PR #672's Specifiers/Formulation separation so both are two fully separate, working modes. This branch contains the separation work plus the fixes below:

  • Restores the standalone Specifiers workspace (/specifiers, /specifiers/[slug], /specifiers/builder, /specifiers/compare, /specifiers/map), each route connected to its own @/components/specifiers/* component and the specifiers universal-search domain. The legacy /specifiers/[[...path]] redirect into Formulation is gone.
  • Keeps Formulation on its own parallel routes, mode, and formulation search domain — no cross-wiring between the two.
  • Fixes the CI blocker: formatted specifier-builder-page.tsx, specifier-map-page.tsx, and specifiers-home-page.tsx so format:check (Static PR checks) passes.
  • Repairs the Specifiers mode composer (previously unresolved P2): added a specifiers entry to searchCommandSurfaceByMode so the composer renders smart examples, typeahead, and cross-mode chips instead of falling back to raw children.
  • Surfaces per-mode quick actions: wired the existing Specifiers and Formulation mode action sets into the universal command surface so their quick actions render in each mode's composer (navigation handlers already existed and route to each mode's own pages).
  • Added targeted unit coverage for the Specifiers command-surface config.

Verification

  • npm run typecheck
  • npm run lint
  • npm run format:check
  • npm run sitemap:check
  • npm run test — 2411 passed, 3 skipped
  • npm run build — compiles; both /specifiers/* and /formulation/* route families emit as separate routes
  • npm run verify:ui — not run in this environment (Chromium UI gate); CI "UI regression" covers it

Clinical Governance Preflight

Change is limited to mode routing and search-composer wiring — no answer generation, retrieval/ranking logic, source rendering, ingestion, or privacy surface was modified.

  • Source-backed claims still require linked source verification before clinical use (unchanged)
  • No patient-identifiable document workflow was introduced or expanded
  • Supabase target remains Clinical KB Database (sjrfecxgysukkwxsowpy) (unchanged)
  • Service-role keys and private document access remain server-only (unchanged)
  • Demo/synthetic content remains clearly separated from real clinical sources (unchanged)
  • Source metadata, review status, and outdated/unknown-source behavior remain conservative (unchanged)
  • Deployment classification/TGA SaMD impact checked — no clinical decision-support logic changed; specifier content is reference wording guidance

Notes

  • Supersedes the manual review of PR Fix Specifiers and Formulation separation #672 on branch codex/formulation-specifier-separation-current. The four CodeRabbit/Codex review findings (route metadata, builder deep-link diagnosis inference, map initialSlug resync, "clinical fit" → "text relevance" copy) were already applied in 7a77dde; the outstanding one was the missing Specifiers command-surface config, now fixed here.

🤖 Generated with Claude Code

https://claude.ai/code/session_01C2VkQ6g1tYpMXCfpzKKkav


Generated by Claude Code

Summary by CodeRabbit

  • New Features

    • Added a dedicated Specifiers experience with search, builder, comparison, map, and detail pages.
    • Added clinical specifier guidance, filtering, compatibility checks, and example wording tools.
    • Added distinct universal-search results and destinations for Specifiers and Formulation.
  • Bug Fixes

    • Corrected Specifiers routing, labels, and search ownership to prevent confusion with Formulation.
    • Preserved deep links and enforced incompatible specifier constraints.
  • Documentation

    • Updated sitemap and review records to include the new Specifiers routes.

BigSimmo and others added 5 commits July 15, 2026 00:12
Fixed 8 file(s) based on 3 unresolved review comments.

Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
…rface

- format specifier builder/map/home components so `format:check` (Static PR
  checks) passes again
- add a `specifiers` search-command-surface config so the Specifiers mode
  composer renders smart examples, typeahead, and cross-mode chips instead of
  falling back to raw children
- wire the existing Specifiers and Formulation mode action sets into the
  universal command surface so their quick actions render in each mode's
  composer
- cover the Specifiers command-surface config with a targeted unit test

Keeps Specifiers and Formulation as two fully separate modes, each connected
to its own routes, search domain, and quick actions.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C2VkQ6g1tYpMXCfpzKKkav
@supabase

supabase Bot commented Jul 14, 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

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This change introduces first-class Specifiers routes and UI, adds a psychiatric specifier catalogue and search tools, separates Specifiers from Formulation universal-search domains, updates navigation and sitemap ownership, and adds unit and browser coverage.

Changes

Specifier and Formulation separation

Layer / File(s) Summary
Specifier data and search contracts
src/lib/specifiers.ts, src/lib/universal-search-domains.ts, src/lib/universal-search-mode-context.ts
Adds specifier records, search, applicability, normalization, related-record utilities, and distinct Specifiers/Formulation domain mappings.
Specifier routes and search home
src/app/specifiers/..., src/components/specifiers/specifier-ui.tsx, src/components/specifiers/specifiers-home-page.tsx
Adds search, detail, builder, compare, and map route entry points with shared navigation, metadata, query handling, and search-results rendering.
Builder, comparison, map, and detail tools
src/components/specifiers/specifier-builder-page.tsx, src/components/specifiers/specifier-compare-page.tsx, src/components/specifiers/specifier-map-page.tsx, src/components/specifiers/specifier-record-page.tsx
Adds interactive diagnosis/specifier selection, comparison, mapping, detail guidance, related links, and generated wording views.
Universal search and mode routing
src/lib/universal-search.ts, src/lib/search-command-surface.ts, src/components/clinical-dashboard/...
Routes Specifiers and Formulation searches through separate adapters, labels their domains correctly, and sends mode actions to dedicated destinations.
Validation and route inventory
tests/*, playwright.config.ts, scripts/generate-site-map.ts, docs/site-map.md, docs/branch-review-ledger.md
Adds catalogue, routing, universal-search, UI, accessibility, sitemap, and production test coverage, and documents the new route family.

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

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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 name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: separating Specifiers and Formulation into independent modes.
Description check ✅ Passed The description follows the template sections and includes summary, verification, governance preflight, and notes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/pr-672-specifiers-formulation-3n123f

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

@github-actions

Copy link
Copy Markdown

CI triage

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

  • UI regressionpossible known flake: UI/Playwright job; check tests/flake-ledger.json (tests/ui-smoke.spec.ts, tests/ui-smoke.spec.ts, tests/ui-tools.spec.ts, tests/ui-tools.spec.ts) and re-run before bisecting.
  • PR requiredpossible known flake: UI/Playwright job; check tests/flake-ledger.json (tests/ui-smoke.spec.ts, tests/ui-smoke.spec.ts, tests/ui-tools.spec.ts, tests/ui-tools.spec.ts) and re-run before bisecting.

Heuristic only — a main-side or flake label is a starting point, not a verdict.

@BigSimmo
BigSimmo marked this pull request as ready for review July 14, 2026 17:53
The UI regression job was red on three stale/incorrect specifier assertions:

- ui-smoke: the legacy test asserted `?mode=specifiers` redirects to
  `/formulation`. Specifiers is now its own mode, so it redirects to
  `/specifiers`; update the expectation to the standalone route and heading.
- ui-specifiers "text-relevance" test used straight quotes in the results
  heading, but the page renders curly quotes (&ldquo;/&rdquo;); match them.
- ui-specifiers builder test expected the pre-fix behaviour where a mixed
  deep link fell back to hard-coded MDD and disabled rapid cycling. The merged
  diagnosis-inference fix now infers a compatible bipolar base instead, so the
  deep link is scoped to the psychotic-features specifier that legitimately
  keeps the recurrent-MDD base and blocks the bipolar-only specifier.

Verified locally against the running app: all 6 ui-specifiers tests and both
mode-param redirect smoke tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C2VkQ6g1tYpMXCfpzKKkav

@chatgpt-codex-connector chatgpt-codex-connector Bot 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: 3ed63d4747

ℹ️ 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 thread tests/ui-specifiers.spec.ts Outdated
@BigSimmo

Copy link
Copy Markdown
Owner Author

@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. 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. After fixing or dispositioning a thread, reply in that thread with as the first line, followed by a concise summary; that marker authorizes the workflow to close that exact thread. If human input or new authorization is required, do not use the marker and leave the thread open with the blocker. 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) July 14, 2026 17:59
@chatgpt-codex-connector

Copy link
Copy Markdown

Summary

  • Updated the Specifiers Playwright regression test heading locator to use a quote-agnostic regex, so it matches rendered curly quotes and ASCII quotes around racing thoughts. tests/ui-specifiers.spec.tsL153-L158
  • Committed the change on the current branch with commit 8f974da (Fix specifiers heading quote matcher).
  • Created a PR via the make_pr tool with title: Fix specifiers UI heading quote matcher.

Testing

  • npx prettier --check tests/ui-specifiers.spec.ts
  • node - <<'NODE' const pattern = /Matches for [“\"]racing thoughts[”\"]/; if (!pattern.test('Matches for “racing thoughts”')) throw new Error('curly mismatch'); if (!pattern.test('Matches for "racing thoughts"')) throw new Error('ascii mismatch'); console.log('quote-agnostic heading regex matches curly and ASCII quotes'); NODE
  • ⚠️ npm run lint -- tests/ui-specifiers.spec.ts (warning due to environment limitation: this checkout has no node_modules/eslint/bin/eslint.js and node resolved to v20.20.2 instead of the repo-required Node 24.x)

View task →

@BigSimmo
BigSimmo merged commit 92e371c into main Jul 14, 2026
24 checks passed

@coderabbitai coderabbitai Bot 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: 1

🧹 Nitpick comments (1)
src/lib/specifiers.ts (1)

632-646: 🎯 Functional Correctness | 🔵 Trivial

Search index omits fit/notFit/checks/treatmentLens/wording text.

recordSearchText only indexes name/shortName/familyLabel/appliesTo/summary/clinicalSignal/decisionQuestion/patientLanguage/keywords. Clinically meaningful phrases that live only in fit, notFit, checks, treatmentLens, or wording (e.g. distinguishing exclusion language) won't be found unless echoed in keywords, reducing recall for a clinical search tool.

♻️ Broaden the search haystack
 function recordSearchText(record: SpecifierRecord) {
   return normalizeSearchText(
     [
       record.name,
       record.shortName,
       record.familyLabel,
       ...record.appliesTo,
       record.summary,
       record.clinicalSignal,
       record.decisionQuestion,
       ...record.patientLanguage,
       ...record.keywords,
+      ...record.fit,
+      ...record.notFit,
+      ...record.checks,
+      record.treatmentLens,
+      record.wording,
     ].join(" "),
   );
 }

As per coding guidelines, P2-level observations for this file are consolidated here rather than posted as multiple inline notes ("P2 context belongs in one summary").

🤖 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/lib/specifiers.ts` around lines 632 - 646, Expand recordSearchText to
include the clinically meaningful text from each record’s fit, notFit, checks,
treatmentLens, and wording fields in the normalized search haystack, alongside
the existing fields. Preserve the current normalization and joining behavior so
phrases present only in those fields become searchable.

Source: Coding guidelines

🤖 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/components/specifiers/specifier-builder-page.tsx`:
- Around line 39-42: Update wordingSegment and the diagnosis composition flow so
severity is derived and emitted only once, preventing duplicate or conflicting
text when with-psychotic-features is combined with compatible severity or
remission records. Preserve the existing wording for non-conflicting records,
add targeted tests covering these combinations, then run the relevant domain
check and npm run check:production-readiness.

---

Nitpick comments:
In `@src/lib/specifiers.ts`:
- Around line 632-646: Expand recordSearchText to include the clinically
meaningful text from each record’s fit, notFit, checks, treatmentLens, and
wording fields in the normalized search haystack, alongside the existing fields.
Preserve the current normalization and joining behavior so phrases present only
in those fields become searchable.
🪄 Autofix (Beta)

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 Plus

Run ID: e690ac33-121c-4ffc-b292-eb08149a8dda

📥 Commits

Reviewing files that changed from the base of the PR and between 430f27f and 059398c.

📒 Files selected for processing (34)
  • docs/branch-review-ledger.md
  • docs/site-map.md
  • playwright.config.ts
  • scripts/generate-site-map.ts
  • src/app/specifiers/[[...path]]/page.tsx
  • src/app/specifiers/[slug]/page.tsx
  • src/app/specifiers/builder/page.tsx
  • src/app/specifiers/compare/page.tsx
  • src/app/specifiers/layout.tsx
  • src/app/specifiers/map/page.tsx
  • src/app/specifiers/page.tsx
  • src/components/clinical-dashboard/global-search-shell.tsx
  • src/components/clinical-dashboard/master-search-header.tsx
  • src/components/clinical-dashboard/mode-action-popup.tsx
  • src/components/clinical-dashboard/universal-search-command-surface.tsx
  • src/components/specifiers/specifier-builder-page.tsx
  • src/components/specifiers/specifier-compare-page.tsx
  • src/components/specifiers/specifier-map-page.tsx
  • src/components/specifiers/specifier-record-page.tsx
  • src/components/specifiers/specifier-ui.tsx
  • src/components/specifiers/specifiers-home-page.tsx
  • src/lib/app-mode-icons.ts
  • src/lib/search-command-surface.ts
  • src/lib/specifiers.ts
  • src/lib/universal-search-domains.ts
  • src/lib/universal-search-mode-context.ts
  • src/lib/universal-search.ts
  • tests/app-modes.test.ts
  • tests/search-command-surface.test.ts
  • tests/specifiers.test.ts
  • tests/ui-formulation.spec.ts
  • tests/ui-smoke.spec.ts
  • tests/ui-specifiers.spec.ts
  • tests/universal-search.test.ts
💤 Files with no reviewable changes (1)
  • src/app/specifiers/[[...path]]/page.tsx

Comment on lines +39 to +42
function wordingSegment(record: SpecifierRecord) {
if (record.slug === "mild-severity") return "mild";
if (record.slug === "with-psychotic-features") return "severe with psychotic features";
return record.name.charAt(0).toLowerCase() + record.name.slice(1);

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.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Compose severity only once in the generated diagnosis.

Selecting with-psychotic-features with a compatible severity/remission record can produce wording such as “severe with psychotic features, severe.” Normalization only excludes mild-severity; it does not prevent duplicate or conflicting severity language. Derive severity once and add targeted coverage for these combinations.

As per coding guidelines, “When behavior changes, add or update the smallest relevant targeted test” and run the relevant domain check plus npm run check:production-readiness.

🤖 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/specifiers/specifier-builder-page.tsx` around lines 39 - 42,
Update wordingSegment and the diagnosis composition flow so severity is derived
and emitted only once, preventing duplicate or conflicting text when
with-psychotic-features is combined with compatible severity or remission
records. Preserve the existing wording for non-conflicting records, add targeted
tests covering these combinations, then run the relevant domain check and npm
run check:production-readiness.

Source: Coding guidelines

Sign up for free to 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.

3 participants