fix(safety): rappel « mieux mort » + regex normalize compilées une fois
Code-review (2e passe) : - Faux négatif CrisisGuard : « je serais/suis mieux mort », « mieux mort que vivant » ne déclenchaient aucun motif. Ajout du motif « mieux mort » + 3 cas de test. (Sécurité vitale — sensibilité d'abord.) - normalize() recompilait 3 Regex à chaque appel (1×/message patient) : hoistées en constantes (MARKS/APOS/SPACES). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
7669a79f4f
commit
d7e90c16c4
|
|
@ -40,19 +40,26 @@ object CrisisGuard {
|
||||||
"(vaudrait|vaut) mieux (en finir|tout arreter|que je (parte|disparaisse|meure)|d ?arreter|arreter)",
|
"(vaudrait|vaut) mieux (en finir|tout arreter|que je (parte|disparaisse|meure)|d ?arreter|arreter)",
|
||||||
"me faire du mal", "m ?automutiler", "me mutiler", "me scarifier",
|
"me faire du mal", "m ?automutiler", "me mutiler", "me scarifier",
|
||||||
"plus la force de vivre", "mieux sans moi", "tous mieux sans moi",
|
"plus la force de vivre", "mieux sans moi", "tous mieux sans moi",
|
||||||
|
"mieux mort", // « je serais/suis mieux mort », « mieux mort que vivant »
|
||||||
"me pendre", // aucun usage bénin → autonome
|
"me pendre", // aucun usage bénin → autonome
|
||||||
"(veux|voudrais|envie de) (disparaitre|en finir|me noyer)",
|
"(veux|voudrais|envie de) (disparaitre|en finir|me noyer)",
|
||||||
"me jeter (par|sous|dans|du)", "passer a l acte"
|
"me jeter (par|sous|dans|du)", "passer a l acte"
|
||||||
).map { Regex(it) }
|
).map { Regex(it) }
|
||||||
|
|
||||||
|
// Regex de normalisation compilées une fois (detect() est appelé à chaque
|
||||||
|
// message patient — inutile de les recompiler à chaque appel).
|
||||||
|
private val MARKS = Regex("\\p{Mn}+")
|
||||||
|
private val APOS = Regex("['’‘]")
|
||||||
|
private val SPACES = Regex("\\s+")
|
||||||
|
|
||||||
/** minuscules + suppression des accents (NFD → retrait des diacritiques) +
|
/** minuscules + suppression des accents (NFD → retrait des diacritiques) +
|
||||||
* apostrophes (droites/typographiques) → espace + espaces compactés. Permet
|
* apostrophes (droites/typographiques) → espace + espaces compactés. Permet
|
||||||
* d'écrire les motifs sans accents ni apostrophes (robuste au STT et à la frappe). */
|
* d'écrire les motifs sans accents ni apostrophes (robuste au STT et à la frappe). */
|
||||||
private fun normalize(s: String): String =
|
private fun normalize(s: String): String =
|
||||||
java.text.Normalizer.normalize(s.lowercase(), java.text.Normalizer.Form.NFD)
|
java.text.Normalizer.normalize(s.lowercase(), java.text.Normalizer.Form.NFD)
|
||||||
.replace(Regex("\\p{Mn}+"), "")
|
.replace(MARKS, "")
|
||||||
.replace(Regex("['’‘]"), " ")
|
.replace(APOS, " ")
|
||||||
.replace(Regex("\\s+"), " ")
|
.replace(SPACES, " ")
|
||||||
|
|
||||||
/** true si le message évoque une idéation suicidaire / auto-agression. */
|
/** true si le message évoque une idéation suicidaire / auto-agression. */
|
||||||
fun detect(message: String): Boolean {
|
fun detect(message: String): Boolean {
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,9 @@ class CrisisGuardTest {
|
||||||
"je veux disparaître",
|
"je veux disparaître",
|
||||||
"je pense à me pendre",
|
"je pense à me pendre",
|
||||||
"je vais passer à l'acte",
|
"je vais passer à l'acte",
|
||||||
|
"je serais mieux mort", // forme conditionnelle « mieux mort »
|
||||||
|
"tout le monde serait mieux sans moi",
|
||||||
|
"je suis mieux mort que vivant",
|
||||||
// accents supprimés (sortie STT fréquente) — DOIVENT matcher quand même
|
// accents supprimés (sortie STT fréquente) — DOIVENT matcher quand même
|
||||||
"je veux mettre fin a mes jours",
|
"je veux mettre fin a mes jours",
|
||||||
"ca sert a rien de vivre",
|
"ca sert a rien de vivre",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue