"""Immediate, gated capture of explicit identity/form-of-address signals from student messages. Gates via MemoryPromotionGate and stages into approved_profile_staging — does NOT call Cognee directly (that happens batched, at Commit, via run_commit_adaptation()). Replaces the old _remember_profile_signal(), which bypassed the gate and flushed Cognee on every message. See docs/commit-memory-adaptation-architecture.md. """ from __future__ import annotations from app.services import approved_profile_staging from app.services.memory_candidates import MemoryCandidate, make_candidate_id from app.services.memory_promotion import MemoryPromotionGate from app.services.name_signal_extractor import extract_preferred_name async def capture_explicit_profile_signal( *, project_id: str, interaction_id: str, user_text: str, ) -> None: name = extract_preferred_name(user_text) if not name: return statement = f"The student prefers to be called {name}." candidate = MemoryCandidate( candidate_id=make_candidate_id("student", project_id, "preferred_name", statement), destination="student", project_id=project_id, kind="preferred_name", statement=statement, attribution="explicit_student", confidence=0.99, interaction_ids=[interaction_id], evidence_ids=[], ) decision = MemoryPromotionGate().evaluate_student(candidate) if not decision.promote: return approved_profile_staging.append(project_id, candidate)