diff --git a/core/cli.py b/core/cli.py index 1587b47d..ddca48e0 100644 --- a/core/cli.py +++ b/core/cli.py @@ -23,9 +23,18 @@ _CORE_RS_DIR = _REPO_ROOT / "core-rs" _CORE_RS_MANIFEST = _CORE_RS_DIR / "Cargo.toml" DESCRIPTION = "CORE versor engine command suite." -EPILOG = "Examples:\n core chat\n core trace \"word beginning truth\"\n core trace --output-language grc --frame-pack grc --json \"logos\"\n core rust status\n core rust build\n core oov covenant\n core pack list\n core pack verify en_minimal_v1\n core test --suite smoke -q\n core test --suite cognition -q\n core test -- tests/test_alignment_graph.py -q\n core eval cognition\n core eval cognition --json" +EPILOG = "Examples:\n core chat\n core trace \"word beginning truth\"\n core trace --output-language grc --frame-pack grc --json \"logos\"\n core rust status\n core rust build\n core oov covenant\n core pack list\n core pack verify en_minimal_v1\n core test --suite fast -q\n core test --suite smoke -q\n core test --suite cognition -q\n core test -- tests/test_alignment_graph.py -q\n core eval cognition\n core eval cognition --json" _TEST_SUITES: dict[str, tuple[str, ...]] = { + "fast": ( + "tests/test_cli_test_suites.py", + "tests/test_runtime_config.py", + "tests/test_core_semantic_seed_pack.py", + "tests/test_intent_proposition_graph.py", + "tests/test_articulation_realizer_v2.py", + "tests/test_reviewed_teaching_loop.py", + "tests/test_cognitive_eval_harness.py", + ), "smoke": ( "tests/test_chat_runtime.py", "tests/test_achat.py", diff --git a/language_packs/compiler.py b/language_packs/compiler.py index 72133c40..8f680007 100644 --- a/language_packs/compiler.py +++ b/language_packs/compiler.py @@ -2,6 +2,7 @@ from __future__ import annotations import hashlib import json +from functools import lru_cache from pathlib import Path from typing import TYPE_CHECKING @@ -330,6 +331,22 @@ def _parse_entry(payload: dict) -> LexicalEntry: ) +def _clone_manifold(source: VocabManifold) -> VocabManifold: + """Return a mutable defensive copy of a cached compiled manifold.""" + clone = VocabManifold() + for idx in range(len(source)): + surface = source.get_word_at(idx) + clone.add( + surface, + source.get_versor_at(idx), + morphology=source.morphology_for_word(surface), + language=source.language_for_word(surface), + energy=source.energy_for_word(surface), + valence=source.valence_for_word(surface), + ) + return clone + + def _apply_alignment_corrections(home_manifold: VocabManifold, home_id_map: dict[str, str], foreign_manifold: VocabManifold, foreign_id_map: dict[str, str], pack_id: str) -> None: from alignment.graph import load_alignment @@ -351,7 +368,8 @@ def _apply_alignment_corrections(home_manifold: VocabManifold, home_id_map: dict home_manifold.update(source_surface, corrected) -def load_pack(pack_id: str) -> tuple[LanguagePackManifest, VocabManifold]: +@lru_cache(maxsize=None) +def _load_pack_cached(pack_id: str) -> tuple[LanguagePackManifest, VocabManifold]: pack_dir = Path(__file__).parent / "data" / pack_id manifest_path = pack_dir / "manifest.json" lexicon_path = pack_dir / "lexicon.jsonl" @@ -403,13 +421,14 @@ def load_pack(pack_id: str) -> tuple[LanguagePackManifest, VocabManifold]: return manifest, home_manifold -def load_mounted_packs(pack_ids: tuple[str, ...] | list[str]) -> VocabManifold: - """ - Mount multiple compiled packs into one exact-search manifold. +def load_pack(pack_id: str) -> tuple[LanguagePackManifest, VocabManifold]: + manifest, manifold = _load_pack_cached(pack_id) + return manifest, _clone_manifold(manifold) - The mounted field is a union of already-compiled Cl(4,1) points. It does - not add a side index, fallback embedding, or approximate distance path. - """ + +@lru_cache(maxsize=None) +def _load_mounted_packs_cached(pack_ids: tuple[str, ...]) -> VocabManifold: + """Compile a mounted pack union once; callers receive defensive copies.""" mounted = VocabManifold() seen: set[str] = set() primary_groups: dict[str, list[tuple[str, str]]] = {} @@ -439,6 +458,16 @@ def load_mounted_packs(pack_ids: tuple[str, ...] | list[str]) -> VocabManifold: return mounted +def load_mounted_packs(pack_ids: tuple[str, ...] | list[str]) -> VocabManifold: + """ + Mount multiple compiled packs into one exact-search manifold. + + The mounted field is a union of already-compiled Cl(4,1) points. It does + not add a side index, fallback embedding, or approximate distance path. + """ + return _clone_manifold(_load_mounted_packs_cached(tuple(pack_ids))) + + def _apply_mounted_primary_domain_resonance( mounted: VocabManifold, primary_groups: dict[str, list[tuple[str, str]]], @@ -474,7 +503,8 @@ def _infer_foreign_pack_ids(home_pack_id: str, graph: "AlignmentGraph") -> list[ return sorted(foreign) -def load_pack_entries(pack_id: str) -> list[LexicalEntry]: +@lru_cache(maxsize=None) +def _load_pack_entries_cached(pack_id: str) -> tuple[LexicalEntry, ...]: pack_dir = Path(__file__).parent / "data" / pack_id lexicon_path = pack_dir / "lexicon.jsonl" entries: list[LexicalEntry] = [] @@ -482,7 +512,11 @@ def load_pack_entries(pack_id: str) -> list[LexicalEntry]: if line.strip(): entries.append(_parse_entry(json.loads(line))) _validate_morphology_links(pack_id, entries) - return entries + return tuple(entries) + + +def load_pack_entries(pack_id: str) -> list[LexicalEntry]: + return list(_load_pack_entries_cached(pack_id)) def _validate_morphology_links(pack_id: str, entries: list[LexicalEntry]) -> None: diff --git a/tests/test_cli_test_suites.py b/tests/test_cli_test_suites.py index e7467245..c22be2df 100644 --- a/tests/test_cli_test_suites.py +++ b/tests/test_cli_test_suites.py @@ -12,6 +12,7 @@ def test_core_test_lists_curated_suites(capsys) -> None: captured = capsys.readouterr() assert rc == 0 + assert "fast" in captured.out.splitlines() assert "smoke" in captured.out.splitlines() assert "cognition" in captured.out.splitlines() assert "teaching" in captured.out.splitlines() @@ -40,6 +41,26 @@ def test_core_test_suite_expands_to_expected_pytest_paths(monkeypatch) -> None: assert "-q" in command +def test_core_test_fast_suite_expands_to_iteration_lane(monkeypatch) -> None: + calls: list[tuple[str, ...]] = [] + + def fake_run(*args: str, check: bool = False, cwd=None) -> int: + calls.append(args) + return 0 + + monkeypatch.setattr(cli, "_run", fake_run) + + rc = cli.main(["test", "--suite", "fast", "-q"]) + + assert rc == 0 + command = calls[0] + assert "tests/test_cli_test_suites.py" in command + assert "tests/test_runtime_config.py" in command + assert "tests/test_core_semantic_seed_pack.py" in command + assert "tests/test_cognitive_eval_harness.py" in command + assert "tests/" not in command + + def test_core_test_suite_accepts_pytest_flags_without_separator(monkeypatch) -> None: calls: list[tuple[str, ...]] = [] diff --git a/tests/test_language_pack_cache.py b/tests/test_language_pack_cache.py new file mode 100644 index 00000000..16ff67d3 --- /dev/null +++ b/tests/test_language_pack_cache.py @@ -0,0 +1,40 @@ +"""Language-pack cache isolation tests.""" + +from __future__ import annotations + +from language_packs.compiler import load_mounted_packs, load_pack, load_pack_entries + + +def test_load_pack_returns_defensive_manifold_copies() -> None: + _manifest_a, manifold_a = load_pack("en_core_cognition_v1") + _manifest_b, manifold_b = load_pack("en_core_cognition_v1") + + original_len = len(manifold_b) + manifold_a.insert_transient("cache_probe_token", manifold_a.get_versor("truth")) + + assert len(manifold_a) == original_len + 1 + assert len(manifold_b) == original_len + assert not manifold_b.is_transient("cache_probe_token") + + +def test_load_mounted_packs_returns_defensive_manifold_copies() -> None: + packs = ("en_minimal_v1", "en_core_cognition_v1") + mounted_a = load_mounted_packs(packs) + mounted_b = load_mounted_packs(packs) + + original_len = len(mounted_b) + mounted_a.insert_transient("mounted_cache_probe_token", mounted_a.get_versor("truth")) + + assert len(mounted_a) == original_len + 1 + assert len(mounted_b) == original_len + assert not mounted_b.is_transient("mounted_cache_probe_token") + + +def test_load_pack_entries_returns_new_list_from_cached_tuple() -> None: + entries_a = load_pack_entries("en_core_cognition_v1") + entries_b = load_pack_entries("en_core_cognition_v1") + + entries_a.pop() + + assert len(entries_a) == len(entries_b) - 1 + assert entries_b[-1].entry_id == "en-core-cog-055"