Files
PTSRaiAgent/config/rules.yaml
ElebobaandClaude Opus 5.5 711c646876
CI / ruff · pytest (pull_request) Successful in 18s
feat(core): rule engine for alerts/agent actions and virtual demo clock
- app/core/clock.py: now()/today(), virtual offset (advance/set_now/reset),
  pluggable offset persistence hook (ADR-005)
- config/rules.yaml + app/core/rules.py: YAML declares rules (params, actions,
  levels, reason_ru), Python evaluators implement predicates by id; dedup of
  open alerts, crisis never suppressed; ADR-006 colours (ADR-007)
- tests: per-rule unit tests, dedup, clock, 13-day demo persona trajectory

Refs #5

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 14:58:19 +03:00

179 lines
8.5 KiB
YAML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Alert & agent-action rules (ADR-007, ADR-008).
#
# Split of responsibilities:
# * This file DECLARES the rules: id, clinical description, thresholds/windows (`params`), which actions the
# rule produces (type, level, extra params) and the short Russian reason shown on the doctor dashboard.
# A psychiatrist can change thresholds, levels, actions and texts here without touching code.
# * `app/core/rules.py` IMPLEMENTS the predicate of each rule as a Python function registered under the
# same `id` (`@evaluator("<id>")`). The function reads only the patient snapshot and `params` from here.
# Adding a new rule = new YAML entry + new evaluator; an id without an evaluator fails at load time.
#
# Fields:
# id — stable rule id; also the default alert/reason code (dedup key, stored with the alert).
# description — what and why (for the reviewer/jury); not shown to patients.
# enabled — false switches the rule off without deleting it.
# params — thresholds/windows passed to the evaluator; also available in `reason_ru` as {name}.
# actions — produced in this order when the predicate fires. `level` is info|moderate|high|acute.
# Action `params` are merged with values computed by the evaluator.
# reason_ru — short text for the doctor (str.format with params + evaluator values).
#
# Dedup: if a rule produces an `alert` whose code is already open (not acked by the doctor), the whole rule
# is silent — no repeated alert, no repeated med_info/reach_out. `crisis` is never suppressed.
#
# Starting thresholds are from SPEC §6, CLINICAL_MODULES.md and the demo persona; final values are approved
# by the team psychiatrist.
rules:
# ---------------------------------------------------------------- suicide risk → crisis (red, ADR-006)
- id: phq9_item9
description: >
PHQ-9 item 9 (thoughts of death/self-harm) >= 1 in a recent PHQ-9. Always a crisis: fixed safety
script, safety plan on screen, C-SSRS screening, immediate escalation to the doctor on duty.
params: {threshold: 1, recent_hours: 24}
actions:
- {type: crisis, level: acute}
- {type: show_safety_plan}
- {type: schedule_scale, params: {scale: cssrs_screen, scheduled: false}}
reason_ru: "PHQ-9 п.9 = {item9} (мысли о смерти/самоповреждении)"
- id: cssrs_high
description: >
C-SSRS: suicidal ideation with intent/plan or suicidal behaviour (risk "high") → urgent escalation,
safety plan and crisis contacts on screen.
params: {}
actions:
- {type: crisis, level: acute}
- {type: show_safety_plan}
reason_ru: "C-SSRS: высокий риск (намерение/план или поведение)"
- id: weapon_access_risk
description: >
Access to weapons together with any suicide-risk signal (recent PHQ-9 item 9 >= 1 or C-SSRS >= moderate).
Means restriction is one of the most evidence-based suicide-prevention measures → crisis safety block.
params: {item9_threshold: 1, cssrs_min: moderate, recent_hours: 24}
actions:
- {type: crisis, level: acute}
- {type: show_safety_plan, params: {block: means_restriction}}
reason_ru: "Доступ к оружию при сигнале суицидального риска"
- id: cssrs_moderate
description: >
C-SSRS moderate (ideation without plan/intent) = SPEC "Safety POSSIBLE" → doctor within 24 h.
params: {}
actions:
- {type: alert, level: high}
reason_ru: "C-SSRS: умеренный риск, врачу в течение 24 ч"
# ---------------------------------------------------------------- scale thresholds (yellow)
- id: phq9_severe
description: Latest PHQ-9 total in the severe range (>= 20) → doctor within 24 h.
params: {threshold: 20}
actions:
- {type: alert, level: high}
reason_ru: "PHQ-9 = {total} (тяжёлая депрессия, порог {threshold})"
- id: pcl5_severe
description: Latest PCL-5 total >= 50 → doctor within 24 h.
params: {threshold: 50}
actions:
- {type: alert, level: high}
reason_ru: "PCL-5 = {total} (порог {threshold})"
- id: phq9_rise
description: PHQ-9 rose by >= 5 points between the two latest measurements → doctor within 24 h.
params: {min_rise: 5}
actions:
- {type: alert, level: high}
reason_ru: "Рост PHQ-9 {previous} → {total} (+{rise})"
- id: pcl5_rise
description: PCL-5 rose by >= 10 points between the two latest measurements (veteran module) → doctor.
params: {min_rise: 10}
actions:
- {type: alert, level: high}
reason_ru: "Рост PCL-5 {previous} → {total} (+{rise})"
- id: auditc_positive
description: >
AUDIT-C positive screen (>= 4 men / >= 3 women). Alcohol is a suicide risk factor and interacts with
antidepressants → flag for the visit, daily alcohol question.
params: {threshold_m: 4, threshold_f: 3}
actions:
- {type: alert, level: moderate}
reason_ru: "AUDIT-C = {total} (положительный скрининг, порог {threshold})"
# ---------------------------------------------------------------- medication adherence
- id: quit_intent
description: >
Patient says they want to stop the medication (extracted from free text), or skips the dose after having
expressed that intent within the window. Delayed SSRI effect (2–4 weeks) is the usual reason → explain,
advise not to stop without the doctor, notify the doctor.
params: {window_days: 7}
actions:
- {type: alert, level: high}
- {type: med_info, params: {topic: delayed_effect}}
reason_ru: "Намерение прекратить приём препарата"
- id: missed_doses_7d
description: >
>= 3 days with a missed/skipped dose in the last 7 days → check-in about the reasons, flag for the visit.
params: {threshold: 3, window_days: 7}
actions:
- {type: alert, level: moderate}
- {type: reach_out, params: {topic: missed_doses}}
reason_ru: "Пропуски приёма: {count} из {window_days} дней"
- id: side_effect_3d
description: >
Side-effect complaints on 3 consecutive days (e.g. SSRI nausea, persona day 4) → flag for the doctor.
params: {consecutive_days: 3}
actions:
- {type: alert, level: moderate}
reason_ru: "Побочные эффекты {consecutive_days} дня подряд: {effects}"
# ---------------------------------------------------------------- daily check-in patterns
- id: sleep_lt4_3n
description: Sleep < 4 h for 3 consecutive nights (F_Y6) → flag for the doctor.
params: {consecutive_days: 3}
actions:
- {type: alert, level: moderate}
reason_ru: "Сон < 4 ч {consecutive_days} ночи подряд"
- id: alcohol_3d
description: >
Alcohol on 3 consecutive days (F_Y5) → information about alcohol/antidepressant interaction,
flag for the doctor, suggest an earlier visit.
params: {consecutive_days: 3}
actions:
- {type: alert, level: moderate}
- {type: med_info, params: {topic: alcohol_interaction}}
- {type: suggest_visit, params: {reason: alcohol}}
reason_ru: "Алкоголь {consecutive_days} дня подряд"
- id: mood_low_3d
description: >
Mood <= 3 (0–10) on 3 consecutive days → unscheduled PHQ-9 (ADR-002). Not an alert by itself; skipped if
an unscheduled PHQ-9 was already taken within the cooldown.
params: {threshold: 3, consecutive_days: 3, cooldown_days: 7}
actions:
- {type: schedule_scale, params: {scale: phq9, scheduled: false}}
reason_ru: "Настроение ≤ {threshold} {consecutive_days} дня подряд → внеплановый PHQ-9"
- id: no_contact_3d
description: >
No message from the patient for > 3 days. Silence itself is a risk signal → grey flag, caring contact.
params: {days: 3}
actions:
- {type: alert, level: info}
- {type: reach_out, params: {topic: silence}}
reason_ru: "Нет ответа пациента {silent_days} дн."
- id: young_adult_start
description: >
Age < 25 in the first 4 weeks of antidepressant therapy: possible increase of suicidal thoughts (FDA
boxed warning) → enhanced monitoring (more frequent check-ins and C-SSRS).
params: {age_below: 25, max_therapy_day: 28}
actions:
- {type: enhanced_monitoring, level: info}
reason_ru: "Возраст < 25, первые 4 недели терапии: усиленный мониторинг"