Skip to content

PR #20: Safeguarding exit language — supporter and professional variants per v1.1#20

Merged
camlambert2000 merged 14 commits into
mainfrom
staging
Jun 2, 2026
Merged

PR #20: Safeguarding exit language — supporter and professional variants per v1.1#20
camlambert2000 merged 14 commits into
mainfrom
staging

Conversation

@camlambert2000

@camlambert2000 camlambert2000 commented May 14, 2026

Copy link
Copy Markdown
Collaborator

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 __PROFESSIONAL phrasebank variants, updates __SUPPORTER wording per v1.1, threads userType through to the phrasebank selector at call sites, and introduces userType-aware composition in buildUnder16Exit.

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.

  • No change to crisis gate options, order, or count
  • No change to hardcoded routes, numbers, or routing logic
  • No change to safeguarding bypass behaviour
  • All proposed text remains within the existing phrasebank pattern

Commits

# SHA Summary
1 b1f4ee4 refactor(safeguarding): thread userType through to phrasebank selector at exit call sites
2 b5e5d49 refactor(under-16): extract buildUnder16Exit fragments to named phrasebank entries
3 fe0fef6 feat(under-16): add professional variants and v1.1 supporter wording
4 a567860 feat(dv-sa): update supporter wording and add professional variants
5 4185c9e feat(self-harm): add v1.1 phrasebank entries (not yet wired)
6 a1526ec chore(phrasebank): remove orphaned SELF_HARM_EXIT and UNDER_16_EXIT entries
7 5b32a4c chore: update backlog with PR #20 completion and follow-up items

Detailed walkthrough

1. b1f4ee4 — userType propagation (structural prerequisite)

Widens safeguardingExit() signature to accept userType values (was boolean only). Switches 13 safeguarding-pathway selector calls from session.isSupporter to session.userType across crisis.ts (9), shared.ts (1), and stateMachine.ts (3). No behavioural change — __PROFESSIONAL entries don't exist yet at this commit, so the selector falls back to __SUPPORTER as before. Without this commit, all subsequent __PROFESSIONAL entries would be dead code.

2. b5e5d49 — buildUnder16Exit refactor

Moves inline supporter-side text in buildUnder16Exit into 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 __SUPPORTER entries added. Pure structural change, no wording change, byte-identical output.

3. fe0fef6 — Under-16 v1.1 wording + professional variants

Updates three __SUPPORTER entries with v1.1 wording (UNDER16_INTERCEPT_PREFIX__SUPPORTER, CRISIS_UNDER16_LOCATION__SUPPORTER, CRISIS_UNDER16_SOMEWHERE_ELSE__SUPPORTER). Adds six new __PROFESSIONAL entries.

Deliberately omits CRISIS_UNDER16_LOCATION__PROFESSIONAL per v1.1 §1.2 — supporter and professional wording would be identical, selector falls back to __SUPPORTER to avoid maintenance trap.

