safety: Track B — route threat-to-others to refusal+911, not 988/self-harm #76
Open
will.anderson
wants to merge 0 commits from
hotfix/trackb-threat-to-others into main
pull from: hotfix/trackb-threat-to-others
merge into: :main
:main
:feat/immutable-engram-deletes
:feat/agent-phase1-soul
:hotfix/elc-source-typos
:hotfix/trackb-threat-to-others
:feat/soul-model-self-report
:feat/openai-format-providers
:feat/plan-mode-endpoint
:fix/operator-identity-home-resolution
:fix/wrapper-backlog-endpoints
:fix/list-typed-slice-offset
:feat/connectors-call-route
:fix/chat-vision-attachments
:fix/prevent-engram-corruption
:fix/emergency-regressions
:fix/session-continuity-hook
:fix/context-dedup-shared-ids
:fix/engram-float-parser
:improve/recall-context-format
:improve/recall-context-dedup
:improve/recall-cross-session-continuity
:improve/recall-emotional-recall
:improve/recall-activation-seed
:improve/recall-recall-completeness
:improve/recall-temporal-precision
:improve/recall-engram-scoring
:improve/recall-recall-reliability
:improve/recall-session-start-recall
:improve/reliability-engram-write
:improve/reliability-state-management
:improve/soul-memory-formation
:improve/safety-crisis-detection
:improve/reliability-route-error-recovery
:improve/reliability-llm-retry
:improve/reliability-session-boundary
:improve/reliability-safety-resilience
:improve/reliability-engram-connection
:improve/soul-routes-api
:improve/reliability-cross-session-affective
:propose/agent-workspace-root-read
:improve/reliability-conv-history
:improve/soul-strip
:improve/soul-chat-pipeline
:docs/conversation-retrieval-design
:propose/no-fake-tools-in-chat-mode
:fix/ci-soul-build-single-file
:fix/canonical-self-bridge
:feat/agent-tool-workspace-scope
:fix/agentic-tools-duplicate-web-search
:green/agentic-fixes
:feat/connectors-soul
:feat/layer-safety
:feat/layer-imprint
:feat/layer-stewardship
:test/layer-composition
:test/layer-safety
:test/layer-stewardship
:test/layer-imprint
:feat/memory-delete-update
:feat/native-web-search
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Delete Branch "hotfix/trackb-threat-to-others"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
LIVE SAFETY FIX — threat-to-others must not route to the 988 suicide line
Approved by Will + Tim on 2026-07-14.
The bug
safety.elclassifies a hard bell intoabuseorself_harmand, insafety_hard_directive, defaults anything unbucketed toself_harm. A threat toward another person —"going to kill","going to hurt", etc. (fromsafety_general_hard_phrases) — had no bucket insafety_classify_hard_bell, so it fell through to theself_harmdefault.Result: for a homicide/assault statement, the user was shown the 988 Suicide & Crisis Lifeline and (via the desktop safety gate keyed on the hard bell) had their safety contact pulled in. That is the wrong resource and a dangerous framing for someone voicing intent to harm someone else.
The fix — a distinct Track B
Track A (
abuse+self_harm, the victim/self-directed paths) is correct and is left untouched. This PR adds Track B for threat-to-others:safety_threat_to_others_phrases()(homicide/assault intent toward others:going to kill/hurt him/her/them/you,going to shoot/stab,shoot up,kill everyone, …).threat_otherclassification insafety_classify_hard_bell, checked afterabuseandself_harmso victim phrasings (kill me→ abuse) and self-directed phrasings (kill myself→ self_harm) still win.threat_otherbranch insafety_hard_directivethat:threat_otherphrases also added to theis_harddetection OR-chain so weapon phrases not ingeneral_hard(e.g.going to shoot) still fire a hard bell.The directive is advisory to an LLM that sees the full message, so it explicitly instructs the model to re-judge benign/figurative matches and respond normally — keeping false positives non-accusatory.
Tests
tests/test_bell_safety.elSection 9 previously asserted the buggygoing to kill → self_harmfall-through. It now pins the corrected behavior:going to kill him/going to hurt them/going to shoot→threat_othergoing to kill me→abuse,going to kill myself→self_harmValidation
No gradle/EL interpreter is available locally and the
elc/elbcompiler is broken, so this was validated by careful reading + trace-through of every affected test case. Note that CI (ci.yaml) compiles the authoritativedist/soul.cdirectly and does not run the.elunit tests, so a green CI here does not exercise this change.⚠️ Required to ship (for the maintainer)
This is a source-only change. The live soul runs from
dist/soul.c.elb) and regeneratedist/soul.cso the new routing is compiled in. I deliberately did not hand-patch/regendist/soul.c(rebuild is delicate and the compiler is broken — out of scope for this PR).threat_othersub-type likeabuse— i.e. never notify the contact. That gate lives outside this repo; please branch onthreat_otherthere before shipping.View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.