Merge pull request #175 from AssetOverflow/chore/main-test-rot

chore(tests): reconcile pre-existing main rot — 58 failures → 0
This commit is contained in:
Shay 2026-05-23 14:48:06 -07:00 committed by GitHub
commit e2227d7552
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 129 additions and 41 deletions

View file

@ -1,18 +1,19 @@
"""``en_core_meta_v1`` — conversational substrate pack tests. """``en_core_meta_v1`` — conversational substrate pack tests.
The meta pack carries 73 lemmas across four semantic clusters that the The meta pack carries 77 lemmas (73 seed + 4 added under adr-0085-style-v2
cognition pack deliberately omits: review) across four semantic clusters that the cognition pack deliberately
omits:
- meta.speech_act.* say, tell, claim, deny, suggest, ... (20 verbs) - meta.speech_act.* say, tell, claim, deny, suggest, ... (20+ verbs)
- meta.mental_state.* know, believe, want, doubt, decide, ... (18 verbs) - meta.mental_state.* know, believe, want, doubt, decide, ... (18+ verbs)
- meta.perception.* see, hear, feel, notice, find, ... (11 verbs) - meta.perception.* see, hear, feel, notice, find, ... (11+ verbs)
- meta.self_reference.* self, mind, view, role, model, ... (10 nouns) - meta.self_reference.* self, mind, view, role, model, ... (10 nouns)
- meta.discourse.* fact, idea, statement, instance, ... (14 nouns) - meta.discourse.* fact, idea, statement, instance, ... (14 nouns)
Contracts pinned here: Contracts pinned here:
- Checksum-verified load (bytes-on-disk match manifest digest). - Checksum-verified load (bytes-on-disk match manifest digest).
- 73 entries total, broken down 49 VERB / 24 NOUN. - 77 entries total, broken down 53 VERB / 24 NOUN.
- Every lemma carries a semantic_domains list starting with ``meta.``. - Every lemma carries a semantic_domains list starting with ``meta.``.
- No collision with ``en_core_cognition_v1`` lemmas (forbidden list - No collision with ``en_core_cognition_v1`` lemmas (forbidden list
enforced at authoring time re-asserted here as a regression gate). enforced at authoring time re-asserted here as a regression gate).
@ -35,10 +36,23 @@ from language_packs.compiler import load_pack
PACK_ID = "en_core_meta_v1" PACK_ID = "en_core_meta_v1"
_PACK_ROOT = Path(__file__).resolve().parent.parent / "language_packs" / "data" / PACK_ID _PACK_ROOT = Path(__file__).resolve().parent.parent / "language_packs" / "data" / PACK_ID
EXPECTED_TOTAL = 73 EXPECTED_TOTAL = 77
EXPECTED_VERB = 49 EXPECTED_VERB = 53
EXPECTED_NOUN = 24 EXPECTED_NOUN = 24
# Allowed provenance shapes:
# - ``["seed:core_meta_v1"]`` for original seed entries
# - ``["seed:core_meta_v1", "adr-0085-style-v2:reviewed:2026-05-22"]`` /
# ``["seed:core_meta", "adr-0085-style-v2:reviewed:2026-05-22"]`` for
# entries added under the ADR-0085 style-v2 review.
# The ``seed:core_meta`` (no _v1) shape on two entries (feel, think) is a
# known author-time inconsistency; the test allows it rather than masking it.
_ALLOWED_PROVENANCE_SHAPES: frozenset[tuple[str, ...]] = frozenset({
("seed:core_meta_v1",),
("seed:core_meta_v1", "adr-0085-style-v2:reviewed:2026-05-22"),
("seed:core_meta", "adr-0085-style-v2:reviewed:2026-05-22"),
})
EXPECTED_REPRESENTATIVE_LEMMAS: tuple[str, ...] = ( EXPECTED_REPRESENTATIVE_LEMMAS: tuple[str, ...] = (
"say", "tell", "deny", "suggest", "respond", "say", "tell", "deny", "suggest", "respond",
"know", "believe", "doubt", "decide", "hold", "know", "believe", "doubt", "decide", "hold",
@ -124,7 +138,8 @@ def test_no_collision_with_cognition_v1() -> None:
def test_provenance_is_seed_core_meta_v1() -> None: def test_provenance_is_seed_core_meta_v1() -> None:
for entry in _read_lexicon(): for entry in _read_lexicon():
assert entry["provenance_ids"] == ["seed:core_meta_v1"], entry shape = tuple(entry["provenance_ids"])
assert shape in _ALLOWED_PROVENANCE_SHAPES, entry
def test_entry_ids_contiguous_and_zero_padded() -> None: def test_entry_ids_contiguous_and_zero_padded() -> None:

View file

@ -34,15 +34,23 @@ from language_packs.compiler import load_pack
PACK_ID = "en_core_spatial_v1" PACK_ID = "en_core_spatial_v1"
_PACK_ROOT = Path(__file__).resolve().parent.parent / "language_packs" / "data" / PACK_ID _PACK_ROOT = Path(__file__).resolve().parent.parent / "language_packs" / "data" / PACK_ID
EXPECTED_TOTAL = 24 EXPECTED_TOTAL = 25
EXPECTED_POS_COUNTS = {"ADV": 7, "ADP": 8, "NOUN": 9} EXPECTED_POS_COUNTS = {"ADV": 7, "ADP": 8, "NOUN": 10}
# Manifold surfaces include an inflected plural ("places") under a distinct
# entry id (en-core-spatial-025) added during the adr-0085-style-v2 review.
EXPECTED_LEMMAS: tuple[str, ...] = ( EXPECTED_LEMMAS: tuple[str, ...] = (
"here", "there", "forward", "backward", "left", "up", "down", "here", "there", "forward", "backward", "left", "up", "down",
"near", "far", "above", "below", "inside", "outside", "between", "beyond", "near", "far", "above", "below", "inside", "outside", "between", "beyond",
"place", "location", "area", "region", "space", "end", "top", "bottom", "side", "place", "places", "location", "area", "region", "space", "end", "top",
"bottom", "side",
) )
_ALLOWED_PROVENANCE_SHAPES: frozenset[tuple[str, ...]] = frozenset({
("seed:core_spatial_v1",),
("seed:core_spatial", "adr-0085-style-v2:reviewed:2026-05-22"),
})
def _read_lexicon() -> list[dict]: def _read_lexicon() -> list[dict]:
return [ return [
@ -90,7 +98,8 @@ def test_no_collision_with_prior_packs() -> None:
def test_provenance_is_seed_core_spatial_v1() -> None: def test_provenance_is_seed_core_spatial_v1() -> None:
for entry in _read_lexicon(): for entry in _read_lexicon():
assert entry["provenance_ids"] == ["seed:core_spatial_v1"], entry shape = tuple(entry["provenance_ids"])
assert shape in _ALLOWED_PROVENANCE_SHAPES, entry
def test_entry_ids_contiguous_and_zero_padded() -> None: def test_entry_ids_contiguous_and_zero_padded() -> None:
@ -113,7 +122,11 @@ def test_pack_registered_after_prior_content_packs() -> None:
def test_resolver_routes_spatial_lemmas_to_this_pack() -> None: def test_resolver_routes_spatial_lemmas_to_this_pack() -> None:
# "places" is a plural surface (entry en-core-spatial-025), not a lemma —
# the resolver only resolves on lemma form, so exclude inflected surfaces.
for lemma in EXPECTED_LEMMAS: for lemma in EXPECTED_LEMMAS:
if lemma == "places":
continue
resolved = resolve_lemma(lemma) resolved = resolve_lemma(lemma)
assert resolved is not None and resolved[0] == PACK_ID, ( assert resolved is not None and resolved[0] == PACK_ID, (
f"{lemma!r} resolved to {resolved}" f"{lemma!r} resolved to {resolved}"

View file

@ -15,6 +15,7 @@ Contracts pinned here:
from __future__ import annotations from __future__ import annotations
import json import json
import os
from pathlib import Path from pathlib import Path
import pytest import pytest
@ -22,6 +23,32 @@ import pytest
from evals.framework import LaneInfo, get_lane, run_lane from evals.framework import LaneInfo, get_lane, run_lane
def _holdout_decryption_available() -> bool:
"""Return True if the cognition lane's holdout cases can be loaded
by ``evals.holdout_runner._decrypt_holdout``.
Mirrors ``_decrypt_holdout``'s contract: with no
``CORE_HOLDOUT_KEY``, the loader looks for a sibling
``cases_plaintext.jsonl`` next to the encrypted file. Tests skip
when neither is available so CI stays green on contributor
machines that don't have the sealed key.
"""
if os.environ.get("CORE_HOLDOUT_KEY"):
return True
try:
sealed = get_lane("cognition").holdout_cases_path_sealed()
except Exception:
return False
plaintext = sealed.parent / "cases_plaintext.jsonl"
return plaintext.exists() and plaintext.read_text().strip() != ""
_requires_holdout = pytest.mark.skipif(
not _holdout_decryption_available(),
reason="holdout cases not available (set CORE_HOLDOUT_KEY or provide cases_plaintext.jsonl)",
)
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# LaneInfo.holdout_cases_path resolution # LaneInfo.holdout_cases_path resolution
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@ -69,6 +96,7 @@ def test_holdout_path_when_nothing_exists_returns_versioned_path(tmp_path: Path)
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@_requires_holdout
def test_run_lane_holdout_runs_full_cognition_set() -> None: def test_run_lane_holdout_runs_full_cognition_set() -> None:
lane = get_lane("cognition") lane = get_lane("cognition")
result = run_lane(lane, split="holdout") result = run_lane(lane, split="holdout")
@ -77,6 +105,7 @@ def test_run_lane_holdout_runs_full_cognition_set() -> None:
assert result.metrics["total"] == 19 assert result.metrics["total"] == 19
@_requires_holdout
def test_run_lane_holdout_returns_expected_metric_keys() -> None: def test_run_lane_holdout_returns_expected_metric_keys() -> None:
lane = get_lane("cognition") lane = get_lane("cognition")
result = run_lane(lane, split="holdout") result = run_lane(lane, split="holdout")
@ -90,6 +119,7 @@ def test_run_lane_holdout_returns_expected_metric_keys() -> None:
assert expected.issubset(result.metrics.keys()) assert expected.issubset(result.metrics.keys())
@_requires_holdout
def test_run_lane_holdout_versor_closure_preserved() -> None: def test_run_lane_holdout_versor_closure_preserved() -> None:
"""The non-negotiable field invariant (versor_condition < 1e-6) must """The non-negotiable field invariant (versor_condition < 1e-6) must
hold on every holdout case same gate as dev/public.""" hold on every holdout case same gate as dev/public."""
@ -113,6 +143,7 @@ def test_run_lane_unknown_split_lists_all_three_values() -> None:
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@_requires_holdout
def test_holdout_dev_public_share_metric_schema() -> None: def test_holdout_dev_public_share_metric_schema() -> None:
lane = get_lane("cognition") lane = get_lane("cognition")
dev = run_lane(lane, split="dev").metrics dev = run_lane(lane, split="dev").metrics

View file

@ -83,8 +83,10 @@ class TestPromotedDomainsBuildSuccessfully:
class TestUnpromotedDomainRefused: class TestUnpromotedDomainRefused:
def test_unpromoted_domain_raises_value_error(self) -> None: def test_unpromoted_domain_raises_value_error(self) -> None:
# arithmetic is a real language pack but has no audit_passed_claims
# entry (unlike systems_software, mathematics_logic, physics).
with pytest.raises(ValueError, match="No audit_passed_claims entry"): with pytest.raises(ValueError, match="No audit_passed_claims entry"):
build_expert_demo("systems_software") build_expert_demo("arithmetic")
def test_unknown_domain_raises_value_error(self) -> None: def test_unknown_domain_raises_value_error(self) -> None:
with pytest.raises(ValueError, match="No audit_passed_claims entry"): with pytest.raises(ValueError, match="No audit_passed_claims entry"):

View file

@ -89,6 +89,7 @@ class TestExpectedLaneCoverage:
"fabrication_control_summary", # ADR-0096 "fabrication_control_summary", # ADR-0096
"demo_composition", # ADR-0098 "demo_composition", # ADR-0098
"public_demo", # ADR-0099 "public_demo", # ADR-0099
"curriculum_loop_closure",
} }
) )

View file

@ -37,4 +37,4 @@ def test_load_pack_entries_returns_new_list_from_cached_tuple() -> None:
entries_a.pop() entries_a.pop()
assert len(entries_a) == len(entries_b) - 1 assert len(entries_a) == len(entries_b) - 1
assert entries_b[-1].entry_id == "en-core-cog-085" assert entries_b[-1].entry_id == "en-core-cog-091"

View file

@ -13,6 +13,7 @@ import pytest
from teaching.store import PackMutationProposal from teaching.store import PackMutationProposal
from teaching.epistemic import EpistemicStatus from teaching.epistemic import EpistemicStatus
from teaching.source import ProposalSource
def _sample_proposal(**overrides: object) -> PackMutationProposal: def _sample_proposal(**overrides: object) -> PackMutationProposal:
@ -22,6 +23,9 @@ def _sample_proposal(**overrides: object) -> PackMutationProposal:
"subject": "memory", "subject": "memory",
"correction_text": "memory is the storage of recalled experience", "correction_text": "memory is the storage of recalled experience",
"prior_surface": "i do not know what memory means", "prior_surface": "i do not know what memory means",
"source": ProposalSource(
kind="operator", source_id="", emitted_at_revision="test"
),
} }
defaults.update(overrides) defaults.update(overrides)
return PackMutationProposal(**defaults) # type: ignore[arg-type] return PackMutationProposal(**defaults) # type: ignore[arg-type]

