fix(resonance): remediate 0.85 score flatlining (P1-4)

- Raised ContentMemoryDB cache threshold from 0.95 to 0.98 to prevent cross-post poisoning.
- Implemented continuous resonance scoring by storing and retrieving 'resonance_score'
  in ContentMemoryDB.
- ResonanceEngine now prioritizes high-fidelity raw scores from cache over
  discrete 'high/medium/low' mapping.

TDD: 3 tests verifying threshold and scoring logic integrity.
This commit is contained in:
2026-05-04 14:42:59 +02:00
parent 91fa426b70
commit 5c9ea0e5e2
3 changed files with 21 additions and 21 deletions

View File

@@ -675,7 +675,7 @@ class ContentMemoryDB(QdrantBase):
def __init__(self):
super().__init__(collection_name="gramaddict_content_memory")
def store_evaluation(self, description: str, classification: str, reason: str):
def store_evaluation(self, description: str, classification: str, reason: str, resonance_score: float = 0.0):
"""Saves an AI-evaluated description to memory."""
if not self.is_connected or not description:
return
@@ -691,12 +691,13 @@ class ContentMemoryDB(QdrantBase):
"description": description,
"classification": classification,
"reason": reason,
"resonance_score": resonance_score,
"stored_at": time.time(),
},
log_success=f"🧠 [ContentMemory] Stored evaluation in memory: {classification} ({reason})",
log_success=f"🧠 [ContentMemory] Stored evaluation: {resonance_score:.3f} ({classification})",
)
def get_cached_evaluation(self, description: str, similarity_threshold: float = 0.95) -> Optional[dict]:
def get_cached_evaluation(self, description: str, similarity_threshold: float = 0.98) -> Optional[dict]:
"""Queries for a nearly identical past post to act as a cache."""
if not self.is_connected or not description:
return None

View File

@@ -129,7 +129,13 @@ class ResonanceEngine:
# 1. Check ContentMemoryDB cache — have we seen nearly identical content?
cached = self.content_memory.get_cached_evaluation(content_text)
if cached:
score = self._classification_to_score(cached.get("classification", "medium"))
# P1-4: Prioritize raw continuous score from cache if available
cached_score = cached.get("resonance_score")
if cached_score is not None:
score = float(cached_score)
else:
score = self._classification_to_score(cached.get("classification", "medium"))
logger.info(
f"✨ [Resonance Cache Hit] '{content_text[:40]}...'{score*100:.1f}%",
extra={"color": f"{Fore.MAGENTA}"},
@@ -163,6 +169,7 @@ class ResonanceEngine:
content_text[:500], # Cap length for storage
classification,
f"Resonance: {score:.3f} (raw cosine: {raw_score:.3f})",
resonance_score=score,
)
# 6. Feed the Parasocial CRM