| """Player-facing investigation log helpers. | |
| Distinct from active_agency's WorldEvent feed (which drives witness/gossip | |
| mechanics and is never shown to the player). Entries here are what the | |
| detective sees in their notebook. | |
| """ | |
| import logging | |
| from backend.models.case import CaseFile, NPC, NotebookEntry | |
| log = logging.getLogger("notebook") | |
| # Anxiety at/above which a disclosure counts as a "high-anxiety reveal" (design R2). | |
| SUSPICIOUS_ANXIETY = 65 | |
| def append(case: CaseFile, kind: str, text: str, source: str = "auto") -> NotebookEntry: | |
| entry = NotebookEntry(kind=kind, text=text, source=source) | |
| case.notebook.append(entry) | |
| log.info("Notebook += [%s/%s] %s", kind, source, text[:60]) | |
| return entry | |
| def is_high_anxiety_reveal(npc: NPC) -> bool: | |
| """A turn is suspicious when the NPC is highly anxious AND is holding | |
| anxiety-gated knowledge that such pressure would tend to leak (design R2).""" | |
| if npc.emotional_state.anxiety < SUSPICIOUS_ANXIETY: | |
| return False | |
| ar = npc.authorized_reveals | |
| if not ar: | |
| return False | |
| return bool(ar.anxiety_gt_50 or ar.anxiety_gt_75) | |