From 6b1478fd0a707dbad53a405e72dc718eaec2c2de Mon Sep 17 00:00:00 2001 From: camlambert2000 Date: Tue, 2 Jun 2026 11:16:06 +0100 Subject: [PATCH 1/5] docs(backlog): record PR #20 merge, Item 57 delivered, Item 78 added Co-Authored-By: Claude Opus 4.8 (1M context) --- VA_BACKLOG.md | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/VA_BACKLOG.md b/VA_BACKLOG.md index b328275..f33e3e8 100644 --- a/VA_BACKLOG.md +++ b/VA_BACKLOG.md @@ -1,7 +1,7 @@ # Street Support VA: Implementation Backlog **Purpose:** Track what we should be considering working on next. -**Last updated:** 21 May 2026 +**Last updated:** 2 June 2026 --- @@ -28,9 +28,10 @@ - `VA_BACKLOG.md` included in commit - `__PROFESSIONAL` entries deferred to PR #20 -### PR #20: Open — awaiting James review -**Status:** Raised against main 14 May 2026. 102/102 tests passing on staging at dd40a7f. Review responded 19 May 2026; awaiting approval. +### PR #20: Merged — 2 June 2026 +**Status:** Merged to main 2 June 2026 (mergedAt 2026-06-02T09:20:22Z; base `main`). Raised against main 14 May 2026; review responded 19 May 2026; approved and merged 2 June 2026. 102/102 tests passing on staging at dd40a7f. **URL:** https://github.com/StreetSupport/street-support-va/pull/20 +**Delivered:** Item 57 (under-16 exit — supporter and professional pathway). Cross-referenced against the merged commit list; Item 57 is the only backlog item the commits close. See Item 57 for the full chain. **Scope:** - userType propagation through phrasebank selector (13 sites) - buildUnder16Exit refactor: inline → phrasebank @@ -38,8 +39,8 @@ - DV/SA v1.1 supporter and 9 __PROFESSIONAL entries; SA 999 line - Self-harm v1.1 entries added but not wired (deferred to Item 72) - Orphan cleanup: unsuffixed SELF_HARM_EXIT and UNDER_16_EXIT removed (UNDER_16_EXIT__SUPPORTER orphan retained for separate handling — Item 73) -- Post-review tidy-ups: Item 72 backlog note added (bfed14c); cases 6 and 7 in crisis.ts threaded to session.userType for visual consistency with cases 1 to 5 (dd40a7f) -**Deferred to follow-ups:** Item 71 (B2_WHO_FOR duplication), Item 72 (self-harm wiring), Item 73 (UNDER_16_EXIT__SUPPORTER orphan delete), Item 74 (CHILD_AT_RISK_EXIT v1.1 wiring) +- Post-review tidy-ups: Item 72 backlog note added (bfed14c); cases 6 and 7 in crisis.ts threaded to session.userType for visual consistency with cases 1 to 5 (dd40a7f); DV __SUPPORTER 999 line locked by test (6b61ebf) +**Deferred to follow-ups (surfaced by PR #20 / its review, NOT closed by it):** Item 71 (B2_WHO_FOR duplication), Item 72 (self-harm wiring), Item 73 (UNDER_16_EXIT__SUPPORTER orphan delete), Item 74 (CHILD_AT_RISK_EXIT v1.1 wiring), Item 75 (SELF DV/SA 999 parity), Item 76 (PROFESSIONAL under-16 abrupt ending), Item 77 (PROFESSIONAL Male/LGBTQ+ DV/SA regression tests), Item 78 (under-16 NSPCC SELF guard hardening). --- @@ -801,6 +802,16 @@ Endpoint surfacing: cards alongside the conversation (not a terminal page), coll **Required:** Add regression tests for Male and LGBTQ+ `__PROFESSIONAL` variants on both DV and SA exits. **Files:** `__tests__/safeguarding.test.ts` +### 78. Under-16 NSPCC adult-helpline guard for SELF: harden against fallback-by-omission +**Priority:** Medium (safeguarding-adjacent) +**Status:** Open. Follow-up from James's PR #20 approval (2 June 2026). Not started. +**Issue:** The under-16 exit suppresses the adult NSPCC helpline line for SELF (direct-experience) users by fallback-by-omission. In `buildUnder16Exit` (`lib/handlers/shared.ts:97`) the guard is `if (session.userType !== 'PROFESSIONAL')`, so SELF users enter the block; the line is then dropped only because `UNDER16_EXIT_NSPCC_FOR_ADULT` has no base/SELF entry (only `UNDER16_EXIT_NSPCC_FOR_ADULT__SUPPORTER`, `phrasebank.ts:2105`), so `getPhrase(...)` returns null and `?.text || ''` yields an empty string. Output is correct today, but the guard is implicit and fragile — adding a base entry or changing the selector could silently reintroduce the adult helpline line into a child's exit. No SELF test asserts its absence. +**Required (codebase audit first, tests after — safeguarding adjacency):** +- (a) Tighten the guard to an explicit condition — `if (session.userType === 'SUPPORTER')` — so only SUPPORTER receives the NSPCC adult line, matching Under-16 Design Note v1.1 §1.4. (Confirm this preserves the PROFESSIONAL exclusion already in place.) +- (b) Add a SELF regression assertion that the under-16 exit does NOT contain the adult NSPCC helpline line. +**Files:** `lib/handlers/shared.ts`, `lib/phrasebank.ts`, `__tests__/safeguarding.test.ts` +**Source:** James Cross, PR #20 approval follow-up (2 June 2026). + --- ### 55. Financial category: constrain unconstrained `support` mapping @@ -813,7 +824,7 @@ Endpoint surfacing: cards alongside the conversation (not a terminal page), coll ### 57. Under-16 exit: supporter and professional pathway review **Priority:** High (safeguarding) -**Status:** Code complete — 14 May 2026. PR #20 raised against main, awaiting James review. +**Status:** Delivered — PR #20 merged to main 2 June 2026 (mergedAt 2026-06-02T09:20:22Z). Code complete 14 May 2026; approved and merged 2 June 2026. Follow-ups split out as Items 72–78. **PR #20 commits on staging (chain from b1f4ee4):** - b1f4ee4 — userType propagation through phrasebank selector (13 safeguarding-pathway call sites) @@ -826,6 +837,8 @@ Endpoint surfacing: cards alongside the conversation (not a terminal page), coll - bfed14c — docs: note phrasebank dormant entries on Item 72 (19 May 2026) - dd40a7f — refactor(crisis): pass session.userType for cases 6 and 7 (19 May 2026) +**Also merged in PR #20** (post-19-May staging work that rode the same merge, confirmed against the GitHub PR commit list): c5ada99 (backlog refresh, ahead of b1f4ee4), ce37922 (backlog: PR #19 merged, Item 74 added), fc5b28b (merge main into staging), 6b61ebf (test: lock DV __SUPPORTER 999 line), 773197a (backlog: Items 75–77, Item 57 DV 999 annotation). Merge tip on main: 75186c1. + **Test count:** 96 → 102 across the chain, all green. **Behaviours now implemented:** From f274f2ae066ebb19cd620696a84b846b2dcd4a88 Mon Sep 17 00:00:00 2001 From: camlambert2000 Date: Tue, 16 Jun 2026 09:42:32 +0100 Subject: [PATCH 2/5] feat(safeguarding): add 999 line to SELF DV and SA exits for parity Co-Authored-By: Claude Opus 4.8 (1M context) --- __tests__/safeguarding.test.ts | 44 ++++++++++++++++++++++++++++++++++ lib/phrasebank.ts | 36 +++++++++++++++++++++------- 2 files changed, 71 insertions(+), 9 deletions(-) diff --git a/__tests__/safeguarding.test.ts b/__tests__/safeguarding.test.ts index 77887eb..93dda7f 100644 --- a/__tests__/safeguarding.test.ts +++ b/__tests__/safeguarding.test.ts @@ -368,6 +368,30 @@ describe('Domestic Abuse Disclosure', () => { expect(endings.filter((e) => !e.ends999)).toEqual([]); }); + test('DV SELF base exits all include the 999 line (parity with supporter variants)', () => { + // The SELF base DV exits previously had no 999 line, unlike their + // __SUPPORTER counterparts. Parity added so a person disclosing for + // themselves sees the emergency line too. Parallel to the SELF SA 999 + // test in 'Sexual Violence Disclosure'. + const NINE_NINE_NINE = "If you're in immediate danger, call 999."; + const cases: Array<[string, number]> = [ + ['Female', 1], ['Female', 2], + ['Male', 1], ['Male', 2], + ['Non-binary or other', 1], ['Non-binary or other', 2], + ]; + const missing = cases.filter(([dvGender, childrenOption]) => { + const session = sessionAt('DV_CHILDREN_ASK', { + dvGender, + isSupporter: false, + userType: 'SELF', + }); + const result = select(session, childrenOption); + return !result.text.includes(NINE_NINE_NINE); + }); + // Every DV SELF exit must include the 999 line. + expect(missing).toEqual([]); + }); + }); // ============================================================================= @@ -402,6 +426,26 @@ describe('Sexual Violence Disclosure', () => { expect(result.text).toContain('999'); }); + test('SA SELF base exits all include the 999 line (parity with supporter variants)', () => { + // The SELF base SA exits previously had no 999 line, unlike their + // __SUPPORTER counterparts. Parity added so a person disclosing for + // themselves sees the emergency line too. Parallel to the SELF DV 999 + // test in 'Domestic Abuse Disclosure'. + const NINE_NINE_NINE = "If you're in immediate danger, call 999."; + // SA_GENDER_ASK options: 1=Female, 2=Male, 3=Non-binary or other + const genderOptions = [1, 2, 3]; + const missing = genderOptions.filter((genderOption) => { + const session = sessionAt('SA_GENDER_ASK', { + isSupporter: false, + userType: 'SELF', + }); + const result = select(session, genderOption); + return !result.text.includes(NINE_NINE_NINE); + }); + // Every SA SELF exit must include the 999 line. + expect(missing).toEqual([]); + }); + }); // ============================================================================= diff --git a/lib/phrasebank.ts b/lib/phrasebank.ts index 2e7f6a3..5777bf1 100644 --- a/lib/phrasebank.ts +++ b/lib/phrasebank.ts @@ -1581,7 +1581,9 @@ https://nationaldahelpline.org.uk HOUSING ADVICE Shelter - Domestic Violence Advice -https://england.shelter.org.uk/housing_advice/homelessness/priority_need/at_risk_of_domestic_abuse` +https://england.shelter.org.uk/housing_advice/homelessness/priority_need/at_risk_of_domestic_abuse + +If you're in immediate danger, call 999.` }, DV_FEMALE_CHILDREN_YES__SUPPORTER: { @@ -1637,7 +1639,9 @@ https://nationaldahelpline.org.uk HOUSING ADVICE Shelter - Domestic Violence Advice -https://england.shelter.org.uk/housing_advice/homelessness/priority_need/at_risk_of_domestic_abuse` +https://england.shelter.org.uk/housing_advice/homelessness/priority_need/at_risk_of_domestic_abuse + +If you're in immediate danger, call 999.` }, DV_FEMALE_CHILDREN_NO__SUPPORTER: { @@ -1685,7 +1689,9 @@ Confidential support for men affected by domestic violence HOUSING ADVICE Shelter - Domestic Violence Advice -https://england.shelter.org.uk/housing_advice/homelessness/priority_need/at_risk_of_domestic_abuse` +https://england.shelter.org.uk/housing_advice/homelessness/priority_need/at_risk_of_domestic_abuse + +If you're in immediate danger, call 999.` }, DV_MALE_CHILDREN_YES__SUPPORTER: { @@ -1734,7 +1740,9 @@ https://mankind.org.uk HOUSING ADVICE Shelter - Domestic Violence Advice -https://england.shelter.org.uk/housing_advice/homelessness/priority_need/at_risk_of_domestic_abuse` +https://england.shelter.org.uk/housing_advice/homelessness/priority_need/at_risk_of_domestic_abuse + +If you're in immediate danger, call 999.` }, DV_MALE_CHILDREN_NO__SUPPORTER: { @@ -1782,7 +1790,9 @@ National helpline for LGBTQ+ people affected by abuse or violence HOUSING ADVICE Shelter - Domestic Violence Advice -https://england.shelter.org.uk/housing_advice/homelessness/priority_need/at_risk_of_domestic_abuse` +https://england.shelter.org.uk/housing_advice/homelessness/priority_need/at_risk_of_domestic_abuse + +If you're in immediate danger, call 999.` }, DV_LGBTQ_CHILDREN_YES__SUPPORTER: { @@ -1831,7 +1841,9 @@ https://galop.org.uk HOUSING ADVICE Shelter - Domestic Violence Advice -https://england.shelter.org.uk/housing_advice/homelessness/priority_need/at_risk_of_domestic_abuse` +https://england.shelter.org.uk/housing_advice/homelessness/priority_need/at_risk_of_domestic_abuse + +If you're in immediate danger, call 999.` }, DV_LGBTQ_CHILDREN_NO__SUPPORTER: { @@ -1874,7 +1886,9 @@ If they're in immediate danger, call 999.` SEXUAL VIOLENCE SUPPORT Rape Crisis England & Wales 0808 500 2222 (Free, confidential, 24/7) -https://rapecrisis.org.uk` +https://rapecrisis.org.uk + +If you're in immediate danger, call 999.` }, SA_FEMALE_16PLUS__SUPPORTER: { @@ -1919,7 +1933,9 @@ SEXUAL VIOLENCE SUPPORT SurvivorsUK 020 3598 3898 https://survivorsuk.org -Specialist, confidential support for men and boys aged 16 and over` +Specialist, confidential support for men and boys aged 16 and over + +If you're in immediate danger, call 999.` }, SA_MALE_16PLUS__SUPPORTER: { @@ -1961,7 +1977,9 @@ https://survivorsuk.org SEXUAL VIOLENCE SUPPORT Galop 0800 999 5428 -https://galop.org.uk` +https://galop.org.uk + +If you're in immediate danger, call 999.` }, SA_LGBTQ_OR_NONBINARY__SUPPORTER: { From be11c58110c29c9e688e20ef17e90f42bab313ea Mon Sep 17 00:00:00 2001 From: camlambert2000 Date: Tue, 16 Jun 2026 09:46:15 +0100 Subject: [PATCH 3/5] refactor(safeguarding): thread userType through CHILD_AT_RISK_EXIT call site Co-Authored-By: Claude Opus 4.8 (1M context) --- __tests__/safeguarding.test.ts | 23 +++++++++++++++++++++++ lib/handlers/prevention.ts | 2 +- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/__tests__/safeguarding.test.ts b/__tests__/safeguarding.test.ts index 93dda7f..8f7e31a 100644 --- a/__tests__/safeguarding.test.ts +++ b/__tests__/safeguarding.test.ts @@ -448,6 +448,29 @@ describe('Sexual Violence Disclosure', () => { }); +// ============================================================================= +// CHILD AT RISK - userType wiring must resolve to a valid exit in every register +// ============================================================================= + +describe('Child At Risk Exit', () => { + + test('CHILD_AT_RISK_EXIT resolves to base entry with 999 line for SELF and PROFESSIONAL', () => { + // The call site passes session.userType (not a boolean). There is only a + // base CHILD_AT_RISK_EXIT entry — no __SUPPORTER or __PROFESSIONAL variant. + // Both registers must fall through to the base entry and still surface the + // 999 line. Guards the wiring so adding a variant later can't silently + // break either register. + const NINE_NINE_NINE = 'If a child is in immediate danger, call 999.'; + for (const userType of ['SELF', 'PROFESSIONAL'] as const) { + // B7D_4A option 4 = Child safety -> CHILD_AT_RISK_EXIT + const session = sessionAt('B7D_4A_PREVENTION_SAFEGUARDING_FOLLOW_UP', { userType }); + const result = select(session, 4); + expect(result.text).toContain(NINE_NINE_NINE); + } + }); + +}); + // ============================================================================= // SELF-HARM (from crisis gate) - Must show support, not abandon // ============================================================================= diff --git a/lib/handlers/prevention.ts b/lib/handlers/prevention.ts index f5eea12..0f902ee 100644 --- a/lib/handlers/prevention.ts +++ b/lib/handlers/prevention.ts @@ -143,7 +143,7 @@ export function handleB7D4APreventionSafeguardingFollowUp( sessionEnded: true }; case 4: // Child safety - return safeguardingExit('CHILD_AT_RISK_EXIT', session.isSupporter, 'CHILD_AT_RISK'); + return safeguardingExit('CHILD_AT_RISK_EXIT', session.userType, 'CHILD_AT_RISK'); default: // Continue to terminal const result2 = buildTerminalServices(session); const additionalNeeds = getPhrase('TERMINAL_ADDITIONAL_NEEDS', session.isSupporter); From bb73d03b9906bd30d583ebb5aa56c59d97400e77 Mon Sep 17 00:00:00 2001 From: camlambert2000 Date: Tue, 16 Jun 2026 09:53:46 +0100 Subject: [PATCH 4/5] test(safeguarding): add Male and LGBTQ+ professional regression tests for DV and SA exits Co-Authored-By: Claude Opus 4.8 (1M context) --- __tests__/safeguarding.test.ts | 59 ++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/__tests__/safeguarding.test.ts b/__tests__/safeguarding.test.ts index 8f7e31a..9e29ea4 100644 --- a/__tests__/safeguarding.test.ts +++ b/__tests__/safeguarding.test.ts @@ -341,6 +341,36 @@ describe('Domestic Abuse Disclosure', () => { expect(result.text).toContain('999'); }); + test('DV Male __PROFESSIONAL exit fires when userType is PROFESSIONAL', () => { + const session = sessionAt('DV_CHILDREN_ASK', { + dvGender: 'Male', + isSupporter: true, + userType: 'PROFESSIONAL', + }); + const result = select(session, 1); + expect(result.text).toContain('Here are the specialist contacts'); + expect(result.text).toContain("You'll know your next steps from here"); + expect(result.text).not.toContain("You don't have to work this out on your own"); + // Male DV variant routes to ManKind, not the National DA Helpline. + expect(result.text).toContain('0808 800 1170'); + expect(result.text).toContain('999'); + }); + + test('DV LGBTQ+ __PROFESSIONAL exit fires when userType is PROFESSIONAL', () => { + const session = sessionAt('DV_CHILDREN_ASK', { + dvGender: 'Non-binary or other', + isSupporter: true, + userType: 'PROFESSIONAL', + }); + const result = select(session, 1); + expect(result.text).toContain('Here are the specialist contacts'); + expect(result.text).toContain("You'll know your next steps from here"); + expect(result.text).not.toContain("You don't have to work this out on your own"); + // LGBTQ+ DV variant routes to Galop. + expect(result.text).toContain('0800 999 5428'); + expect(result.text).toContain('999'); + }); + test('DV __SUPPORTER exits all end with the 999 line (behavioural change per v1.1)', () => { // Pre-v1.1 DV __SUPPORTER exits ended at the Shelter housing advice URL. // v1.1 adds a 999 line to every safeguarding exit. Locking in the @@ -426,6 +456,35 @@ describe('Sexual Violence Disclosure', () => { expect(result.text).toContain('999'); }); + test('SA Male __PROFESSIONAL exit fires when userType is PROFESSIONAL', () => { + const session = sessionAt('SA_GENDER_ASK', { + isSupporter: true, + userType: 'PROFESSIONAL', + }); + const result = select(session, 2); // Male + expect(result.text).toContain('Here are the specialist contacts'); + expect(result.text).toContain("You'll know your next steps from here"); + expect(result.text).not.toContain("You don't have to work this out on your own"); + // Male SA variant routes to SurvivorsUK, not Rape Crisis. + expect(result.text).toContain('020 3598 3898'); + expect(result.text).toContain('999'); + }); + + test('SA LGBTQ+ __PROFESSIONAL exit fires when userType is PROFESSIONAL', () => { + const session = sessionAt('SA_GENDER_ASK', { + isSupporter: true, + userType: 'PROFESSIONAL', + }); + const result = select(session, 3); // Non-binary or other + expect(result.text).toContain('Here are the specialist contacts'); + expect(result.text).toContain("You'll know your next steps from here"); + expect(result.text).not.toContain("You don't have to work this out on your own"); + // LGBTQ+ SA variant lists both SurvivorsUK and Galop. + expect(result.text).toContain('020 3598 3898'); + expect(result.text).toContain('0800 999 5428'); + expect(result.text).toContain('999'); + }); + test('SA SELF base exits all include the 999 line (parity with supporter variants)', () => { // The SELF base SA exits previously had no 999 line, unlike their // __SUPPORTER counterparts. Parity added so a person disclosing for From f9d7f9355ccbc7c5d93bffc697c343546af54aa7 Mon Sep 17 00:00:00 2001 From: camlambert2000 Date: Tue, 16 Jun 2026 10:14:50 +0100 Subject: [PATCH 5/5] chore(backlog): mark items 75, 74, 77 complete; raise PR #21; add item 79 Co-Authored-By: Claude Opus 4.8 (1M context) --- VA_BACKLOG.md | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/VA_BACKLOG.md b/VA_BACKLOG.md index f33e3e8..cf7ee88 100644 --- a/VA_BACKLOG.md +++ b/VA_BACKLOG.md @@ -1,7 +1,7 @@ # Street Support VA: Implementation Backlog **Purpose:** Track what we should be considering working on next. -**Last updated:** 2 June 2026 +**Last updated:** 16 June 2026 --- @@ -42,6 +42,17 @@ - Post-review tidy-ups: Item 72 backlog note added (bfed14c); cases 6 and 7 in crisis.ts threaded to session.userType for visual consistency with cases 1 to 5 (dd40a7f); DV __SUPPORTER 999 line locked by test (6b61ebf) **Deferred to follow-ups (surfaced by PR #20 / its review, NOT closed by it):** Item 71 (B2_WHO_FOR duplication), Item 72 (self-harm wiring), Item 73 (UNDER_16_EXIT__SUPPORTER orphan delete), Item 74 (CHILD_AT_RISK_EXIT v1.1 wiring), Item 75 (SELF DV/SA 999 parity), Item 76 (PROFESSIONAL under-16 abrupt ending), Item 77 (PROFESSIONAL Male/LGBTQ+ DV/SA regression tests), Item 78 (under-16 NSPCC SELF guard hardening). +### PR #21: Open — raised 16 June 2026 +**Status:** Open. Raised against main 16 June 2026. Awaiting James review. 110/110 tests passing on staging; tsc clean. +**URL:** TBC +**Scope:** +- Item 75 — 999 line added to the nine SELF DV and SA base exits for parity (behavioural change — flagged for James in the PR description) +- Item 74 — `session.userType` threaded through the `CHILD_AT_RISK_EXIT` call site (no behaviour change; completes safeguarding-pathway selector coverage) +- Item 77 — four Male and LGBTQ+ professional regression tests for DV and SA exits +**Test count:** 102 → 110, all green. `tsc --noEmit` clean. +**Commits:** f274f2a, be11c58, bb73d03, plus this backlog refresh. +**Behavioural change flagged for James:** Item 75 adds a 999 emergency line to the SELF (direct-experience) DV and SA exits, so a person disclosing for themselves now sees the same emergency line their supporter does. Called out explicitly in the PR description. + --- ## Governance Decisions Log @@ -775,7 +786,7 @@ Endpoint surfacing: cards alongside the conversation (not a terminal page), coll ### 74. CHILD_AT_RISK_EXIT: supporter and professional pathway wiring **Priority:** Medium (safeguarding-adjacent) -**Status:** Surfaced 19 May 2026 in PR #20 review. Not started. +**Status:** Complete — PR #21, 16 June 2026. Surfaced 19 May 2026 in PR #20 review. **Issue:** `safeguardingExit('CHILD_AT_RISK_EXIT', ...)` in `lib/handlers/prevention.ts` still passes `session.isSupporter` as a boolean and is not in the "13 selector calls wired" count delivered by PR #20. Behaviour is unchanged today because there is no `__PROFESSIONAL` variant for this key, so `phrase()` produces the same output. Wiring needs picking up to complete the safeguarding-pathway selector coverage. **Required:** Thread `session.userType` through the `safeguardingExit('CHILD_AT_RISK_EXIT', ...)` call. If a `CHILD_AT_RISK_EXIT__PROFESSIONAL` variant is wanted, write it in phrasebank as part of this item. Run tests. **Files:** `lib/handlers/prevention.ts`, possibly `lib/phrasebank.ts` @@ -783,7 +794,7 @@ Endpoint surfacing: cards alongside the conversation (not a terminal page), coll ### 75. SELF DV and SA exits: 999 line parity **Priority:** Medium (safeguarding) -**Status:** Surfaced 19 May 2026 in PR #20 review. Not started. +**Status:** Complete — PR #21, 16 June 2026. Surfaced 19 May 2026 in PR #20 review. **Issue:** PR #20 added the 999 line to DV and SA `__SUPPORTER` exits. SELF (direct-experience) DV and SA exits still have no 999 line, so a person directly experiencing DV or SA gets less emergency information than their supporter does. **Required:** Add 999 line to SELF DV and SA exits mirroring the `__SUPPORTER` pattern, with regression tests. **Files:** `lib/phrasebank.ts`, `__tests__/safeguarding.test.ts` @@ -797,7 +808,7 @@ Endpoint surfacing: cards alongside the conversation (not a terminal page), coll ### 77. `__PROFESSIONAL` Male and LGBTQ+ DV/SA variants: regression tests **Priority:** Medium (test coverage) -**Status:** Surfaced 19 May 2026 in PR #20 review. Not started. +**Status:** Complete — PR #21, 16 June 2026. Surfaced 19 May 2026 in PR #20 review. **Issue:** PR #20 added `__PROFESSIONAL` Male and LGBTQ+ variants for DV and SA exits. Female `__PROFESSIONAL` variants have regression tests; Male and LGBTQ+ don't. Asymmetric coverage on safeguarding-adjacent entries. **Required:** Add regression tests for Male and LGBTQ+ `__PROFESSIONAL` variants on both DV and SA exits. **Files:** `__tests__/safeguarding.test.ts` @@ -812,6 +823,14 @@ Endpoint surfacing: cards alongside the conversation (not a terminal page), coll **Files:** `lib/handlers/shared.ts`, `lib/phrasebank.ts`, `__tests__/safeguarding.test.ts` **Source:** James Cross, PR #20 approval follow-up (2 June 2026). +### 79. SA supporter 999 test asymmetry: extend to Male and LGBTQ+ +**Priority:** Low (test-only) +**Status:** Open. Surfaced 16 June 2026 codebase audit. Not started. +**Issue:** The SA `__SUPPORTER` 999 test checks the Female variant only, while the DV `__SUPPORTER` 999 test loops all six variants. Asymmetric coverage on the SA supporter 999 line. +**Required:** Extend the SA supporter 999 test to Male and LGBTQ+ for symmetric coverage with the DV supporter test. +**Files:** `__tests__/safeguarding.test.ts` +**Note:** Originally raised as "Item 78" in the 16 June 2026 instruction; renumbered to 79 because 78 was already taken by the under-16 NSPCC SELF guard item (collision-renumbering convention, cf. items 60/61 → 67/68). + --- ### 55. Financial category: constrain unconstrained `support` mapping @@ -1213,3 +1232,4 @@ When enriched eligibility data is in use, confidence levels must influence langu | 2026-04-30 | Item 57 in progress. B2_WHO_FOR audit: userType stored as SUPPORTER/PROFESSIONAL but collapsed to isSupporter boolean downstream — distinction unused. GATE0 case 2 safeguardingTriggered fix built. Phrasebank selector widened to support __PROFESSIONAL variant. Supporter and Professional Language Review v1.0 produced — with James for sign-off. PR #19 ready to commit (mechanical changes). PR #20 will follow once language approved. Items 46, 55, 56, 3 (governance docs) all marked complete. Backlog fully audited and updated. | | 2026-05-14 | Supporter and Professional Language Review v1.1 signed off by James 8 May 2026. PR #20 codebase audit complete, three structural pieces confirmed: (1) add v1.1 phrasebank entries, (2) refactor buildUnder16Exit from inline strings to phrasebank composition, (3) wire userType through to phrasebank selector at call sites — critical structural piece without which new __PROFESSIONAL entries would be dead code. Adjacent findings: orphaned SELF_HARM_EXIT and UNDER_16_EXIT phrasebank entries to delete in PR #20 (audit-first confirmation), SA exits gain 999 line (behavioural change to flag in PR description). Item 57 status updated; Item 71 added (B2_WHO_FOR handler duplication, not in PR #20 scope). PR #20 ready to build. Pipeline repo work today is on a separate workstream — see PIPELINE_BACKLOG.md in ssn-enrichment-pipeline. | | 2026-05-14 (afternoon) | PR #20 (under-16 + DV + SA + self-harm supporter/professional language) work complete on staging, awaiting James review. Six commits: b1f4ee4 (userType propagation through selector), b5e5d49 (buildUnder16Exit refactor to phrasebank composition), fe0fef6 (under-16 v1.1 wording + professional variants, PROFESSIONAL excludes NSPCC/sign-off), a567860 (DV/SA v1.1 wording + professional variants, SA 999 behavioural change), 4185c9e (self-harm entries placed but not wired pending Item 72 decision), a1526ec (orphan cleanup of unsuffixed SELF_HARM_EXIT and UNDER_16_EXIT). Plus 7th commit refreshing this backlog. Test count 96 → 102, all green throughout. Item 57 status updated. Item 72 added (self-harm wiring follow-up — governance decision needed on Mind Infoline and warm sign-off). Item 73 added (UNDER_16_EXIT__SUPPORTER orphan cleanup, low priority). | +| 2026-06-16 | Recorded PR #20 merge to main (2 June 2026) in changelog. PR #21 raised against main (items 75, 74, 77): 999 line added to the nine SELF DV/SA base exits (behavioural change flagged for James), `session.userType` threaded through the CHILD_AT_RISK_EXIT call site (no behaviour change), four Male/LGBTQ+ professional regression tests for DV and SA. Commits f274f2a, be11c58, bb73d03 plus this backlog refresh. Test count 102 → 110, all green, tsc clean. Items 75, 74, 77 marked Complete (PR #21). Item 79 added (SA supporter 999 test asymmetry, low priority test-only; requested as "Item 78" but renumbered — 78 already taken). |