52 lines
1.7 KiB
Python
52 lines
1.7 KiB
Python
"""Small write/decision boundary for the journal MVP. Not a policy engine."""
|
|
from __future__ import annotations
|
|
|
|
|
|
from conversation_signals import similar_enough
|
|
|
|
|
|
class PolicyError(Exception):
|
|
def __init__(self, code: str, message: str, status_code: int = 400):
|
|
super().__init__(message)
|
|
self.code = code
|
|
self.message = message
|
|
self.status_code = status_code
|
|
|
|
|
|
ENTRY_ORIGINS = {"user_edit", "accepted_draft", "restore"}
|
|
|
|
|
|
def require_explicit_generate(explicit: bool) -> None:
|
|
if not explicit:
|
|
raise PolicyError("generate_not_explicit", "Journal Drafts entstehen nur auf ausdrückliche Aktion.")
|
|
|
|
|
|
def consolidation_offer(conversations: list[dict] | int) -> bool:
|
|
"""Offer merge only when conversations look narratively compatible. User decides."""
|
|
if isinstance(conversations, int):
|
|
return False
|
|
return similar_enough(conversations)
|
|
|
|
|
|
def source_conversation_ids(explicit_ids: list[str] | None, day_conversation_ids: list[str]) -> list[str]:
|
|
"""Missing selection never silently merges multiple conversations."""
|
|
known = [item for item in day_conversation_ids if item]
|
|
if explicit_ids:
|
|
chosen = [item for item in explicit_ids if item in known]
|
|
if not chosen:
|
|
raise PolicyError("unknown_conversation", "Keine der angegebenen Conversations gehört zu diesem Tag.")
|
|
return chosen
|
|
if not known:
|
|
raise PolicyError("no_source_dialogue", "Ohne Dialog gibt es nichts zu erzeugen.")
|
|
return [known[-1]]
|
|
|
|
|
|
def draft_must_not_touch_entry() -> None:
|
|
return None
|
|
|
|
|
|
def require_origin(origin: str) -> str:
|
|
if origin not in ENTRY_ORIGINS:
|
|
raise PolicyError("invalid_origin", "origin muss user_edit, accepted_draft oder restore sein")
|
|
return origin
|