View file

@ -118,19 +118,21 @@ class TestLexiconResidencyEnforced:
class TestMissingGlossesIsBackCompat: class TestMissingGlossesIsBackCompat:
"""All currently-ratified packs ship no glosses.jsonl — the """When a pack ships no glosses.jsonl the resolver must treat that
resolver must treat that as the default and return None / empty, as the default and return None / empty, never raise.
never raise."""
en_minimal_v1 is the canonical no-glosses pack used here; most
content packs have since had glosses seeded under ADR-0085."""
def test_pack_with_no_glosses_returns_empty(self) -> None: def test_pack_with_no_glosses_returns_empty(self) -> None:
# en_core_relations_v1 currently ships no glosses glosses = _pack_glosses_for("en_minimal_v1")
glosses = _pack_glosses_for("en_core_relations_v1")
assert glosses == {} assert glosses == {}
def test_resolve_gloss_on_lemma_without_gloss_file_returns_none(self) -> None: def test_resolve_gloss_on_lemma_without_gloss_file_returns_none(self) -> None:
# ``parent`` is in en_core_relations_v1 lexicon; that pack # ``yes`` is in en_minimal_v1 lexicon; that pack ships no
# ships no glosses.jsonl today. # glosses.jsonl today. Restrict resolution to that pack so a
assert resolve_gloss("parent") is None # gloss seeded for "yes" elsewhere can't shadow the test.
assert resolve_gloss("yes", ("en_minimal_v1",)) is None
class TestClearResolverCacheClearsBoth: class TestClearResolverCacheClearsBoth:

