fix(ward-flow): remove the fabricated Mental Health Act figure - #2340
Conversation
`main` carried an invented statutory figure and rendered it to users as a legal deadline. No product owner supplied it; an assistant wrote it from its own recollection. It is the third invented statutory figure this prototype has produced and the second attributed to the Act in a doc comment. It was not dead code. It existed in four places and reached the screen: ward-model.ts FORM_1A_REFERRAL_EXPIRY_MINUTES = 7 * 24 * 60, doc-commented as "the Mental Health Act's seven-day outer limit" ward-model.ts the LegalForm doc comment asserting that a Form 1A "always carries a real statutory examination window, so it always carries a dueAt" — the same fabrication in prose ward-flow-reducer.ts RAISE_REFERRAL stamped it onto every newly raised 1A ward-movements.ts authored dueAt values on Form 1A movements ward-management-console.tsx rendered "· due <time>"; ward-derivations.ts turned it into a "Legal timing breached" inbox item with a countdown; priority-queue.tsx and shortlist-panel.tsx rendered breach state from it. A user raising a referral saw a legal deadline that does not exist. A test also required it: ward-model-phase3.test.ts asserted that every Form 1A carries a dueAt. The fabrication was pinned in place by a guard. The correction is the product owner's own, recorded verbatim in the code. Asked directly on 2026-08-23 his instruction was narrower than a corrected figure — "please can you leave the legal part and just start a clock once the patient arrives to ED. Keep it simple for now." So neither a Form 1A nor a Form 3B carries a dueAt. The forms record that they exist, never when they lapse. This change supplies no figure and corrects none; removal is the only direction it moves in. Also corrected: "— no statutory deadline" now reads "no deadline recorded". The first states what the Act requires, with the same unearned confidence as the countdown being deleted; the second states what the record holds, which is the only claim this prototype is entitled to make. The same unattributed claim is brought into line at five further sites. Adds tests/ward-legal-figure-guard.test.ts against a fourth recurrence. Two independent halves, both fail-closed by construction rather than by guessing what a bad name looks like: Part 1 walks the reducer through every event type, against a Form 1A and a Form 3B, asserting each event is genuinely accepted rather than refused, and that no legal form of ANY code carries a dueAt except an allowlist — 4A "Transport order" and 4C "Transfer between authorised hospitals" — each with a recorded reason for legitimately carrying an operational deadline. Part 2 requires recorded provenance for every exported declaration in ward-model.ts whose initializer contains a numeric literal, naming who supplied the figure and when. ED_ACCESS_TARGET_MINUTES qualifies: the clinician's instruction of 2026-08-22 was "change the 4 hour limit to 24 for patients in ED". Both halves are declared rather than pattern-matched, so a name nobody has invented yet fails for being undeclared. The file states plainly what it still cannot see. Four bypasses that defeated earlier drafts now fail, each verified by applying it, reading the edited line back from the file and watching the guard go red: the constant under a different name; a post-construction dueAt in TRANSPORT_ACCEPTED; the same targeted at Form 1A specifically; and three declaration shapes (object, arrow function, enum). Three tests that had quietly stopped proving anything were repaired rather than left honest-but-dormant, each confirmed by re-running the regression it exists to catch: the action inbox's one-item-per-category guard, the ED pressure breach count, and the parallel-referral-cap case. Out of scope and unchanged: forms 4A and 4C, which carry real operational deadlines about moving a person rather than about the examination timeline; and formedAt on RAISE_REFERRAL, which travels with the branch reconciliation. Verification: tsc clean, exit 0, zero output lines. Ward unit suites, one invocation, 20 files — 228 passed. Prettier clean on all 14 files. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Warning Review limit reachedNext included review available in 29 minutes. View limit detailsLimit details: You’ve used the included review currently available. Your 101 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. Review configuration: ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (14)
Comment |
This pull request has been ignored for the connected project Preview Branches by Supabase. |
Uh oh!
There was an error while loading. Please reload this page.
Reconciles the branch with `main` so the unlanded Ward Flow work can reach it. 36 files conflicted; every conflict was resolved per file and per hunk with intent, never per side, because neither side was wholly right. Why 36. PR #2289 squash-merged this branch's Phase 3 work into `main` on 2026-08-22. A squash is not an ancestor of the branch, so git treats identical lineage as unrelated content: most of the conflict was the branch's own earlier work coming back at it. 135 hunks in total, of which 41 were mechanical repetitions of one already-decided rename and the rest genuine judgement. Which side is newer flips by concern, and that is what the resolution turned on: the fabricated Mental Health Act figure, dueAt on a 1A or 3B, and statutory wording -> take main. PR #2340 is the newer correction, reviewed twice, and it carries a guard test the branch has never seen. Phase 3 behaviour main lacks: reducer closure guards, live capacity, the demo clock, expired bed holds, the role switcher -> take HEAD. This is the work the merge exists to deliver. accessibility, forced-colors, CSS, layout and performance -> take main. Ruling R76: main's design-system work must survive the ward add/add conflicts rather than be silently reverted. Source 76 hunks (62 HEAD, 11 main, 3 combined); tests 51 hunks (32 HEAD, 14 main, 5 combined); config and generated docs 8 hunks, all main, with the five generated files regenerated rather than hand-merged. Two hunks genuinely contradicted, and both were ruled rather than guessed. Which legal statuses receive a Form 1A on RAISE_REFERRAL. Taken from main, which gives one only to a patient actually awaiting examination. The branch gave one to anyone not voluntary, including a patient already recorded as an involuntary inpatient, which would let RECORD_EXAMINATION fire on someone already examined. Measured against the fixture: seven involuntary-inpatient records, none carrying a 1A. This settles open question 3 in the handover, in the conservative direction that document itself leaned toward, and it is flagged to the product owner as settled by merge rather than left to be discovered. WF-018's withdrawn referral. Taken from HEAD's empty list: the record carries no acceptedUnitId and no declines, so the withdrawal it displayed can never have happened. No test was dropped: per-file counts confirm every resolved file carries at least as many as the larger side. One assertion was deliberately not kept, main's toContainText(/Parallel referral|referred to 3/i) in ui-ward-roles.spec.ts, which a single badge satisfies while its own comment claims three. HEAD's toHaveCount(3) on the testid replaces it. Keeping both would have kept a check that cannot fail beside one that can. Invariants re-checked AFTER the merge, never only before. Ruling R81 exists because the third fabricated statutory figure in this project arrived through a file that appeared in no conflict list: no statutory duration constant declared anywhere in src no Form 1A or 3B carries a dueAt; the four that remain are 4A and 4C tests/ward-legal-figure-guard.test.ts present and passing both render sites read "no deadline recorded" zero unattributed claims about what the Act imposes, across src, tests, scripts, docs and worker. Ten code sites were fixed, two of them in files that were never conflicted and appeared in no task list eligibleCandidatesAmong still takes units as a required parameter, with its static guard and its Playwright test intact sex remains the only patient attribute main's accessibility and CSS work survived; the only ward .module.css delta from main is additive all three ward specs registered in testMatch, productionSpecPattern and the shard groups Verification: tsc --noEmit clean, exit 0, zero errors. Ward unit suites, 20 files, 239 passed, more than either side carried alone. Adoption and route-reachability, 59 passed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>


