- pages/2_Демо-консоль.py: persona selector, virtual clock bar (+1 h, to 08:00/20:00,
next day, reset with confirm), fallback patient web chat (buttons from Reply.buttons,
kind styling, outbox drained after every action and on a 2 s fragment poll), scenario panel
- pages/3_Сплит-экран.py: patient chat or PATIENT_WEB_URL iframe on the left, compact doctor
panel (patients, live alerts, red banner on a new acute alert) on the right
- console/playback.py: data/synthetic/<persona>.jsonl runner (advance_to/press/text/
expect_color/start), date chaining between days, pause on failure with retry/skip/manual
- console/api.py: own HTTP client over the frozen API contract, ApiError only
Refs #17
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Doctor list/card/alerts/ack/connect, dialog events/outbox/history and demo
controls now read the identity and clinical DBs. Rule-based discontinuation
risk index, trend, adherence; every doctor read is audited.
Refs #12
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- menu button «Вопрос о лечении» -> kb.question -> rag.answer (KR quote + source)
or «уточните у врача»; dose questions get a fixed doctor redirect
- free text in idle that looks like a question (no check-in signals, not a drug
question) -> knowledge base; no answer -> the usual support phrase
- routing order unchanged: consent/safety first, side effects/quit/alcohol -> check-in,
own drug -> med_qa (instruction only, SPEC §7 p.5)
- question cues, small talk and texts in config/texts/knowledge.yaml; scrub placeholders
before "что такое X" no longer hide the definition question
Refs #64
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Focus screen renders versioned questionnaire items (iq: buttons): section chip, position
(adaptive forms without "of N"), recall date, pause / help-now actions, optional skip,
sleep-hours input, 0-10 scale anchors, RUS-AUDIT item 2 standard-drink table.
- Paused / held-for-review questionnaires get their own screen.
- Today: intake and diary tasks, review notice, therapy-day card on days 1/7/14.
- Drug card /meds/:ref from data/meds/meds_reference.json (draft built from the Minzdrav
guidelines: depression 2024, PTSD 2023) — expected effect, course, side effects, red flags;
no doses shown. "Report a side effect" always available (med:side_effects:<ref>).
- API: /instruments/catalog, /meds/reference; today gains questionnaire state, reference id,
indication and therapy day; demo persona seeds the dashboard dose history.
- INTAKE_DEMO=1 (demo clock only) opens the questionnaires on synthetic data without touching
the clinical release gate in config/intake_runtime.yaml.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- focus screens: question and context on the left, answers on the right in
one wide card; consent text and the 0–10 scale in one wide column
- today: dashboard with tasks, this week's doses and quick actions side by
side; meds / doctor / profile in two-column grids; welcome gets «Как это
работает» steps
- fix: 0–10 scale no longer overflows narrow containers
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- /flow renders the dialog engine's current step as a mock screen (consent,
age, onboarding and scales with progress, mood 0–10, free text, dose
reminder, crisis with hotlines and breathing, safety plan), so every
engine scenario gets the design without duplicating its logic
- today / meds / doctor / profile / messages tabs; navy sidebar and
emergency rail on desktop, emergency block and tab bar on phones
- API: GET /me/{token}/today (today's doses, week marks, next visit, demo
clock time); demo ЕМИАС sign-in seeds the persona's synthetic profile and
prescription from the dashboard fixtures
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A second channel to the same dialog engine as the Telegram bot: consent,
onboarding, scales and check-ins come from app/dialog; the bot is unchanged.
- API: /auth/emias (doctor's one-time connect code via EmiasMock),
/auth/emias/demo (synthetic personas), /auth/anonymous (random token,
nothing stored in the identity DB), /crisis/resources from crisis.yaml
- web/: React + TS + Vite, mobile-first, safe areas, hash routing,
tokens and texts isolated for a Capacitor mobile build
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Structure-aware units with audience/evidence metadata, manual review,
hybrid BM25 search, citation-checked answers and an eval set.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- converter marks a paragraph glued across a page break with ⟦стр. N⟧; the chunker
strips the marker and extends the chunk's page range (wrong-page citations 24 -> 3,
the rest are scale-form table rows split by a page)
- [NAME]/[PHONE] placeholders from privacy.scrub() no longer count as unknown words
(a scrubbed question used to fall below the coverage gate)
- a question naming one disease boosts its guideline in retrieval and passage choice
("ТМС при депрессии" was answered from the PTSD guideline); "антидепрессант" is not a cue
Refs #62
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- app/scheduler/demo.py: run_until(now) replays due and fresh events in time order: dose rows +
med_reminder, missed after 2 h without an answer → monitoring, daily_checkin, scale_due by the
config/modules.yaml schedules, daily monitoring pass (silence, missed doses) → reach_out/scale_due
- idempotent via scheduler_events (unique token+key); stale events are not sent; no contact without
consent or during an open crisis
- config/scheduler.yaml: times and windows; runs while the questionnaire release is off
- POST /demo/clock/advance replays the scheduler up to the new time
Refs #13
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- app/services/snapshot.py: PatientSnapshot from the clinical DB (field mapping, age, therapy day,
recent C-SSRS risk, weapon access from dialog facts)
- app/services/monitoring.py: RuleMonitoring registered via register_monitoring; persists alert/crisis
actions, crisis_acute audit, enhanced_monitoring flag, cached status_color, notifies the doctor (and
the doctor on duty for crises) after commit; a running crisis is not restarted
- demo clock offset persisted in clock_state, restored on scheduler start
- tests: Andrey's 13 days through the service → G G G Y Y G G G G Y Y Y R
Refs #38
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- No same-day C-SSRS repeat: a risk screen completed within cssrs_cooldown_hours is not queued again
after PHQ-9 item 9 >= 1 (scale crisis path, rule schedule_scale, scale_due); crisis script and alerts stay.
- Scale intro registry: register_scale_intro(scale_id, text_or_fn); start_scale(intro=None) uses it.
veteran_daily migrated from per-scale on_enter hooks.
- Prefix triggers "button:<prefix>:*" with trigger_payload(event); medication buttons carry the dose
(med:taken:<dose_id>, ...), med_pending dropped; payload-less legacy buttons answer as stale.
- Abandoned-step timeout: settings.abandon_after_hours (default 6 h) returns abandonable states
(daily.*, meds.*, scale.* not in onboarding) to idle before the next event; never in crisis or with intake on.
Refs #56
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Daily check-in (mood → dose → sleep/nightmares → alcohol → free text with
extract_checkin, buttons win over the LLM, progressive upsert of
daily_checkins), medication reminder flow (taken / skip with reason /
side effects → doses + daily_checkins), medication question menu via
med_qa, med_info rule reactions from the drug instruction excerpt,
«записаться раньше» request recorded for lane B, friendly intros for
scheduled scales. actions.py: additive med_info handler hook.
Refs #37
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Start screening of the veteran module: peer-tone intro, trauma exposure gate for
PC-PTSD-5, PCL-5/PHQ-9/AUDIT-C via scale sessions (sex asked if unknown), weapon
access question stored as facts for lane B with a safe-storage block on risk,
plain-language result, modules enabled in profile, FAQ, resume after a crisis.
Refs #36
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Deep-link /start <code> binds the chat via IdentityProvider, text and
button presses go to get_engine().handle(), replies render as inline
keyboards and are sent verbatim (no parse_mode). TelegramOutbox delivers
scheduler pushes to bound chats and falls back to the previous outbox.
No-op without TG_BOT_TOKEN; logs carry no text or chat ids.
Refs #11
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DfbiLXFJswz2EK3qtWF7S7
build_structured() aggregates a PatientCard into scores, flags and
adherence (no patient text, no names); build_summary() sends it through
the LLM gateway, falls back to a config-driven template, keeps an open
acute alert first and caches per (token, provider, data hash).
Refs #19
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Topic from engine or keyword classifier, section via integrations.drug_info,
sentence retrieval by keyword overlap (dosing sentences dropped), LLM only
rephrases the excerpt through gateway.phrase("med_answer") with forbidden-output
and added-content guards; dose questions and missing answers -> None + fallback text.
Refs #15
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Freeze interfaces between lanes A (bot), B (backend), C (dashboard) so three developers work in
parallel without touching each other's files: dialog Event/Reply + engine registry with echo stub,
integration protocols with in-memory defaults, MonitoringService with noop stub, /api/v1 schemas
with fixture-backed routes, frozen main.py wiring, config/modules.yaml + due_scales(), DAR-5,
tzdata, Andrey trajectory, lanes in WORKFLOW, ADR-010.
Refs #34
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>