buildUnder16Exit now wraps NSPCC + sign-off composition in if (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 change

DV (12 entries touched): 6 __SUPPORTER variants updated with v1.1 opener + closing + 999 line; 6 new __PROFESSIONAL variants added.

SA (6 entries touched): 3 __SUPPORTER variants updated with new opener + closing + 999 line; 3 new __PROFESSIONAL variants added.

Alignment comment added before the first DV __PROFESSIONAL and before the first SA __PROFESSIONAL documenting intentional content alignment per v1.1 §3.1.

⚠️ Includes behavioural changes for DV and SA — see "Behavioural changes" below.

5. 4185c9e — Self-harm entries (not yet wired)

Adds SELF_HARM_EXIT__SUPPORTER (updated wording) and SELF_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 cleanup

Removes the unsuffixed SELF_HARM_EXIT and UNDER_16_EXIT phrasebank entries after audit confirmed zero direct references across the codebase. Selector lookups via getPhrase(KEY, userType) resolve to __SUPPORTER or __PROFESSIONAL variants and do not constitute direct references to the unsuffixed base. Removal does not affect behaviour.

7. 5b32a4c — Backlog refresh

Item 57 status updated to "Code complete, PR #20 raised". Items 72 (self-harm wiring follow-up) and 73 (UNDER_16_EXIT__SUPPORTER orphan) 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 __SUPPORTER exits now end with "If they're in immediate danger, call 999." Pre-PR these __SUPPORTER exits 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 __PROFESSIONAL variants 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 __SUPPORTER exits now include "If they're in immediate danger, call 999." Current SA __SUPPORTER exits did not include this. Confirmed in your 8 May sign-off email as intentional. Regression test in tests/safeguarding.test.ts locks in the new line.

PROFESSIONAL users see different under-16 content (commit 3)

buildUnder16Exit now excludes NSPCC and warm sign-off fragments when userType === '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 __SUPPORTER text everywhere because no __PROFESSIONAL entries 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.md Item 72)

buildSelfHarmExit (lib/handlers/crisis.ts:85-126) is still fully inline and does NOT source from the SELF_HARM_EXIT__SUPPORTER / __PROFESSIONAL entries added in commit 5. The live exit output is unchanged.

Discrepancy surfaced during build: buildSelfHarmExit currently 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:

  • Retain Mind Infoline + warm sign-off in any refactor (entries would need expanding)
  • Drop them per v1.1's reading
  • Some middle position

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 __SUPPORTER and __PROFESSIONAL variants 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 __SUPPORTER and __PROFESSIONAL exits per v1.1 principle but NOT to SELF base entries. Worth a decision whether SELF should follow the same principle.

CRISIS_UNDER16_SOMEWHERE_ELSE style divergence

The SELF base entry still uses the v1.0 "SPECIALIST HELPLINE" headers and "---" separator. The new __SUPPORTER and __PROFESSIONAL v1.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_LINE consolidation

Parked 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_FOR handler duplication (Item 71)

Pre-existing duplication between lib/stateMachine.ts:1194 and lib/handlers/profiling.ts:43 surfaced during the codebase audit. Not in PR #20 scope.

UNDER_16_EXIT__SUPPORTER orphan (Item 73)

A second orphan (different from the unsuffixed UNDER_16_EXIT deleted 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:

  • Commit 3: PROFESSIONAL users see opener + 999 but NOT NSPCC or warm sign-off on under-16 exit
  • Commit 4: SA 999-line presence (locks in behavioural change); DV 999-line presence across all six __SUPPORTER exits (locks in behavioural change — test added in follow-up commit 6b61ebf); DV __PROFESSIONAL resolves for userType=PROFESSIONAL; SA __PROFESSIONAL resolves for userType=PROFESSIONAL
  • Commit 5: getPhrase('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 __PROFESSIONAL entries, alignment comments, orphan deletions
  • lib/shared.tssafeguardingExit() signature widening, buildUnder16Exit refactor + userType branching
  • lib/handlers/crisis.ts — userType propagation at safeguarding call sites
  • lib/stateMachine.ts — userType propagation at safeguarding call sites
  • tests/safeguarding.test.ts — regression tests
  • VA_BACKLOG.md — Item 57 status, new items 72 and 73, change log

Reviewer guidance

  1. Most impactful change is commit 1 (b1f4ee4, userType propagation). The structural piece that makes everything else functional. Without it, the new __PROFESSIONAL entries would be dead code at merge.

  2. 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).

  3. 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 __SUPPORTER exits that previously ended at the Shelter URL. Flagged explicitly.

  4. Three regression tests lock in the new PROFESSIONAL behaviour. Representative rather than exhaustive — per Safeguarding Contract testing philosophy.

References

  • Supporter and Professional Language Review v1.1 — signed off 8 May 2026
  • VA_BACKLOG.md — Items 57 (under-16 review), 71 (B2_WHO_FOR duplication), 72 (self-harm wiring), 73 (UNDER_16_EXIT__SUPPORTER orphan)
  • Governance Decision Framework v1.0 — Tier 2 classification
  • PR fix(safeguarding): GATE0 case 2 safeguarding state; widen phrasebank selector for PROFESSIONAL #19 (predecessor) — phrasebank selector widened to accept userType
  • Safeguarding Contract v3.2 — testing philosophy applied

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.

camlambert2000 and others added 8 commits May 14, 2026 14:16
…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>
@vercel

vercel Bot commented May 14, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
street-support-va-staging Ready Ready Preview, Comment May 21, 2026 6:20am
streetsupport-platform-va Ready Ready Preview, Comment May 21, 2026 6:20am

Request Review

@camlambert2000 camlambert2000 self-assigned this May 14, 2026

@james-cross james-cross left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread lib/handlers/crisis.ts
};
}

function buildSelfHarmExit(session: SessionState): RoutingResult {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread lib/handlers/crisis.ts Outdated
return phrase('SA_GENDER_ASK', session.userType);
case 6: // Fire/flood -> ask location first
return {
...phrase('CRISIS_FIRE_FLOOD_LOCATION', session.isSupporter),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>

@james-cross james-cross left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 james-cross left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@camlambert2000 camlambert2000 merged commit 75186c1 into main Jun 2, 2026
2 checks passed
camlambert2000 added a commit that referenced this pull request Jun 2, 2026
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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