Summary
maincarriedFORM_1A_REFERRAL_EXPIRY_MINUTES = 7 * 24 * 60, doc-commented as "the Mental Health Act's seven-day outer limit". No product owner supplied that figure; an assistant wrote it from its own recollection. It is the third invented statutory figure this prototype has produced, and the second attributed to the Act in a doc comment.RAISE_REFERRALstamped it onto every newly raised Form 1A as adueAt; the seeded fixture carried authoreddueAtvalues on Form 1A movements;ward-management-console.tsxrendered· due <time>;ward-derivations.tsturned it into a "Legal timing breached" action-inbox item with a countdown;priority-queue.tsxandshortlist-panel.tsxrendered breach state from it. A user raising a referral saw a legal deadline that does not exist.tests/ward-model-phase3.test.tsrequired every Form 1A to carry adueAt, so the fabrication was pinned in place by a guard. That test now asserts the opposite, and keeps its non-vacuity floor so it still fails if the fixture stops containing 1As or 3Bs.dueAtin this model any longer. The forms record that they exist, never when they lapse. This change supplies no figure and corrects none. Removal is the only direction it moves in.LegalFormdoc comment asserted that a Form 1A "always carries a real statutory examination window, so it always carries adueAt" — the same fabrication in words. Separately,"— no statutory deadline"now reads"no deadline recorded": the first states what the Act requires with the same unearned confidence as the countdown being deleted, the second states what the record holds, which is the only claim this prototype is entitled to make. The same unattributed claim is brought into line at five further sites.tests/ward-legal-figure-guard.test.tsagainst a fourth recurrence. Two independent halves, both fail-closed by construction rather than by guessing what a bad name looks like:dueAtexcept an allowlist — 4A "Transport order" and 4C "Transfer between authorised hospitals" — each with a recorded reason for legitimately carrying an operational deadline.ward-model.tswhose initializer contains a numeric literal, naming who supplied the figure and when.ED_ACCESS_TARGET_MINUTESqualifies: the clinician's instruction of 2026-08-22 was "change the 4 hour limit to 24 for patients in ED".formedAtonRAISE_REFERRAL, which is a separate question travelling with a later branch reconciliation.Verification
Verification not run:
npm run verify:pr-local— this change is confined to the Ward Flow prototype's model, fixture, components and its own tests. Ward Flow shares no code path with retrieval, ingestion or answer generation. The gates below cover it directly and were all run first-hand on the committed tree.npx tsc --noEmit -p tsconfig.json— clean, exit 0, zero output lines.tsconfig.jsonincludes**/*.ts, so the Playwright spec edits are typechecked too.ui-ward-coordinator,ui-ward-management,ui-ward-roles— 39 passed in 1.6 min, zero failures, against a warmed dev server on this worktree's own printed port.npx prettier --checkon all 14 changed files — "All matched files use Prettier code style!"Every test added or changed was mutation-tested: the mutation applied, the edited line read back from the file, the run watched to fail, then reverted and confirmed green. Four bypasses that defeated earlier drafts of the guard now fail, each verified this way — the constant under a different name (
FORM_1A_REFERRAL_CLOCK), a post-constructiondueAtinTRANSPORT_ACCEPTED, the same targeted specifically at a Form 1A, and three declaration shapes (object, arrow function, enum).Known limits of the guard, stated in the file itself rather than implied: Part 1 exercises every event type against a 1A and a 3B, but not every guard condition inside each case; Part 2 governs
ward-model.tsexported declarations only; and the meta-check that exclusions are justified is stage-sensitive, so a bogus exclusion entry is not itself rejected. These are recorded, not hidden — the file's own assertions pin its incompleteness so that quietly widening it goes red.Risk and rollout
dueAtexplicitly — that path was built in Task 6A for Form 3B, which has never carried one — so no surface gains an absence it was not already written for. The visible effect is that a Form 1A no longer displays a due time or a "Legal timing breached" item.Clinical Governance Preflight
Clinical KB Database(sjrfecxgysukkwxsowpy)On the last item specifically: this change reduces decision-support surface rather than extending it. It removes a displayed legal deadline that no source supports. Ward Flow remains a synthetic prototype and is not clinical decision support; nothing here alters that classification.
Notes
codex/ward-management-design. That branch's own pull request (Codex/ward management design #2289) squash-merged on 2026-08-22 — before the correction was made there — which is why the fabrication is onmainwhile that branch is clean. This pull request ports the reviewed correction somainstops carrying it, without waiting for the larger branch reconciliation that is still outstanding.dueAtwere relabelled to Form 4A "Transport order" rather than deleted: one of them is now the only positive proof that the breach-scoring path works at all, so removing them would have lost real coverage.Note
Medium Risk
Touches Mental Health Act form timing on coordinator screens, inbox, and priority scoring. The change only removes an unsupported deadline and keeps 4A/4C operational clocks, but wrong legal copy here is still high-impact if it regresses.
Overview
Stops Form 1A (and already-empty Form 3B) from carrying a
dueAt. The seven-dayFORM_1A_REFERRAL_EXPIRY_MINUTESconstant is deleted;RAISE_REFERRALand the fixture no longer stamp a countdown onto examination forms. UI copy now says no deadline recorded instead of claiming what the Act requires.Transport/transfer forms 4A and 4C still keep operational
dueAts. Inbox, ED pressure, and priority scoring still treat a pastdueAtas a breach, but the live fixture no longer has examination-form breaches.Adds
tests/ward-legal-figure-guard.test.ts: runtime allowlist for which form codes may have a deadline, provenance for numeric exports inward-model.ts, and an AST denylist so invented statutory durations cannot return under a new name. Related tests that had become zero-only after the fixture change now inject 4A movements so.find()/ hard-wired-zero regressions still fail.Reviewed by Cursor Bugbot for commit e415ab2. Configure here.