View file

@ -101,17 +101,17 @@ class TestGlossQuote:
return _surface_quotes_gloss(surface, terms) return _surface_quotes_gloss(surface, terms)
def test_quoted_short_gloss_detected(self) -> None: def test_quoted_short_gloss_detected(self) -> None:
# ``light`` gloss is ``"visible medium that reveal truth"`` — # ``light`` gloss is ``"a visible medium that reveals truth"`` —
# 5 tokens, but only 5 are ≥4 chars; the old 4-token window # 6 tokens, only 4 are ≥4 chars; the old 4-token window would
# would barely fit. ``parent`` gloss is ``"person with a child"`` # barely fit. ``parent`` gloss is ``"person with a child"``
# 4 tokens, 3 are ≥4 chars; the old window could never match. # 4 tokens, 3 are ≥4 chars; the old window could never match.
# Substring match handles both natively. # Substring match handles both natively.
assert self._make( assert self._make(
"Parent is person with a child. pack-grounded (en_core_relations_v1).", "Parent is person with a child. pack-grounded (en_core_relations_v1).",
("parent",), ("parent",),
) is True ) is True
assert self._make( assert self._make(
"Light is visible medium that reveal truth. pack-grounded (en_core_cognition_v1).", "Light is a visible medium that reveals truth. pack-grounded (en_core_cognition_v1).",
("light",), ("light",),
) is True ) is True

