Stage Mental Health Act section guidance for form pages - #2273
Conversation
…very form Form 1A was the only form whose Priority-facts cards opened detail sheets and whose fourth card showed tappable Act sections. That was never a design difference: all 54 forms render through one component, and 1A was simply the only form with a curated `priorityFacts` block in data/forms-catalog.json, from a single-form pilot that was never rolled out. Two mechanisms kept it that way. `form-detail-page.tsx` gated tap-for-detail on that curated block existing, even though `priorityFactBody` already synthesises a sheet body for every form. That gate is replaced with a content test: a card becomes interactive when its body says more than its title. On a boilerplate form the clock card's title is its whole body, so it stays inert rather than promising detail it cannot deliver; the authority card composes maker + authorises + does-not-authorise on every form, so it now works everywhere. The Act-sections card needed section summaries that did not exist. Every archived form already records its citations in `sourceFacts.sectionCue`, which resolve to 75 distinct sections. Those summaries now live once, keyed by section, in data/mha-2014-sections.json — several sections are cited by three or four forms, and a summary is a property of the Act, not of a form. `actSectionsForCue` yields sections only when every section a form cites has been clinically reviewed, so summaries can land in reviewed batches without any form ever showing a half-populated authority card. All 75 start pending, so this change alters no clinical content: 1A keeps its curated override and every other form keeps its Source status card. scripts/build-mha-act-sections.mjs owns the data. `--refresh` fetches the current consolidated Mental Health Act 2014 (WA) and extracts verbatim text with per-section hashes; `--draft` seeds pending stubs and emits the review sheet a clinician signs off from; `--check` is the offline gate. A reviewed summary is pinned by hash to the exact statutory text its reviewer read, so amended law fails the gate instead of silently shipping a stale clinical claim. `--refresh` is the repo's only network-fetching build mode and is manual; CI runs `--check`. Also visible on all 54 forms: the clock card no longer prints "Not listed" when a form has no indexed clock cue — 34 forms have none, and that string read as a fact about the form rather than an absence of one. Act-section chips are capped at six behind a wired overflow control, since Form 5A cites 11 and would break the 2x2 grid. The card title "MHA 2014 referral pathway" was 1A-specific and is now "Authority under the Act". One shared label map replaces the drift where the grid said "Criteria / threshold" and the sheet said "Criteria". Verification: verify:cheap green (698 test files, 7808 tests passed); ui-forms-section-nav 6 passed against a production build; Form 1A confirmed unchanged and Form 4C confirmed to lose "Not listed" and gain a working authority sheet at phone width. check:production-readiness fails only on absent Supabase/OpenAI credentials in this offline container. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vpz4n8tbrFYr85FD4wGPpi
Stage 1 shipped the mechanism with every section pending, so the Act sections card was still Form 1A's alone. This writes the 75 summaries and turns it on: 47 of the 54 forms now show tappable Act sections. The remaining 7 have no archive row and therefore no section cue, so they keep Source status — that is the designed end state, not a gap. Each summary is written from the verbatim statutory text this repo extracted from the current consolidated Mental Health Act 2014 (WA), version 02-b0-01 as at 25 September 2025, and is pinned to it by `sourceTextSha256`. A third review status carries the distinction that matters. `pending` has no summary and does not render. `drafted` — where all 75 sit — renders, with "Drafted from the Act text and awaiting clinical review" on the section sheet. `reviewed` additionally names a clinician and a date, and drops that note. Recording these as `reviewed` would have meant writing a sign-off nobody performed, and the status is the only thing telling a reader whether a clinician has checked the summary. Promotion to `reviewed` is a data-only edit per batch; the gate already requires `reviewedBy` and `reviewedAt` for it. `--check` now validates drafted entries as strictly as reviewed ones for text provenance — both must carry a summary and a hash matching the extracted text — and only requires reviewer identity for `reviewed`. A pending entry carrying a summary is rejected outright. The extractor also decodes the non-breaking hyphen the Act uses in compounds, which had been surviving into headings such as "Order to attend if non-compliance continues". Verification: verify:cheap green (698 test files, 7812 tests passed, no unhandled errors); ui-forms-section-nav 6 passed against a production build. Confirmed at phone width that Form 4C shows sections 66 and 91 opening real summaries with the awaiting-review note, that Form 5A's 11 citations render as 6 chips plus a +5 overflow without breaking the 2x2 grid, and that Form 1A still renders from its own curated override. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vpz4n8tbrFYr85FD4wGPpi
|
This pull request has been ignored for the connected project Preview Branches by Supabase. |
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 7 minutes Limit details: You’ve used the included review currently available. Your 90 included PR review attempts over the past 7 days set your current allowance at 1 review per hour. Your organization has reached its usage spending cap. Adjust your spending cap in the billing tab. How can I continue?Wait for the limit to reset, then comment An organization admin can change what happens after included review limits in Billing. How do review limits work?CodeRabbit enforces per-developer PR review limits within each organization. For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (23)
Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2ec0676799
ℹ️ 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".
… card Seven official forms had no Act sections because they have no row in data/forms-catalog.json at all, and so no `sourceFacts.sectionCue` for the resolver to read: 1A attachment, 4D, 4E, 7C, 10H, 12C attachment and 13. Nothing about them was unresolvable — the Act sections that govern them exist and in four cases the section heading matches the form title almost word for word. What was missing was any record of which sections those are. data/forms-act-section-cues.json supplies them, and `sectionCueForForm` falls back to it when a form has no catalogue cue. Unlike a catalogue cue this is an assertion the repo makes rather than one it inherited, so every entry must state a `basis` — the reason that section governs that form — and `--check` rejects an entry without one, or one that shadows a catalogue cue. The mappings: 1A attachment to ss 41 and 42 (referral information given in confidence), 4D to s 555 and 4E to s 557 (the interstate transfer order and the transfer approval order), 7C to s 110 (cancelling leave), 10H to s 238 (the psychiatrist review after 6 hours of restraint), 12C attachment to s 262 (the 24-hourly review of a communication restriction), and 13 to s 201 (the monthly ECT statistics report). Four of those sections were not previously extracted, so the Act source now holds 79 rather than 75, all drafted and hash-pinned like the rest. None is recorded as clinically reviewed. The gate earned its keep here: adding the cues before the sections existed failed `--check` with all four missing sections named, which is exactly the dead-chip case it was built to prevent. Verification: verify:cheap green (698 test files, 7813 tests passed); ui-forms-section-nav 6 passed against a production build; confirmed at phone width that Form 13 opens the s 201 ECT statistics duty and Form 4D the s 555 interstate transfer order, both with the awaiting-review note. All 54 forms now resolve an Act sections card and none falls back to Source status. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vpz4n8tbrFYr85FD4wGPpi
# Conflicts: # docs/scripts-index.md
…flag drafts on the card Addresses both P1 findings from the Codex review on PR #2273. Superseded summaries surviving in owner rows. `mergeRegistryRecordWithDefaults` spreads a stored owner `catalog_payload` over the baseline, so an owner seeded before an Act amendment or a summary correction kept reading the old legal summary indefinitely — bypassing the `sourceTextSha256` gate whose whole purpose is to force a rewrite when the statutory text changes. Reproduced by seeding Form 1B, overwriting its stored summaries, and watching the merge return them. `actSections` is derived and never owner-editable, so it is now forced from the current baseline, the same treatment `summaryCards` already gets for forms. Forcing at read rather than excluding at write is deliberate: it also repairs rows already seeded. `tests/forms.test.ts` pins it with that exact scenario. Drafted summaries reading as reviewed authority. The awaiting-review caveat appeared only after opening a section, so the card face presented unreviewed summaries as settled authority to anyone who never tapped one. The Act sections card now says "Tap a section — awaiting clinical review" while any rendered section is drafted, and reverts to "Tap a section for authority detail" once they are all reviewed. The review also proposed requiring `status === "reviewed"` to render at all, which would revert the rollout to Form 1A only. That is a product decision for the repository owner, who asked for the rollout knowing the summaries were unreviewed, so it is raised with them rather than actioned here. Nothing in the repo now claims sections become available only after clinical review. Verification: verify:cheap green (699 test files, 7821 tests passed). Also merged origin/main to clear the real conflict in docs/scripts-index.md, whose generated script counts had diverged; regenerated rather than hand-resolved. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vpz4n8tbrFYr85FD4wGPpi
…view-pr-2273 # Conflicts: # docs/scripts-index.md
…tructure-kaboq6' into codex/review-pr-2273
Summary
Verification
npm run verify:pr-localmain; CI remains the broad PR authority.npm run typechecknpm run test -- tests/mha-act-sections.test.ts tests/forms.test.ts --pool=threads— 25/25 passed.npm run check:mha-act-sections— passed: 79 cited sections, 0 reviewed, 79 drafted, 0 pending; Act 02-b0-01 as at 2025-09-25.npm run format— completed on the final tree.npm run verify:uinpm run verify:releasenpm run check:production-readiness— run; source/runtime checks passed, while provider configuration was environment-gated in the isolated worktree because Supabase/OpenAI secrets were intentionally absent.Risk and rollout
Clinical Governance Preflight
Clinical KB Database(sjrfecxgysukkwxsowpy)Notes
docs/evidence/mha-2014-section-summaries-review.md; it is not renderable shared clinical guidance.main; no history rewrite or force-push is used.