Phase 3 — vault exact recall index: - Replace O(N) np.array_equal scan with hash-based exact-match index - Add optional max_entries with deterministic FIFO eviction - Index rebuilds on reproject for consistency Phase 4 — Rust versor_apply parity: - Fix CGA metric signature (+,+,+,+,-) and blade ordering to match Python - Implement versor_apply_closed with null-vector preservation, f64 unitize, and construction seed fallback matching Python closure semantics - Gate Rust dispatch behind CORE_BACKEND=rust; Python remains default - Add f64 geometric product for closure-path precision Phase 5 — cognitive quality pack expansion: - Expand lexicon from 55 to 70 entries (evidence, inference, procedure, verification, distinction, relation, thought, understanding, judgment, principle, order, connectives) - Improve semantic templates for cause, procedure, comparison, recall, verification intents - Expand eval cases from 20 to 45 across all categories Validation: 491 tests pass, 45 eval cases at 100% all metrics.
222 lines
8.7 KiB
Python
222 lines
8.7 KiB
Python
"""Tests for semantic realizer integration into the cognitive pipeline.
|
|
|
|
Verifies that the semantic realizer produces structurally better surfaces
|
|
from intent + proposition graph, and that the ChatResponse contract holds.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
|
|
from generate.intent import IntentTag, classify_intent
|
|
from generate.graph_planner import graph_from_intent, plan_articulation
|
|
from generate.realizer import realize_semantic, realize_target, RealizedPlan
|
|
from generate.semantic_templates import humanize_predicate, render_semantic
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Unit tests: semantic_templates
|
|
# ---------------------------------------------------------------------------
|
|
|
|
class TestSemanticTemplates:
|
|
def test_humanize_known_predicate(self) -> None:
|
|
assert humanize_predicate("is_defined_as") == "is defined as"
|
|
assert humanize_predicate("contrasts_with") == "contrasts with"
|
|
assert humanize_predicate("defines") == "defines"
|
|
assert humanize_predicate("means") == "means"
|
|
assert humanize_predicate("grounds") == "grounds"
|
|
assert humanize_predicate("supports") == "supports"
|
|
assert humanize_predicate("corrects") == "corrects"
|
|
|
|
def test_humanize_unknown_predicate_uses_underscore_replacement(self) -> None:
|
|
assert humanize_predicate("some_new_predicate") == "some new predicate"
|
|
|
|
def test_render_definition(self) -> None:
|
|
surface = render_semantic(
|
|
intent=IntentTag.DEFINITION,
|
|
subject="truth",
|
|
predicate="is_defined_as",
|
|
obj="coherence",
|
|
)
|
|
assert "truth" in surface
|
|
assert "is defined as" in surface
|
|
assert "coherence" in surface
|
|
|
|
def test_render_comparison(self) -> None:
|
|
surface = render_semantic(
|
|
intent=IntentTag.COMPARISON,
|
|
subject="truth",
|
|
predicate="contrasts_with",
|
|
obj="light",
|
|
secondary="light",
|
|
)
|
|
assert "truth" in surface
|
|
assert "light" in surface
|
|
|
|
def test_render_correction(self) -> None:
|
|
surface = render_semantic(
|
|
intent=IntentTag.CORRECTION,
|
|
subject="correction",
|
|
predicate="corrects",
|
|
obj="reviewed repair",
|
|
)
|
|
assert "correction" in surface.lower()
|
|
|
|
def test_pending_obj_displays_as_ellipsis(self) -> None:
|
|
surface = render_semantic(
|
|
intent=IntentTag.DEFINITION,
|
|
subject="truth",
|
|
predicate="is_defined_as",
|
|
obj="<pending>",
|
|
)
|
|
assert "<pending>" not in surface
|
|
assert "..." in surface
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Unit tests: realize_semantic
|
|
# ---------------------------------------------------------------------------
|
|
|
|
class TestRealizeSemantic:
|
|
def test_definition_prompt_uses_semantic_realizer(self) -> None:
|
|
intent = classify_intent("What is truth?")
|
|
assert intent.tag is IntentTag.DEFINITION
|
|
graph = graph_from_intent(intent)
|
|
target = plan_articulation(graph)
|
|
plan = realize_semantic(target, graph)
|
|
assert isinstance(plan, RealizedPlan)
|
|
assert plan.surface
|
|
assert "truth" in plan.surface.lower()
|
|
assert "is defined as" in plan.surface.lower()
|
|
|
|
def test_comparison_prompt_mentions_both_terms(self) -> None:
|
|
intent = classify_intent("Compare truth and light")
|
|
assert intent.tag is IntentTag.COMPARISON
|
|
graph = graph_from_intent(intent)
|
|
target = plan_articulation(graph)
|
|
plan = realize_semantic(target, graph)
|
|
assert plan.surface
|
|
assert "truth" in plan.surface.lower()
|
|
assert "light" in plan.surface.lower()
|
|
|
|
def test_correction_prompt_uses_correction_template(self) -> None:
|
|
intent = classify_intent("No, correction means reviewed repair")
|
|
assert intent.tag is IntentTag.CORRECTION
|
|
graph = graph_from_intent(intent)
|
|
target = plan_articulation(graph)
|
|
plan = realize_semantic(target, graph)
|
|
assert plan.surface
|
|
assert "correction" in plan.surface.lower()
|
|
|
|
def test_cause_prompt(self) -> None:
|
|
intent = classify_intent("Why does light exist?")
|
|
assert intent.tag is IntentTag.CAUSE
|
|
graph = graph_from_intent(intent)
|
|
target = plan_articulation(graph)
|
|
plan = realize_semantic(target, graph)
|
|
assert plan.surface
|
|
assert "is grounded in" in plan.surface.lower()
|
|
|
|
def test_empty_target_returns_empty_plan(self) -> None:
|
|
from generate.graph_planner import ArticulationTarget
|
|
plan = realize_semantic(
|
|
ArticulationTarget(steps=(), source_intent=IntentTag.UNKNOWN),
|
|
)
|
|
assert plan.surface == ""
|
|
assert plan.fragments == ()
|
|
|
|
def test_none_target_returns_empty_plan(self) -> None:
|
|
plan = realize_semantic(None)
|
|
assert plan.surface == ""
|
|
|
|
def test_seed_relation_predicates_humanize_deterministically(self) -> None:
|
|
seed_predicates = [
|
|
"defines", "means", "grounds", "supports",
|
|
"contrasts_with", "corrects", "causes", "reveals",
|
|
"precedes", "follows", "belongs_to", "answers",
|
|
]
|
|
for pred in seed_predicates:
|
|
h = humanize_predicate(pred)
|
|
assert "_" not in h, f"{pred} humanized to {h!r} still has underscores"
|
|
assert h == humanize_predicate(pred), f"{pred} not deterministic"
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Integration: realize_semantic vs realize_target produce valid plans
|
|
# ---------------------------------------------------------------------------
|
|
|
|
class TestSemanticVsRhetoricalRealization:
|
|
@pytest.mark.parametrize("prompt,expected_intent", [
|
|
("What is truth?", IntentTag.DEFINITION),
|
|
("Compare truth and light", IntentTag.COMPARISON),
|
|
("Why does light exist?", IntentTag.CAUSE),
|
|
("No, that's wrong", IntentTag.CORRECTION),
|
|
])
|
|
def test_both_realizers_produce_nonempty_surface(
|
|
self, prompt: str, expected_intent: IntentTag,
|
|
) -> None:
|
|
intent = classify_intent(prompt)
|
|
assert intent.tag is expected_intent
|
|
graph = graph_from_intent(intent)
|
|
target = plan_articulation(graph)
|
|
|
|
rhetorical = realize_target(target, graph)
|
|
semantic = realize_semantic(target, graph)
|
|
|
|
assert rhetorical.surface, f"rhetorical plan empty for {prompt!r}"
|
|
assert semantic.surface, f"semantic plan empty for {prompt!r}"
|
|
|
|
def test_semantic_surfaces_are_deterministic(self) -> None:
|
|
prompt = "What is truth?"
|
|
results = set()
|
|
for _ in range(5):
|
|
intent = classify_intent(prompt)
|
|
graph = graph_from_intent(intent)
|
|
target = plan_articulation(graph)
|
|
plan = realize_semantic(target, graph)
|
|
results.add(plan.surface)
|
|
assert len(results) == 1, f"Non-deterministic: {results}"
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Contract: ChatResponse shape still holds through the pipeline
|
|
# ---------------------------------------------------------------------------
|
|
|
|
class TestChatResponseContractStillHolds:
|
|
def test_chat_response_has_required_fields(self) -> None:
|
|
try:
|
|
from chat.runtime import ChatRuntime, ChatResponse
|
|
except Exception:
|
|
pytest.skip("ChatRuntime not importable in this environment")
|
|
|
|
runtime = ChatRuntime()
|
|
response = runtime.chat("What is truth?")
|
|
assert isinstance(response, ChatResponse)
|
|
assert isinstance(response.surface, str)
|
|
assert response.surface
|
|
assert isinstance(response.versor_condition, float)
|
|
assert response.versor_condition < 1e-6
|
|
assert response.proposition is not None
|
|
assert response.articulation is not None
|
|
assert isinstance(response.articulation_surface, str)
|
|
assert isinstance(response.walk_surface, str)
|
|
assert isinstance(response.dialogue_role, str)
|
|
assert isinstance(response.vault_hits, int)
|
|
|
|
def test_pipeline_result_uses_semantic_surface(self) -> None:
|
|
try:
|
|
from chat.runtime import ChatRuntime
|
|
from core.cognition.pipeline import CognitiveTurnPipeline
|
|
except Exception:
|
|
pytest.skip("ChatRuntime not importable in this environment")
|
|
|
|
runtime = ChatRuntime()
|
|
pipeline = CognitiveTurnPipeline(runtime)
|
|
result = pipeline.run("What is truth?")
|
|
|
|
assert result.surface
|
|
assert "truth" in result.surface.lower()
|
|
assert "is defined as" in result.surface.lower()
|
|
assert result.articulation_surface == result.surface
|
|
assert result.versor_condition < 1e-6
|
|
assert result.trace_hash
|