View file

@ -17,6 +17,7 @@ from field.state import FieldState
from generate.articulation import ArticulationPlan from generate.articulation import ArticulationPlan
from generate.intent import DialogueIntent, IntentTag from generate.intent import DialogueIntent, IntentTag
from generate.proposition import Proposition from generate.proposition import Proposition
from teaching.source import ProposalSource
from teaching.store import PackMutationProposal from teaching.store import PackMutationProposal
@ -122,6 +123,9 @@ def test_pack_plus_teaching() -> None:
subject="x", subject="x",
correction_text="x is z", correction_text="x is z",
prior_surface="x is y", prior_surface="x is y",
source=ProposalSource(
kind="operator", source_id="", emitted_at_revision="test"
),
) )
result = _make_result( result = _make_result(
intent_tag=IntentTag.CORRECTION, intent_tag=IntentTag.CORRECTION,

View file

@ -77,21 +77,25 @@ def test_each_confirmation_prompt_now_articulates(
# ---------- byte-identity invariant on currently-passing cases ---------- # ---------- byte-identity invariant on currently-passing cases ----------
# Surfaces re-pinned after the gloss-aware composer landed; the prior
# strings (e.g. "Light is a source of revelation that makes things knowable.")
# were superseded by gloss-driven phrasings ("Light is a visible medium
# that reveals truth.") that are visibly more grounded. The byte-identity
# guard role is preserved by pinning the current outputs going forward.
_CURRENTLY_PASSING_PROMPTS: tuple[tuple[str, str], ...] = ( _CURRENTLY_PASSING_PROMPTS: tuple[tuple[str, str], ...] = (
( (
"What is light?", "What is light?",
"Light is a source of revelation that makes things knowable. " "Light is a visible medium that reveals truth. "
"pack-grounded (en_core_cognition_v1).", "pack-grounded (en_core_cognition_v1).",
), ),
( (
"Define knowledge.", "Define knowledge.",
"Knowledge is justified understanding grounded in evidence " "Knowledge is what a person knows from truth and evidence. "
"and recall. pack-grounded (en_core_cognition_v1).", "pack-grounded (en_core_cognition_v1).",
), ),
( (
"What is truth?", "What is truth?",
"Truth is a claim or state grounded by evidence and coherent " "Truth is what is true. pack-grounded (en_core_cognition_v1).",
"judgment. pack-grounded (en_core_cognition_v1).",
), ),
) )

View file

@ -45,6 +45,9 @@ REGISTER_AWARE_COMPOSERS: frozenset[str] = frozenset(
# called from chat/runtime.py directly, so the # called from chat/runtime.py directly, so the
# runtime-threading lint passes trivially. # runtime-threading lint passes trivially.
"build_pack_surface_candidate", "build_pack_surface_candidate",
"gloss_aware_cause_surface",
"pack_grounded_unknown_surface",
"teaching_grounded_surface_transitive",
} }
) )

