PR #20: Safeguarding exit language — supporter and professional variants per v1.1#20
Conversation
…r at exit call sites Prerequisite structural change for PR #20. PR #19 widened the selector to accept userType but call sites were not yet passing it. Without this wiring, the __PROFESSIONAL phrasebank entries added in subsequent commits would be dead code at the moment of merge. No behavioural change in this commit: __PROFESSIONAL entries do not yet exist, so the selector falls back to __SUPPORTER as before. Tests pass unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ebank entries Moves the inline supporter-side text in buildUnder16Exit (opener, next-steps, Childline-for-young-person, NSPCC-for-adult, sign-off, 999 line) into named phrasebank entries. Adds matching base entries for SELF text where the wording differs (opener, Childline blurb, 999), and single shared entries where the wording is identical (next-steps, sign-off). NSPCC is __SUPPORTER-only (no base entry); selector returns null for SELF users so the block contributes nothing — byte-identical to the previous if-isSupporter gate. The LA-specific Children's Services contact remains data-driven in code, between the opener and next-steps fragments. Function now composes all six fragments unconditionally via the selector (using session.userType wired through in the previous commit). No userType branching in the function itself; the selector resolves the correct variant. Pure structural change. No wording change, no behavioural change. Output bytes identical for any given input — verified by 97/97 existing tests passing including the SELF-mode under-16 assertions (__tests__/safeguarding.test.ts:147,152,157,161). Preparation for commit 3, which adds the matching __PROFESSIONAL entries and the wording updates per Supporter and Professional Language Review v1.1 (signed off by James, 8 May 2026). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Implements language changes from Supporter and Professional Language Review v1.1 (signed off by James, 8 May 2026) for the under-16 safeguarding pathway. Updated __SUPPORTER entries (v1.1 wording): - UNDER16_INTERCEPT_PREFIX__SUPPORTER - CRISIS_UNDER16_LOCATION__SUPPORTER - CRISIS_UNDER16_SOMEWHERE_ELSE__SUPPORTER New __PROFESSIONAL entries: - UNDER16_INTERCEPT_PREFIX__PROFESSIONAL - CRISIS_UNDER16_SOMEWHERE_ELSE__PROFESSIONAL - UNDER16_EXIT_OPENER__PROFESSIONAL - UNDER16_EXIT_NEXT_STEPS__PROFESSIONAL - UNDER16_EXIT_CHILDLINE_FOR_YOUNG_PERSON__PROFESSIONAL - UNDER16_EXIT_999__PROFESSIONAL CRISIS_UNDER16_LOCATION deliberately has no __PROFESSIONAL variant per v1.1 §1.2 (supporter and professional wording would be identical; selector falls back to __SUPPORTER to avoid maintenance trap). buildUnder16Exit now excludes NSPCC and sign-off fragments for PROFESSIONAL users. NSPCC adult helpline is for non-professionals worried about a child; professionals call Children's Services directly. Warm sign-off is inappropriate register for professional context. Both rationales recorded in v1.1 §1.4. Added one regression test for the userType branching behaviour (PROFESSIONAL excludes NSPCC + sign-off, retains opener and 999). 98/98 tests pass. No existing tests asserted on the old __SUPPORTER wording, so none required updates. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Implements language changes from Supporter and Professional Language
Review v1.1 (signed off by James, 8 May 2026) for DV and SA
safeguarding pathways.
DV __SUPPORTER (all 6 variants): opener replaced. Performative
"I'm really sorry this is happening to them" wording removed in favour
of direct service framing ("These services can help right now with
safety planning, emergency housing, and confidential support."). New
closing line "You don't have to work this out on your own." Contractions
in 999 line, matching commit 3 under-16 entries.
DV __PROFESSIONAL (all 6 variants): new. Direct register
("Here are the specialist contacts."), no consolation opener,
"You'll know your next steps from here." replaces governance phrasing.
SA __SUPPORTER (all 3 variants): opener replaced (parallel to DV).
BEHAVIOURAL CHANGE: 999 line added to all SA __SUPPORTER exits.
Pre-v1.1 SA exits did not include a 999 line. Adding one per v1.1
language principle "999 line on every safeguarding exit". Confirmed
by James in 8 May sign-off as intentional behavioural change rather
than wording change.
SA __PROFESSIONAL (all 3 variants): new. Content intentionally
identical in shape to DV __PROFESSIONAL. Alignment comment added
in phrasebank.ts before the first DV __PROFESSIONAL and before the
first SA __PROFESSIONAL so future divergent changes stay local.
Tests: no existing tests asserted on the old DV/SA opener wording
(audit confirmed; existing tests check phone numbers and Shelter URL
only). Three new regression tests added: SA 999 line presence
(behavioural-change protection), one DV __PROFESSIONAL fires test,
one SA __PROFESSIONAL fires test. 101/101 pass.
Note: SELF (base) entries for DV and SA are deliberately unchanged in
this commit. Per v1.1 scope, only __SUPPORTER and __PROFESSIONAL
variants are updated.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Implements language changes from Supporter and Professional Language Review v1.1 (signed off by James, 8 May 2026) for the self-harm safeguarding pathway. SELF_HARM_EXIT__SUPPORTER: opener replaced. "They deserve support" performative wording removed. "You can encourage them to contact" passive framing removed. Contractions throughout. Closing line "You don't have to work this out on your own" added. NHS terminology updated to "Mental Health Crisis Line". "A and E" → "A&E". SELF_HARM_EXIT__PROFESSIONAL: new. Direct register. "You'll know what to do from here" replaces governance phrasing. Per v1.1 rationale, self-harm involves complex capacity and confidentiality obligations; the VA cannot and should not prescribe next steps. 111 named explicitly as a route for professional uncertainty. A&E line retained on both variants. Self-harm 999 line legitimately differs from other safeguarding pathways by including A&E, which is why it stays separate from any future shared EMERGENCY_999_LINE consolidation. Wiring note: SELF_HARM_EXIT entries remain orphaned at runtime. buildSelfHarmExit (crisis.ts:85-126) is still inline and does not source from these phrasebank entries. Wiring (refactor of buildSelfHarmExit similar to commit 2's buildUnder16Exit refactor) is pending — these entries are placed for the wiring commit to draw from. Regression test added asserts on selector resolution rather than pathway firing, since the pathway is not yet wired. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ntries These unsuffixed entries existed in lib/phrasebank.ts but were not referenced by any code path. Audit confirmed zero direct references across the codebase before deletion (selector lookups via getPhrase(KEY, userType) resolve to __SUPPORTER or __PROFESSIONAL variants and do not constitute references to the unsuffixed base). Removal does not affect any behaviour. The __SUPPORTER and __PROFESSIONAL variants added in earlier commits of PR #20 (UNDER16_EXIT_*__SUPPORTER/__PROFESSIONAL, SELF_HARM_EXIT__SUPPORTER/ __PROFESSIONAL) are not affected. The legacy UNDER_16_EXIT__SUPPORTER entry is also retained per scope (this commit only removes the unsuffixed bases). Cleanup follows the principle that orphaned phrasebank entries are a trap for future engineers who might edit them expecting them to fire. 102/102 tests pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
james-cross
left a comment
There was a problem hiding this comment.
Thanks Matt, this is a solid PR. The refactor being provably byte-identical for the SELF path (covered by the existing tests) gave me confidence, and surfacing both behavioural changes (the SA 999 line and the PROFESSIONAL exclusion of NSPCC plus sign-off on under-16) in the description rather than leaving them in the diff is more good stuff.
Nothing here blocks merge and the Tier 2 classification looks right to me, with the v1.1 sign-off providing the trustee sight the PR title points to. I've left a couple of inline comments, both small.
Two things I noticed that sit outside the diff so I'm raising them here rather than inline. First, the safeguardingExit('CHILD_AT_RISK_EXIT', ...) call in lib/handlers/prevention.ts is the same shape as the DV/SA/under-16 ones this PR threads to userType, but it still passes the boolean and isn't in the "13 selector calls wired" count. Behaviour is unchanged either way since there's no __PROFESSIONAL variant for it, so this isn't a safety thing, it's just that "all safeguarding-pathway selector calls wired" is slightly stronger than what the diff delivers. Could we either thread it in a follow-up or add a line to the description noting child-at-risk is deliberately out of scope for the v1.1 wiring? Either closes the gap.
Second, memory/governance/selfHarm.test.ts references phrasebank.SELF_HARM_EXIT directly in a few places. After this PR those resolve to undefined. It doesn't break the build today only because that suite already fails to load on a pre-existing missing testUtils import, so the broken import is masking the broken references. The practical risk is that whoever fixes that import later sees these assertions fail and it looks like PR #20 caused a regression, when really it's this PR's cleanup surfacing through a separately-broken suite. Worth either updating those assertions to SELF_HARM_EXIT__SUPPORTER, or capturing it as a follow-up alongside Item 73 so it's not lost. I'd lean towards the small fix now, but either works.
The one I'd most value your input on before I approve: confirming that shipping the self-harm v1.1 entries dormant, with the wiring deferred to Item 72, is the deliberate call rather than something to hold back so phrasebank state matches runtime. Neither that or the two points above is urgent. Happy to approve once they're settled. Good work getting it to this point.
| }; | ||
| } | ||
|
|
||
| function buildSelfHarmExit(session: SessionState): RoutingResult { |
There was a problem hiding this comment.
Just noticed the v1.1 self-harm entries (SELF_HARM_EXIT__SUPPORTER and SELF_HARM_EXIT__PROFESSIONAL) land in the phrasebank in this PR, but buildSelfHarmExit here is still fully inline and reads session.isSupporter only. So today, someone selecting "thoughts of harming myself" still gets the pre-v1.1 wording, and a PROFESSIONAL user gets the supporter-flavoured version.
The PR description is honest about this and ties it to Item 72, which I think is the right call rather than rushing the wiring. Could we just confirm in the PR description that shipping the entries dormant is deliberate, so the phrasebank-vs-runtime gap is a known, recorded decision rather than something a future reviewer trips over? No code change needed here, it's a scoping confirmation. Perhaps something to add to the backlog too.
There was a problem hiding this comment.
Self-harm v1.1 entries shipped dormant: confirming deliberate. The
entries land in the phrasebank in this PR; buildSelfHarmExit in
crisis.ts remains inline and continues to read session.isSupporter,
with the wiring sitting at Item 72. The case for shipping dormant
is that the phrasebank entries benefit from being available for
review and reuse even while runtime is unchanged, and the wiring
work belongs in Item 72 alongside the buildSelfHarmExit refactor.
Note added to Item 72 in VA_BACKLOG.md. PR description updated
to record the phrasebank-vs-runtime gap as a known scoping
decision.
| return phrase('SA_GENDER_ASK', session.userType); | ||
| case 6: // Fire/flood -> ask location first | ||
| return { | ||
| ...phrase('CRISIS_FIRE_FLOOD_LOCATION', session.isSupporter), |
There was a problem hiding this comment.
Small consistency thing, not blocking. Cases 1 to 5 here use session.userType, but cases 6 and 7 (CRISIS_FIRE_FLOOD_LOCATION and LOCATION_CONSENT) still pass session.isSupporter. phrase() accepts both so it compiles fine and behaviour is unchanged (there are no __PROFESSIONAL variants for these keys). The only risk is the next person editing this converging them by accident, or splitting them further. Could we either thread userType through 6 and 7 for visual consistency, or drop a one-line comment saying fire/flood and none-apply are deliberately not in the v1.1 safeguarding-wiring scope? Either is fine, it's just about leaving a clear signal for whoever might touch this in the future.
There was a problem hiding this comment.
Cases 6 and 7 threading: done. lib/handlers/crisis.ts now passes
session.userType through CRISIS_FIRE_FLOOD_LOCATION and
LOCATION_CONSENT alongside cases 1 to 5. Behaviour unchanged (no
__PROFESSIONAL variants for these keys, phrase() accepts both).
102/102 tests passing.
There was a problem hiding this comment.
CHILD_AT_RISK_EXIT in prevention.ts: out of scope for v1.1, will
pick up in a follow-up. Behaviour unchanged here (no __PROFESSIONAL
variant). PR description updated to note explicitly.
Test suite reference fix: I ran the audit and the references
aren't where the review describes them. There's no
memory/governance/selfHarm.test.ts in the repo, no bare
phrasebank.SELF_HARM_EXIT references anywhere, and no testUtils
import to break. The one real reference in
tests/safeguarding.test.ts uses
getPhrase('SELF_HARM_EXIT', 'PROFESSIONAL'), which is the helper's
intended pattern (it appends __PROFESSIONAL / __SUPPORTER itself
in lib/phrasebank.ts:2688).
This is the same ground Item 48 in VA_BACKLOG.md covers, closed
9 April 2026 after the same audit. The original Item 48 wording
had the cause and effect reversed, which may be what's surfacing
here. If you're seeing different state on a branch I'd want to
know; on main it drops off.
Ready for approval when you are.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ew tidy-ups recorded Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Thanks for the quick turnaround Matt. The three points from my first pass are settled.
On the selfHarm.test.ts thing - you were right, that was me. I had a stale copy of the file git-ignored somehow and Jest was picking it up from disk. Sorry for the dead end; I've cleaned it up on my side and the suite is clean here too.
One thing I'd still like sorted, and I think it's quick. The DV __SUPPORTER variants gained a 999 line in this PR - every one of them now ends If they're in immediate danger, call 999., where pre-PR they ended at the Shelter URL. That's the same behavioural change you correctly flagged for SA, but the commit message and PR description describe the DV side as "contractions in 999 line" which reads as if the line was already there. Two effects of this: the trustee-sight audit trail for v1.1 has the DV 999 addition slightly hidden, and there's no regression test locking the DV 999 line (the SA one at __tests__/safeguarding.test.ts:352 is exactly the pattern - a parallel DV test would protect against silent removal in a future edit). Either fix is fine: update the description text and add a one-line DV regression test, or reply confirming the DV 999 addition was understood at v1.1 sign-off and you're comfortable carrying it without the parallel test. I'd lean towards the small fix because the SA precedent makes the asymmetry stand out.
Outside scope of this PR but worth flagging so they don't drift: the SELF DV/SA pathways still have no 999 line, so a person directly experiencing DV gets less emergency info than their supporter does; the PROFESSIONAL under-16 exit ending abruptly on the 999 line is a design choice worth being explicit about; and the new __PROFESSIONAL Male and LGBTQ+ variants for DV and SA have no regression test yet (Female variants do). None of these block - happy for them to be follow-ups or fold into future PRs.
Once the DV 999 item is settled either way, I'd be happy to approve.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…57 DV 999 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
james-cross
left a comment
There was a problem hiding this comment.
Nice refactor on this. The byte-identical-for-SELF-and-SUPPORTER shape is exactly right, and the comment above is genuinely helpful for the next person.
One small thought, not blocking. The new guard relies on UNDER16_EXIT_NSPCC_FOR_ADULT having no base entry, so the selector returns null and the || '' fallback drops the NSPCC line for SELF. That's correct behaviour right now, but it's a fallback-by-omission pattern: if someone later adds a base entry for that key (e.g. copying the SUPPORTER wording as a "sensible default"), SELF users would silently start seeing the adult NSPCC helpline. The existing SELF-mode tests don't currently assert NSPCC absence, so it wouldn't be caught.
Two cheap ways to close it if you want to fully cover it:
(a) Tighten the guard to if (session.userType === 'SUPPORTER'). That makes the intent match v1.1 §1.4 literally — NSPCC for SUPPORTER, skip for SELF and PROFESSIONAL — and removes the reliance on selector-returns-null.
(b) Add a one-line SELF assertion parallel to the existing PROFESSIONAL one:
expect(result.text).not.toContain('0808 800 5000')(a) is cleaner. (b) is the minimum-change version. Either fine, and either fine as a follow-up rather than on this PR.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Summary
Implements language changes from Supporter and Professional Language Review v1.1 (signed off 8 May 2026) across all safeguarding exit pathways: under-16, DV, SA, and self-harm. Adds
__PROFESSIONALphrasebank variants, updates__SUPPORTERwording per v1.1, threadsuserTypethrough to the phrasebank selector at call sites, and introduces userType-aware composition inbuildUnder16Exit.PR #19 widened the selector to accept
userType; this PR wires it through to call sites and adds the variant content.Tier classification
Tier 2 per Governance Decision Framework, with trustee sight via James's review of Language Review v1.1.
Commits
b1f4ee4refactor(safeguarding): thread userType through to phrasebank selector at exit call sitesb5e5d49refactor(under-16): extract buildUnder16Exit fragments to named phrasebank entriesfe0fef6feat(under-16): add professional variants and v1.1 supporter wordinga567860feat(dv-sa): update supporter wording and add professional variants4185c9efeat(self-harm): add v1.1 phrasebank entries (not yet wired)a1526ecchore(phrasebank): remove orphaned SELF_HARM_EXIT and UNDER_16_EXIT entries5b32a4cchore: update backlog with PR #20 completion and follow-up itemsDetailed walkthrough
1.
b1f4ee4— userType propagation (structural prerequisite)Widens
safeguardingExit()signature to accept userType values (was boolean only). Switches 13 safeguarding-pathway selector calls fromsession.isSupportertosession.userTypeacrosscrisis.ts(9),shared.ts(1), andstateMachine.ts(3). No behavioural change —__PROFESSIONALentries don't exist yet at this commit, so the selector falls back to__SUPPORTERas before. Without this commit, all subsequent__PROFESSIONALentries would be dead code.2.
b5e5d49— buildUnder16Exit refactorMoves inline supporter-side text in
buildUnder16Exitinto named phrasebank entries:UNDER16_EXIT_OPENER,UNDER16_EXIT_NEXT_STEPS,UNDER16_EXIT_CHILDLINE_FOR_YOUNG_PERSON,UNDER16_EXIT_NSPCC_FOR_ADULT,UNDER16_EXIT_SIGN_OFF,UNDER16_EXIT_999. LA-specific Children's Services contact remains data-driven and inline. Both base entries (for SELF byte-identical preservation) and__SUPPORTERentries added. Pure structural change, no wording change, byte-identical output.3.
fe0fef6— Under-16 v1.1 wording + professional variantsUpdates three
__SUPPORTERentries with v1.1 wording (UNDER16_INTERCEPT_PREFIX__SUPPORTER,CRISIS_UNDER16_LOCATION__SUPPORTER,CRISIS_UNDER16_SOMEWHERE_ELSE__SUPPORTER). Adds six new__PROFESSIONALentries.Deliberately omits
CRISIS_UNDER16_LOCATION__PROFESSIONALper v1.1 §1.2 — supporter and professional wording would be identical, selector falls back to__SUPPORTERto avoid maintenance trap.buildUnder16Exitnow wraps NSPCC + sign-off composition inif (session.userType !== 'PROFESSIONAL'). Per v1.1 §1.4: NSPCC adult helpline is for non-professionals worried about a child; professionals call Children's Services directly. Warm sign-off is inappropriate register for professional context.4.
a567860— DV/SA v1.1 wording + professional variants + SA 999 behavioural changeDV (12 entries touched): 6
__SUPPORTERvariants updated with v1.1 opener + closing + 999 line; 6 new__PROFESSIONALvariants added.SA (6 entries touched): 3
__SUPPORTERvariants updated with new opener + closing + 999 line; 3 new__PROFESSIONALvariants added.Alignment comment added before the first DV
__PROFESSIONALand before the first SA__PROFESSIONALdocumenting intentional content alignment per v1.1 §3.1.5.
4185c9e— Self-harm entries (not yet wired)Adds
SELF_HARM_EXIT__SUPPORTER(updated wording) andSELF_HARM_EXIT__PROFESSIONAL(new) per v1.1 §4.1.These entries are NOT currently wired into
buildSelfHarmExit— see "Deferred items" / Item 72. The live self-harm exit output is unchanged by this commit. Wiring is deferred pending a governance decision.A code comment adjacent to the new entries documents the not-wired state and the reason.
6.
a1526ec— Orphan cleanupRemoves the unsuffixed
SELF_HARM_EXITandUNDER_16_EXITphrasebank entries after audit confirmed zero direct references across the codebase. Selector lookups viagetPhrase(KEY, userType)resolve to__SUPPORTERor__PROFESSIONALvariants and do not constitute direct references to the unsuffixed base. Removal does not affect behaviour.7.
5b32a4c— Backlog refreshItem 57 status updated to "Code complete, PR #20 raised". Items 72 (self-harm wiring follow-up) and 73 (
UNDER_16_EXIT__SUPPORTERorphan) added. Afternoon change log entry added.Behavioural changes
DV exits now include a 999 line (commit 4)
Per v1.1 language principle "999 line on every safeguarding exit", all six DV
__SUPPORTERexits now end with "If they're in immediate danger, call 999." Pre-PR these__SUPPORTERexits ended at the Shelter Domestic Violence Advice URL with no 999 line — this is an added line, not a reworded or contracted one. A behavioural change parallel to the SA 999 addition below. The six new DV__PROFESSIONALvariants carry the same line as part of their initial content.SA exits now include a 999 line (commit 4)
Per v1.1 language principle "999 line on every safeguarding exit", all SA
__SUPPORTERexits now include "If they're in immediate danger, call 999." Current SA__SUPPORTERexits did not include this. Confirmed in your 8 May sign-off email as intentional. Regression test intests/safeguarding.test.tslocks in the new line.PROFESSIONAL users see different under-16 content (commit 3)
buildUnder16Exitnow excludes NSPCC and warm sign-off fragments whenuserType === 'PROFESSIONAL'. Rationale per v1.1 §1.4.PROFESSIONAL users now receive professional-specific language across under-16, DV, SA (commits 3 & 4)
Previously, PROFESSIONAL users fell back to
__SUPPORTERtext everywhere because no__PROFESSIONALentries existed. They now receive v1.1 professional register on under-16, DV, and SA exits. Self-harm not yet — see Deferred items.Deferred items (intentional)
Recorded here for trustee sight. Each is a deliberate choice in this PR, with a path forward in
VA_BACKLOG.md.Self-harm exit wiring (
VA_BACKLOG.mdItem 72)buildSelfHarmExit(lib/handlers/crisis.ts:85-126) is still fully inline and does NOT source from theSELF_HARM_EXIT__SUPPORTER/__PROFESSIONALentries added in commit 5. The live exit output is unchanged.Discrepancy surfaced during build:
buildSelfHarmExitcurrently includes Mind Infoline and a warm sign-off that v1.1 §4.1 did not represent in its "current text" column. v1.1 sign-off was therefore against an incomplete representation of current code. Wiring the v1.1 entries live would silently remove Mind Infoline and the sign-off.Decision needed before wiring:
Tracked as Item 72. Decision deferred to keep this PR's scope bounded to what was explicitly signed off.
SELF DV/SA base entries unchanged
v1.1 covers
__SUPPORTERand__PROFESSIONALvariants only. SELF (base) DV and SA entries were deliberately not updated. If v1.1 intends a SELF refresh too, that's a follow-up.SELF SA 999 line not added
The 999 line was added to SA
__SUPPORTERand__PROFESSIONALexits per v1.1 principle but NOT to SELF base entries. Worth a decision whether SELF should follow the same principle.CRISIS_UNDER16_SOMEWHERE_ELSEstyle divergenceThe SELF base entry still uses the v1.0 "SPECIALIST HELPLINE" headers and "---" separator. The new
__SUPPORTERand__PROFESSIONALv1.1 wording drops both conventions in favour of paragraph-spaced blocks. The SELF base entry now diverges in style from its supporter/professional variants. Deliberate per v1.1 scope.EMERGENCY_999_LINEconsolidationParked per your 8 May email — not in PR #20 scope. Self-harm legitimately stays separate due to the A&E addition. Worth a follow-up issue.
B2_WHO_FORhandler duplication (Item 71)Pre-existing duplication between
lib/stateMachine.ts:1194andlib/handlers/profiling.ts:43surfaced during the codebase audit. Not in PR #20 scope.UNDER_16_EXIT__SUPPORTERorphan (Item 73)A second orphan (different from the unsuffixed
UNDER_16_EXITdeleted in commit 6) was surfaced during commit 6's audit but intentionally retained as out-of-scope. Logged for separate cleanup.Test coverage
Test count progression across commits: 96 → 96 → 96 → 96 → 97 → 98 → 101 → 102 → 102, then 103 after the DV 999-line regression test (
6b61ebf). All green throughout.New tests added in this PR:
__SUPPORTERexits (locks in behavioural change — test added in follow-up commit6b61ebf); DV__PROFESSIONALresolves foruserType=PROFESSIONAL; SA__PROFESSIONALresolves foruserType=PROFESSIONALgetPhrase('SELF_HARM_EXIT', 'PROFESSIONAL')returns expected professional content (selector resolution; entries not yet wired)No existing test required updating during PR #20 — the audit was correct that no test asserted on the old opener wording.
Files touched
lib/phrasebank.ts— entry updates, new__PROFESSIONALentries, alignment comments, orphan deletionslib/shared.ts—safeguardingExit()signature widening,buildUnder16Exitrefactor + userType branchinglib/handlers/crisis.ts— userType propagation at safeguarding call siteslib/stateMachine.ts— userType propagation at safeguarding call sitestests/safeguarding.test.ts— regression testsVA_BACKLOG.md— Item 57 status, new items 72 and 73, change logReviewer guidance
Most impactful change is commit 1 (
b1f4ee4, userType propagation). The structural piece that makes everything else functional. Without it, the new__PROFESSIONALentries would be dead code at merge.Commit 5 deliberately ships entries that are not yet wired. Mind Infoline and warm sign-off discrepancy needs a separate decision before wiring (see Deferred items / Item 72).
DV and SA 999 line additions (commit 4) are behavioural changes rather than wording changes. Both add "If they're in immediate danger, call 999." to
__SUPPORTERexits that previously ended at the Shelter URL. Flagged explicitly.Three regression tests lock in the new PROFESSIONAL behaviour. Representative rather than exhaustive — per Safeguarding Contract testing philosophy.
References
UNDER_16_EXIT__SUPPORTERorphan)Scope clarifications, added in response to review
Self-harm v1.1 entries shipped dormant, deliberate.
SELF_HARM_EXIT__SUPPORTER and SELF_HARM_EXIT__PROFESSIONAL land
in the phrasebank in this PR but buildSelfHarmExit in
lib/handlers/crisis.ts remains inline and continues to read
session.isSupporter. The wiring work sits with Item 72. Shipping
the entries dormant is the deliberate call: the entries benefit
from being in the phrasebank for review and reuse even while the
runtime path is unchanged. The phrasebank-vs-runtime gap is
recorded here and tracked in the backlog against Item 72.
Child-at-risk out of v1.1 wiring scope.
safeguardingExit('CHILD_AT_RISK_EXIT', ...) in
lib/handlers/prevention.ts still passes the boolean and is not in
the "13 selector calls wired" count. Behaviour is unchanged
because there is no __PROFESSIONAL variant for this key.
Child-at-risk wiring will be picked up in a follow-up PR rather
than threaded here, to keep the v1.1 scope tight.
Cases 6 and 7 in crisis.ts threaded for visual consistency.
CRISIS_FIRE_FLOOD_LOCATION and LOCATION_CONSENT calls now pass
session.userType in line with cases 1 to 5. Behaviour is unchanged
since there are no __PROFESSIONAL variants for these keys; this is
a tidy-up to leave a clear signal for future edits.