chore(core): freeze shared core contracts — ScrubbedText, RiskLevel, AlertLevel, privacy signatures

Lets #2-#7 proceed in parallel against stable interfaces.

Refs #2

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-03 14:50:30 +03:00
co-authored by Claude Opus 5.5
parent e35f5b00af
commit 3b9cd36f92
2 changed files with 37 additions and 0 deletions
+13
View File
@@ -0,0 +1,13 @@
"""PII scrubbing and pseudonymisation (issue #2). Contract stub — implementation lands in #2."""
from app.core.types import ScrubbedText
def scrub(text: str) -> ScrubbedText:
"""Replace personal data (phones, emails, SNILS, names, addresses...) with placeholders."""
raise NotImplementedError
def pseudo_id(snils: str, key: str | None = None) -> str:
"""HMAC-SHA256(PSEUDO_KEY, normalised SNILS) as 32 hex chars — the token linking identity and clinical DBs."""
raise NotImplementedError
+24
View File
@@ -0,0 +1,24 @@
"""Shared core types. Frozen contract between zones: change only via a separate small PR."""
from enum import IntEnum
from typing import NewType
# Text that has passed `app.core.privacy.scrub()`. The LLM gateway accepts only this type (guardrail #1).
ScrubbedText = NewType("ScrubbedText", str)
class RiskLevel(IntEnum):
"""Safety risk level. Ordered, so the combined signal is `max(lexicon, llm)`."""
NONE = 0
POSSIBLE = 1
ACUTE = 2
class AlertLevel(IntEnum):
"""Alert level stored in DB. UI colour is derived (ADR-006): ACUTE=red, HIGH/MODERATE=yellow, INFO=grey."""
INFO = 0
MODERATE = 1
HIGH = 2
ACUTE = 3