View file

@ -59,11 +59,11 @@ def _r(overrides: Mapping[str, object]) -> _FakeRegister:
_DEF_CANONICAL = ( _DEF_CANONICAL = (
"Light is a source of revelation that makes things knowable. " "Light is a visible medium that reveals truth. "
"pack-grounded (en_core_cognition_v1)." "pack-grounded (en_core_cognition_v1)."
) )
_DEF_CANONICAL_LENS = ( _DEF_CANONICAL_LENS = (
"Light is a source of revelation that makes things knowable. " "Light is a visible medium that reveals truth. "
"pack-grounded (en_core_cognition_v1) [lens(grc_logos_v1):systematic]." "pack-grounded (en_core_cognition_v1) [lens(grc_logos_v1):systematic]."
) )
_CMP_CANONICAL = ( _CMP_CANONICAL = (
@ -115,7 +115,7 @@ def test_drop_provenance_strips_trailing_gloss_clause():
_DEF_CANONICAL, _r({"drop_provenance_tag": True}), _DEF_CANONICAL, _r({"drop_provenance_tag": True}),
) )
assert "pack-grounded" not in out assert "pack-grounded" not in out
assert out.endswith("knowable.") assert out.endswith("reveals truth.")
assert "..," not in out and ".." not in out # no double-period bug assert "..," not in out and ".." not in out # no double-period bug
@ -288,10 +288,10 @@ def test_terse_full_combo_def_form():
"drop_articles": True, "drop_articles": True,
}), }),
) )
# compress: "Light is a source ... knowable." -> "Light: source ... knowable." # compress: "Light is a visible medium ... truth." -> "Light: visible medium ... truth."
# drop_articles: removes leftover "a/the" articles (none in this gloss). # drop_articles: removes leftover "a/the" articles.
# drop_provenance_tag: trailing pack-grounded clause removed. # drop_provenance_tag: trailing pack-grounded clause removed.
assert out == "Light: source of revelation that makes things knowable." assert out == "Light: visible medium that reveals truth."
def test_terse_full_combo_with_lens(): def test_terse_full_combo_with_lens():
@ -409,7 +409,7 @@ def test_e2e_neutral_unchanged_by_r6(neutral_def_surface: str):
"""default_neutral_v1 has no R6 knobs → surface must be identical """default_neutral_v1 has no R6 knobs → surface must be identical
to the pre-R6 byte-for-byte expected gloss.""" to the pre-R6 byte-for-byte expected gloss."""
expected = ( expected = (
"Light is a source of revelation that makes things knowable. " "Light is a visible medium that reveals truth. "
"pack-grounded (en_core_cognition_v1)." "pack-grounded (en_core_cognition_v1)."
) )
assert neutral_def_surface == expected assert neutral_def_surface == expected

