mnemosyne/tests/test_admission.py
Joey Yakimowich-Payne 681c1454cb feat: add memory management pipeline
Admission control, entropy-based micro-faulting, phantom tool
injection for backing store queries, and xMemory session hierarchy
for long conversations (50+ turns).

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-03-13 11:41:12 -06:00

156 lines
6.3 KiB
Python

"""Tests for the admission control module.
Tests the AdmissionController scoring logic across all four axes:
type_score, novelty_score, utility_score, size_score, and the
threshold-based admit/reject decision.
"""
from __future__ import annotations
from mnemosyne.admission import AdmissionController, AdmissionScore, DEFAULT_THRESHOLD
# ── Type score ───────────────────────────────────────────────────────────
def test_admission_score_design_decision():
"""design_decision has the highest type weight (0.9)."""
ctrl = AdmissionController()
score = ctrl.score("x" * 300, "design_decision", has_duplicate=False)
assert score.type_score == 0.9
def test_admission_score_conversation_phase():
"""conversation_phase has the lowest type weight (0.3)."""
ctrl = AdmissionController()
score = ctrl.score("x" * 300, "conversation_phase", has_duplicate=False)
assert score.type_score == 0.3
def test_admission_unknown_type_default():
"""Unknown object types default to 0.3."""
ctrl = AdmissionController()
score = ctrl.score("x" * 300, "totally_unknown_type", has_duplicate=False)
assert score.type_score == 0.3
# ── Novelty score ────────────────────────────────────────────────────────
def test_admission_duplicate_penalized():
"""Duplicates get novelty_score=0.2 instead of 1.0."""
ctrl = AdmissionController()
score_unique = ctrl.score("x" * 300, "file_context", has_duplicate=False)
score_dup = ctrl.score("x" * 300, "file_context", has_duplicate=True)
assert score_unique.novelty_score == 1.0
assert score_dup.novelty_score == 0.2
assert score_dup.total < score_unique.total
# ── Utility score ────────────────────────────────────────────────────────
def test_admission_utility_code_blocks():
"""Content with code blocks gets utility boost."""
ctrl = AdmissionController()
content_with_code = "Here is code:\n```python\ndef foo(): pass\n```\n" + "x" * 200
content_plain = "Just some plain text without code blocks. " + "x" * 200
score_code = ctrl.score(content_with_code, "file_context", has_duplicate=False)
score_plain = ctrl.score(content_plain, "file_context", has_duplicate=False)
assert score_code.utility_score > score_plain.utility_score
def test_admission_utility_entities():
"""Content with many key_entities gets utility boost."""
ctrl = AdmissionController()
entities = ["foo.py", "bar.py", "baz.py"]
score_with = ctrl.score("x" * 300, "file_context", has_duplicate=False, key_entities=entities)
score_without = ctrl.score("x" * 300, "file_context", has_duplicate=False, key_entities=[])
assert score_with.utility_score > score_without.utility_score
# ── Size score ───────────────────────────────────────────────────────────
def test_admission_size_small_penalized():
"""Very small content (< 100 chars) gets penalized size_score."""
ctrl = AdmissionController()
score = ctrl.score("tiny", "file_context", has_duplicate=False)
assert score.size_score < 1.0
assert score.size_score == len("tiny") / 100
def test_admission_size_large_penalized():
"""Very large content (> 50k chars) gets penalized size_score."""
ctrl = AdmissionController()
score = ctrl.score("x" * 80000, "file_context", has_duplicate=False)
assert score.size_score < 1.0
assert score.size_score >= 0.3
def test_admission_size_normal():
"""Normal-sized content (100-50k chars) gets size_score=1.0."""
ctrl = AdmissionController()
score = ctrl.score("x" * 500, "file_context", has_duplicate=False)
assert score.size_score == 1.0
# ── Threshold decisions ──────────────────────────────────────────────────
def test_admission_threshold_admit():
"""High-value content is admitted."""
ctrl = AdmissionController()
# design_decision (0.9 type) + unique (1.0 novelty) + code + entities + length
content = "```python\ndef important(): pass\n```\n" + "x" * 300
admitted, score = ctrl.should_admit(
content,
"design_decision",
has_duplicate=False,
key_entities=["foo.py", "bar.py", "baz.py"],
)
assert admitted is True
assert score.total >= DEFAULT_THRESHOLD
def test_admission_threshold_reject():
"""Low-value duplicate conversation_phase is rejected."""
ctrl = AdmissionController()
# conversation_phase (0.3 type) + duplicate (0.2 novelty) + tiny content
admitted, score = ctrl.should_admit("hi", "conversation_phase", has_duplicate=True)
assert admitted is False
assert score.total < DEFAULT_THRESHOLD
# ── Stats tracking ───────────────────────────────────────────────────────
def test_admission_stats_tracking():
"""Stats correctly count admitted and rejected objects."""
ctrl = AdmissionController()
assert ctrl.stats == {"admitted": 0, "rejected": 0}
# Admit a high-value object
ctrl.should_admit(
"```python\ndef foo(): pass\n```\n" + "x" * 300,
"design_decision",
has_duplicate=False,
key_entities=["a.py", "b.py", "c.py"],
)
assert ctrl.stats["admitted"] == 1
# Reject a low-value object
ctrl.should_admit("hi", "conversation_phase", has_duplicate=True)
assert ctrl.stats["rejected"] == 1
assert ctrl.stats["admitted"] == 1
# ── Edge cases ───────────────────────────────────────────────────────────
def test_admission_empty_content():
"""Empty content gets size_score=0 and low utility."""
ctrl = AdmissionController()
score = ctrl.score("", "file_context", has_duplicate=False)
assert score.size_score == 0.0
assert score.utility_score == 0.0