Phase C of the gloss feature. Lands the natural-language gloss
content that the resolver (Phase B2) and the runtime composer
(Phase B3) were prepared for. This is the user-visible payoff:
cold-start DEFINITION / RECALL prompts on pack-resident lemmas now
emit fluent grounded sentences instead of dotted-domain disclosure.
Authoring: five parallel subagents in ONE message block (a single
parallel dispatch, ~20s wall-clock vs ~95s sequential). Each
subagent received its pack's complete lemma + POS list and a strict
JSON-shape exemplar. Total returned: 326 raw gloss entries.
Assembly (this commit): the raw entries were partitioned by
lexicon-residency lookup (the resolve_gloss invariant enforced at
storage time), deduplicated within pack, sorted by lemma, written
to ``language_packs/data/<pack>/glosses.jsonl``, and each pack's
manifest received a new ``glosses_checksum`` field. 323 glosses
landed clean; 0 rejected.
Per-pack distribution:
en_core_cognition_v1 78 glosses
en_core_meta_v1 72 glosses
en_core_attitude_v1 40 glosses
en_core_temporal_v1 28 glosses
en_core_action_v1 26 glosses
en_core_quantitative_v1 24 glosses
en_core_spatial_v1 24 glosses
en_core_polarity_v1 16 glosses
en_core_causation_v1 15 glosses
Live-probe lift (fresh ChatRuntime per prompt):
BEFORE:
truth — pack-grounded (en_core_cognition_v1):
cognition.truth; logos.core; epistemic.ground.
No session evidence yet.
AFTER:
Truth is a claim or state grounded by evidence and coherent
judgment. pack-grounded (en_core_cognition_v1).
Same provenance. Same audit-trail content (the dotted domains are
still in lexicon.jsonl, the resolver can still read them, the
candidate object carries them verbatim). But the user-facing
surface is a sentence the user can actually read.
Eval-lane lift:
deterministic_fluency BEFORE AFTER
no_dotted_inventory_rate 0.3333 → 1.0000
no_provenance_only_rate 1.0000 → 1.0000 (held)
no_placeholder_rate 1.0000 → 1.0000 (held)
complete_punctuation_rate 1.0000 → 1.0000 (held)
finite_predicate_shape 1.0000 → 1.0000 (held)
surface_provenance_match 1.0000 → 1.0000 (held)
cold_start_grounding all metrics held at 1.0
warmed_session_consistency no_placeholder + telemetry_match held at 1.0
(warm_grounding_stability still 0 — separate fix)
cognition eval public 100 / 100 / 91.7 / 100 (BYTE-IDENTICAL)
cognition eval holdout 100 / 100 / 83.3 / 100 (BYTE-IDENTICAL)
The cognition eval bytes-identity holds because the eval checks
substring containment (case-insensitive after the format change).
Every lemma still appears in its fluent surface.
Hardening this commit enforces:
Lexicon-residency at storage time
tests/test_pack_glosses_content.py::test_every_gloss_lemma_is_lexicon_resident
walks every glosses.jsonl and asserts every lemma is present in
the same pack's lexicon.jsonl. Drift in glosses (an unratified
lemma sneaking in) fails the lane immediately.
Dual-checksum discipline
tests/test_pack_glosses_content.py::test_every_glossed_pack_has_matching_checksum
re-hashes glosses.jsonl bytes-on-disk and compares against the
manifest's glosses_checksum. Any tampering fails.
Immutable-lexicon invariant
tests/test_pack_glosses_content.py::test_lexicon_checksum_unchanged_by_gloss_landing
re-hashes lexicon.jsonl and compares against the manifest's
(original) checksum. Proves that adding glosses did NOT perturb
the lexicon seal.
High-freq lemma resolution
32 of the most-common conversational lemmas (truth, doubt,
fact, idea, self, true, important, now, place, make, effect,
always, ...) all resolve to a fluent surface end-to-end.
Test-suite drift this commit absorbed:
- tests/test_pack_grounding.py — three substring assertions
updated to be case-insensitive (gloss-backed surfaces capitalize
lemmas at sentence start, dotted-disclosure surfaces don't).
"No session evidence yet" assertion replaced with the
common-substring "pack-grounded" marker that BOTH forms emit.
- tests/test_pack_resolver_glosses.py — the back-compat test
pivots from en_core_cognition_v1 (now glossed) to en_minimal_v1
(deliberately unglossed). A new test pins the glossed case.
Files added:
language_packs/data/<pack>/glosses.jsonl (9 files, 323 entries)
tests/test_pack_glosses_content.py (9 contract tests)
Files modified:
language_packs/data/<pack>/manifest.json (9 files, glosses_checksum field)
chat/pack_grounding.py (lowercase "pack-grounded" tag)
tests/test_pack_grounding.py (3 substring assertions relaxed)
tests/test_pack_resolver_glosses.py (back-compat test pivoted)
Verification:
127/127 affected tests green.
9/9 new gloss-content tests green.
All three eval lanes report the lift documented above.
Cognition eval byte-identical.
175 lines
6.6 KiB
Python
175 lines
6.6 KiB
Python
"""Contract tests for the Phase C ratified glosses.
|
|
|
|
Pins:
|
|
- Every pack with a ``glosses.jsonl`` file has a matching
|
|
``glosses_checksum`` in its manifest.
|
|
- Every gloss entry references a lemma that is ratified in the
|
|
same pack's ``lexicon.jsonl`` (lexicon-residency invariant —
|
|
re-asserted from the storage layer up).
|
|
- The total ratified gloss count meets a floor (>= 300).
|
|
- At least one gloss resolves end-to-end for the most common
|
|
conversational lemmas (sanity check for the wiring + content).
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import hashlib
|
|
import json
|
|
from pathlib import Path
|
|
|
|
from chat.pack_resolver import (
|
|
DEFAULT_RESOLVABLE_PACK_IDS,
|
|
_pack_glosses_for,
|
|
_pack_lexicon_for,
|
|
clear_resolver_cache,
|
|
resolve_gloss,
|
|
)
|
|
|
|
|
|
_DATA = Path(__file__).resolve().parent.parent / "language_packs" / "data"
|
|
|
|
|
|
def _packs_with_glosses() -> list[str]:
|
|
out = []
|
|
for p in DEFAULT_RESOLVABLE_PACK_IDS:
|
|
if (_DATA / p / "glosses.jsonl").exists():
|
|
out.append(p)
|
|
return out
|
|
|
|
|
|
class TestGlossesPresent:
|
|
def test_at_least_eight_packs_ship_glosses(self) -> None:
|
|
"""Phase C seeds glosses in 9 English content packs."""
|
|
packs = _packs_with_glosses()
|
|
assert len(packs) >= 8, (
|
|
f"expected >=8 packs with glosses, got {len(packs)}: {packs}"
|
|
)
|
|
|
|
def test_total_gloss_count_floor(self) -> None:
|
|
"""The Phase C dispatch targeted ~330 glosses; this is the
|
|
regression floor."""
|
|
clear_resolver_cache()
|
|
total = sum(len(_pack_glosses_for(p)) for p in _packs_with_glosses())
|
|
assert total >= 300, f"total gloss count {total} below floor 300"
|
|
|
|
|
|
class TestManifestChecksumDiscipline:
|
|
def test_every_glossed_pack_has_matching_checksum(self) -> None:
|
|
for pack_id in _packs_with_glosses():
|
|
manifest = json.loads(
|
|
(_DATA / pack_id / "manifest.json").read_text(encoding="utf-8")
|
|
)
|
|
assert "glosses_checksum" in manifest, pack_id
|
|
declared = manifest["glosses_checksum"]
|
|
assert isinstance(declared, str) and len(declared) == 64, (pack_id, declared)
|
|
actual = hashlib.sha256(
|
|
(_DATA / pack_id / "glosses.jsonl").read_bytes()
|
|
).hexdigest()
|
|
assert actual == declared, (
|
|
f"glosses_checksum drift on {pack_id}: "
|
|
f"declared={declared[:16]}… actual={actual[:16]}…"
|
|
)
|
|
|
|
def test_lexicon_checksum_unchanged_by_gloss_landing(self) -> None:
|
|
"""Adding glosses must NOT bump the lexicon checksum. The
|
|
lexicon is immutable; only glosses_checksum changes when
|
|
glosses are added or revised."""
|
|
for pack_id in _packs_with_glosses():
|
|
manifest = json.loads(
|
|
(_DATA / pack_id / "manifest.json").read_text(encoding="utf-8")
|
|
)
|
|
actual_lex_checksum = hashlib.sha256(
|
|
(_DATA / pack_id / "lexicon.jsonl").read_bytes()
|
|
).hexdigest()
|
|
assert manifest["checksum"] == actual_lex_checksum, pack_id
|
|
|
|
|
|
class TestLexiconResidencyAcrossAllGlosses:
|
|
"""Every authored gloss must reference a lemma that exists in the
|
|
same pack's lexicon.jsonl. This is the storage-layer enforcement
|
|
of the resolve_gloss runtime invariant — any drift in glosses.jsonl
|
|
that introduces an unratified lemma fails this test."""
|
|
|
|
def test_every_gloss_lemma_is_lexicon_resident(self) -> None:
|
|
clear_resolver_cache()
|
|
for pack_id in _packs_with_glosses():
|
|
lex = _pack_lexicon_for(pack_id)
|
|
glosses = _pack_glosses_for(pack_id)
|
|
for lemma in glosses:
|
|
assert lemma in lex, (
|
|
f"pack {pack_id} ships a gloss for {lemma!r} but the "
|
|
f"lemma is not in its lexicon.jsonl"
|
|
)
|
|
|
|
|
|
class TestEndToEndSmoke:
|
|
"""Resolve known high-frequency conversational lemmas through
|
|
resolve_gloss and assert the runtime composes a fluent surface."""
|
|
|
|
HIGH_FREQ_LEMMAS = (
|
|
# cognition
|
|
"truth", "knowledge", "memory", "evidence", "thought",
|
|
# meta
|
|
"doubt", "fact", "idea", "self", "believe", "know",
|
|
# attitude
|
|
"true", "good", "important", "certain", "necessary",
|
|
# temporal
|
|
"now", "moment", "future", "past", "before",
|
|
# spatial
|
|
"here", "place", "above",
|
|
# action
|
|
"make", "create", "change", "use",
|
|
# causation
|
|
"effect", "outcome",
|
|
# polarity
|
|
"always", "never", "yes",
|
|
)
|
|
|
|
def test_high_freq_lemmas_resolve_a_gloss(self) -> None:
|
|
clear_resolver_cache()
|
|
misses = []
|
|
for lemma in self.HIGH_FREQ_LEMMAS:
|
|
entry = resolve_gloss(lemma)
|
|
if entry is None:
|
|
misses.append(lemma)
|
|
assert not misses, (
|
|
f"resolve_gloss returned None for high-frequency lemmas: {misses}"
|
|
)
|
|
|
|
def test_fluent_surface_contains_lemma_case_insensitive(self) -> None:
|
|
"""End-to-end: pack_grounded_surface composes a fluent sentence
|
|
for every high-freq lemma; the lemma (lowercase) appears in the
|
|
rendered surface."""
|
|
from chat.pack_grounding import pack_grounded_surface
|
|
clear_resolver_cache()
|
|
for lemma in self.HIGH_FREQ_LEMMAS:
|
|
surface = pack_grounded_surface(lemma)
|
|
assert surface is not None, lemma
|
|
assert lemma in surface.lower(), (lemma, surface)
|
|
assert "pack-grounded" in surface, (lemma, surface)
|
|
# No dotted-domain-inventory in gloss-backed surfaces.
|
|
assert "; " not in surface, (lemma, surface)
|
|
|
|
|
|
class TestSurfaceFormatInvariants:
|
|
"""A handful of structural invariants the gloss-backed surfaces
|
|
must respect. These are what the deterministic_fluency lane
|
|
checks at scale — repeated here per-pack for tighter attribution."""
|
|
|
|
SAMPLE = ("truth", "doubt", "important", "now", "place", "make", "effect", "always")
|
|
|
|
def test_surfaces_have_terminal_punctuation(self) -> None:
|
|
from chat.pack_grounding import pack_grounded_surface
|
|
clear_resolver_cache()
|
|
for lemma in self.SAMPLE:
|
|
s = pack_grounded_surface(lemma)
|
|
assert s is not None and s.rstrip().endswith("."), (lemma, s)
|
|
|
|
def test_surfaces_contain_no_placeholders(self) -> None:
|
|
from chat.pack_grounding import pack_grounded_surface
|
|
clear_resolver_cache()
|
|
for lemma in self.SAMPLE:
|
|
s = pack_grounded_surface(lemma)
|
|
assert s is not None
|
|
for marker in ("...", "<pending>", "<prior>"):
|
|
assert marker not in s, (lemma, marker, s)
|