View file

@ -242,6 +242,7 @@ def test_cognition_lane_metrics_unchanged_with_transitive_flag() -> None:
expected_surface_contains assertion that passed flag-OFF must still expected_surface_contains assertion that passed flag-OFF must still
pass flag-ON. If a future change ever drops tokens in transitive pass flag-ON. If a future change ever drops tokens in transitive
mode, this test fails as the deliberate regression it is.""" mode, this test fails as the deliberate regression it is."""
import os
from evals.framework import get_lane, run_lane from evals.framework import get_lane, run_lane
lane = get_lane("cognition") lane = get_lane("cognition")
@ -256,7 +257,15 @@ def test_cognition_lane_metrics_unchanged_with_transitive_flag() -> None:
transitive_surface=True, transitive_surface=True,
transitive_max_depth=2, transitive_max_depth=2,
) )
for split in ("public", "holdout"): # holdout requires CORE_HOLDOUT_KEY or a sibling cases_plaintext.jsonl;
# skip it on contributor machines without the sealed key.
sealed = lane.holdout_cases_path_sealed()
holdout_available = (
os.environ.get("CORE_HOLDOUT_KEY") is not None
or (sealed.parent / "cases_plaintext.jsonl").exists()
)
splits = ("public", "holdout") if holdout_available else ("public",)
for split in splits:
off = run_lane(lane, version="v1", split=split, off = run_lane(lane, version="v1", split=split,
config=RuntimeConfig()).metrics config=RuntimeConfig()).metrics
on = run_lane(lane, version="v1", split=split, on = run_lane(lane, version="v1", split=split,