Skip to content

Specifiers builder: correct the one-of mapping, and show each option's review status - #2726

Open
BigSimmo wants to merge 4 commits into
mainfrom
claude/awesome-meitner-qrhlid
Open

Specifiers builder: correct the one-of mapping, and show each option's review status#2726
BigSimmo wants to merge 4 commits into
mainfrom
claude/awesome-meitner-qrhlid

Conversation

@BigSimmo

@BigSimmo BigSimmo commented Sep 7, 2026

Copy link
Copy Markdown
Owner

Summary

Three gaps left by the catalogue-driven builder in PR #2676. None is a computation bug — all three are about what the screen implies versus what the data supports.

  • The one-of mapping was wrong on four group labels, and could block a valid combination. singleSelectGroupLabels decides whether a specifier group renders as radios. The dataset carries no exclusivity field — a group is a label and a list — so that mapping is authored in this repo, and a wrong entry makes a combination unreachable with nothing on screen to say why. Four labels were wrong against the manual and are now multi-select: Classes (concurrent alcohol, cannabis and tobacco use disorders are ordinary and each is coded in its own right), Clusters (personality disorders across clusters are common and coded as both), Aetiology (the neurocognitive list pairs a certainty term with the aetiology itself, so probable Alzheimer's disease needs two picks, and delirium has to allow more than one contributor), and Attraction (limited to incest is a separate axis, applied alongside the attraction type). Type stays one-of, but specific phobia opts out of it, since the manual asks for every applicable phobia type to be coded — so builderGroupSelection now takes the disorder as well as the label.
  • More importantly, the mapping can no longer block anything. Every single-select group carries a control that reopens it as a checkbox list. A mapping error now costs a default rather than a combination the clinician cannot record, which is the failure direction this surface should have. The step copy states that one-of is the builder's default, not a verified manual rule.
  • Review status was invisible where it is acted on. The builder shows a catalogue option at the moment the clinician selects it and copies it into a note, but showed nothing about that item's review state. Of the 585 catalogued specifiers, 71 have verified sources and all 585 remain pending qualified clinician review. SpecifierReferencePage and the detail routes already render ReviewStatusBadge for exactly this reason, so the option rows now carry it too. Generated definitions stay withheld, unchanged.

The curated mood path is untouched throughout: it renders no badges (those are hand-authored records, not catalogue rows), keeps its own fit and exclusion rules, and its wording output is identical. Deep links and the copied phrase are unchanged.

Scope: one library file, one component file, one unit test, plus two issues-inbox request files.

Verification

  • npm run verify:pr-local

Verification not run: verify:pr-local selects heavy scope for an executable change (lint, typecheck, full test, build and the static suite), which duplicates the verdict CI reaches on this PR. The gates actually run locally, with their real output:

  • node ./node_modules/typescript/bin/tsc -p tsconfig.typecheck.json --noEmit — clean, no output.

  • eslint on all three changed source/test files --max-warnings 0 — clean.

  • npx prettier --check on every changed file, the two inbox requests included — All matched files use Prettier code style!

  • npx vitest related --run across the specifier suites — Test Files 3 passed (3) / Tests 25 passed (25). Four new cases pin the corrected mapping: that the four relaxed labels are multi-select, that specific phobia opts out of the label-wide Type rule while delusional disorder does not, that two substance classes can be held at once, and that relaxBuilderGroups reopens a named group without mutating the original or touching its siblings.

  • npm run check:design-drift-ratchet✓ inline style={{ }} attributes: 233 (ceiling 233). No new inline styles; this gate caught a regression on Specifiers builder: offer every catalogued base diagnosis, not five hardcoded mood presets #2676 so it is run deliberately.

  • node scripts/ledger-inbox.mjs checkLedger inbox check passed: 36 pending request(s), 1080 applied.

  • npm run verify:ui when UI, routing, styling, browser behavior, reduced-motion, or forced-colors behavior changed

Focused browser proof, not the full UI gate. npm run plan:browser selected level focused and attributed the changed component to its owning specs:

  28 passed (43.5s)

[browser-test-plan] PASSED at level "focused" — this is focused browser proof, not the full UI gate.

Every existing builder journey passed unchanged, including blocks incompatible specifiers and preserves severe psychotic-features wording (the curated mood path's own exclusion rules, a separate mechanism from the catalogue mapping), keeps the guided builder readable without horizontal overflow on phone, and the reduced-motion / forced-colors journeys. The full verify:ui suite is left to CI.

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

Risk and rollout

  • Risk: Low, confined to the Specifiers Build route's catalogue path. No wording output, deep-link resolution, or data access changes. The clinical direction is conservative in both changes: the mapping now permits combinations it used to block, and it surfaces an unreviewed state that was previously silent.
  • Rollback: Single-commit revert on each commit. No data, schema, or configuration changes.
  • Provider or production effects: None. No Supabase, OpenAI, or Railway surface is touched, and no provider-backed command was run.
  • RAG impact: none

Clinical Governance Preflight

  • Source-backed claims still require linked source verification before clinical use — each applied specifier still links to its /specifiers/<slug> record, and its review status is now visible before selection rather than only after opening that record.
  • No patient-identifiable document workflow was introduced or expanded without explicit governance approval
  • Supabase target remains Clinical KB Database (sjrfecxgysukkwxsowpy) — untouched.
  • Service-role keys and private document access remain server-only — untouched.
  • Demo/synthetic content remains clearly separated from real clinical sources
  • Source metadata, review status, and outdated/unknown-source behavior remain conservative — this PR strengthens that: 514 of 585 catalogue items read Review due at the point of selection, and generated definitions remain withheld exactly as on the reference pages.
  • Deployment classification/TGA SaMD impact was checked when clinical decision-support behavior changed — the builder remains a documentation aide-memoire producing a wording string, not decision support. Both changes move it further from implying decision support: it withdraws an implied manual rule and stops enforcing an unsourced one.

What this PR does not close, and where it is now recorded

Both remaining gaps need a qualified clinician rather than a code change, so both are queued as issues-inbox requests in this PR (merge-safe request files, not ledger rows; npm run issues:reconcile applies them after it lands):

  • P2 — the catalogue has no clinician sign-off. 585 items, 71 source-verified, none reviewed, dataset lastUpdated 2026-05-09. This PR makes that state honest at the point of selection, which is as far as code reaches.
  • P3 — the fifteen remaining one-of labels are authored here rather than reviewed. The reopen control bounds the consequence to a default the clinician can override rather than an unrecordable combination, so this is a confirmation pass and not a blocker.

🤖 Generated with Claude Code

https://claude.ai/code/session_011RJFStNCUPhDrEdAJe2r4i

Two gaps left by the catalogue-driven builder, both about what the screen
implies rather than what it computes.

The builder shows a catalogue option at the moment the clinician picks it and
copies it into a note, but showed nothing about that item's review state. Of the
585 catalogued specifiers, 71 have verified sources and every one is still
pending qualified clinician review. The detail and reference pages already carry
ReviewStatusBadge for exactly this reason, so carry it on the option rows too:
the state is visible when it is acted on, not only if the record is opened
afterwards. Generated definitions stay withheld, as before.

The single-select step also read as though its one-of rule came from the manual.
It does not. singleSelectGroupLabels is an aide-memoire grouping of the dataset's
50 group labels, so a group wrongly marked exclusive would quietly block a valid
combination. Say so in the step body rather than letting the radio imply
authority it does not have.

No behaviour change: the curated mood path is untouched and shows no badges,
selection rules and wording output are unchanged.

Verified: 20 unit tests pass with a new case pinning that every catalogue item
carries a renderable status and that the needs-review state is present. In the
running app, Autism Spectrum Disorder shows 3 badges on its 3 severity options
and 5 on its 5 co-occurring options, the curated MDD path shows none, and there
is no horizontal overflow at 320, 390, 768 or 1440.

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

coderabbitai Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Team

Run ID: 98427c80-4f98-405d-9215-0b4e2b00f4a4


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@cursor

cursor Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_b8cead28-f187-4a09-8a50-672d84d49ad2)

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 7, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-07T10:48:19.310004Z d1e882a PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@supabase

supabase Bot commented Sep 7, 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 ↗︎.

@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: d1e882a533

ℹ️ 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 src/components/specifiers/specifier-builder-page.tsx Outdated
Comment thread src/components/specifiers/specifier-builder-page.tsx Outdated
Both are correct and both are in the code this PR added.

1. The single-select step said the group "reads as a single graded axis". That is
   false for the nominal groups the rule also covers - Type (erotomanic,
   grandiose, jealous), Attraction, Classes and Current Episode are categorical,
   not degrees - so it handed clinicians a wrong rationale for the enforced
   one-of behaviour. Drop the claim about why and keep only what is true: that
   treating the group as one-of is an aide-memoire grouping, not a verified
   manual rule.

2. The option inputs set aria-label, which overrides the label's descendant text
   in the accessible-name computation, so the new badge was visible but silent.
   A screen-reader user picking a specifier heard the label alone and none of the
   review state, which is the whole point of showing it there. Wire
   aria-describedby to the badge so the status is announced with the control.

Verified: the computed description on each Autism Spectrum Disorder severity
radio now resolves to its badge text, checked in the running app - for example
"Level 2: Requiring substantial support" described by "Review due". The step copy
was confirmed against Delusional Disorder, whose Type group is nominal. A new DOM
test asserts every catalogue option's aria-describedby resolves to a renderable
status, so the silent-badge regression cannot return. 21 unit tests pass,
typecheck, lint and formatting clean, drift ratchet unchanged at 233/233.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011RJFStNCUPhDrEdAJe2r4i
The catalogue builder decides whether a specifier group is one-of from a
hand-authored list of group labels. The dataset carries no exclusivity
field, so that list is a judgement, and a wrong entry makes a valid
combination unreachable with nothing on screen to say why.

Four labels were wrong against the manual and are now multi-select:

  * Classes - concurrent alcohol, cannabis and tobacco use disorders are
    ordinary and each is coded in its own right.
  * Clusters - personality disorders across clusters are common and are
    coded as both.
  * Aetiology - the neurocognitive list pairs a certainty term with the
    aetiology itself, so probable Alzheimer's disease needs two picks,
    and delirium has to allow more than one contributor.
  * Attraction - limited to incest is a separate axis, applied alongside
    the attraction type rather than instead of it.

Type stays one-of, but specific phobia opts out of it: the manual asks
for every applicable phobia type to be coded. That needed a per-disorder
exception, so builderGroupSelection now takes the disorder too.

The wider fix is that the mapping is no longer able to block anything.
Every single-select group carries a control that reopens it as a
checkbox list, so a mapping error costs a default rather than a
combination the clinician cannot record. The step copy says so.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011RJFStNCUPhDrEdAJe2r4i
@BigSimmo BigSimmo changed the title Specifiers builder: show each catalogue option's source-review status Specifiers builder: correct the one-of mapping, and show each option's review status Sep 7, 2026
Neither can be closed by code, and both would otherwise be lost when the
session that found them ends.

  * P2 - the DSM-5-TR specifier catalogue has no clinician sign-off. 585
    items, 71 source-verified, none reviewed, dataset last updated
    2026-05-09. PR #2726 makes that state visible at the point of
    selection, which is as far as code reaches.
  * P3 - the fifteen remaining one-of group labels are authored here
    rather than reviewed. The reopen control added in #2726 bounds the
    consequence to a default rather than an unrecordable combination, so
    this is a confirmation pass, not a blocker.

Both are inbox requests, not ledger rows, so they stay merge-safe until
a reconcile runs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011RJFStNCUPhDrEdAJe2r4i
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.

2 participants