Closes the surface-grounding gap isolated by ADR-0047's
characterisation. Adds the ratified cognition pack as a second
grounding source alongside the session vault.
== chat/pack_grounding.py (new) ==
Loads en_core_cognition_v1's lexicon once (cached; immutable pack)
and exposes:
pack_grounded_surface(lemma) -> str | None
Returns a deterministic, fully pack-sourced surface:
"{lemma} — pack-grounded ({pack_id}): {d1}; {d2}; {d3}. No session evidence yet."
Every visible atom is the lemma or a verbatim semantic_domains
string from the pack. No rewording, no synthesis, no LLM.
== chat/runtime.py ==
_stub_response gains optional pack_grounded_surface= parameter.
_maybe_pack_grounded_surface routes to the pack only when all four
hold: gate_source=="empty_vault", output_language=="en",
intent.tag in {DEFINITION, RECALL}, and intent.subject is a pack
lemma. Safety/ethics refusal still takes priority above this branch.
ChatResponse and TurnEvent gain grounding_source ∈ {vault,pack,none}.
Main walk path tags responses "vault".
== core/cognition/pipeline.py ==
gate_fired detection moved from string equality on the universal
disclosure to provenance:
gate_fired = response.vault_hits == 0 and response.grounding_source != "vault"
Same intent (suppress realizer template on gate-fired turns),
broader stub-path surface set.
== Characterisation (core eval cognition, 13-case public split) ==
Metric Pre Post Δ
intent_accuracy 100.0% 100.0% 0
surface_groundedness 15.4% 46.2% +30.8 pp
term_capture_rate 0.0% 33.3% +33.3 pp
versor_closure_rate 100.0% 100.0% 0
Lift is non-uniform by design: only single-lemma DEFINITION/RECALL
on pack-known English subjects engage. CAUSE/COMPARISON/VERIFICATION
and multi-word OOV subjects still return the universal disclosure —
fabricating those would violate the no-LLM-fallback doctrine.
== Tests ==
tests/test_pack_grounding.py 18 passed
tests/test_semantic_realizer_integration.py (updated) 1 stub-path test
pinned to the broader contract: surface is either universal
disclosure or pack-grounded; never the realizer template.
== Lanes ==
smoke 67 cognition 121 runtime 19 algebra 132
teaching 17 packs 6
versor_condition(F) < 1e-6 invariant unaffected (no algebra changes).
120 lines
4.3 KiB
Python
120 lines
4.3 KiB
Python
"""chat/pack_grounding.py — pack-grounded surface for cold-start DEFINITION
|
|
and RECALL intents (ADR-0048).
|
|
|
|
When the ``UnknownDomainGate`` fires with ``source="empty_vault"`` — i.e.
|
|
the runtime has no session evidence yet — the runtime would otherwise
|
|
emit the universal ``_UNKNOWN_DOMAIN_SURFACE`` disclosure on every turn,
|
|
including for terms that are explicitly compiled into the ratified
|
|
cognition pack.
|
|
|
|
This module supplies a narrow, auditable alternative: when the input's
|
|
intent is ``DEFINITION`` or ``RECALL`` AND the intent's subject lemma is
|
|
present in ``en_core_cognition_v1``, return a deterministic surface
|
|
composed from the pack lexicon's ``semantic_domains`` for that lemma,
|
|
explicitly tagged as pack-sourced.
|
|
|
|
Design constraints (matching the seven axioms):
|
|
|
|
- Geometry-first: the pack lookup is by lemma surface, but the
|
|
``semantic_domains`` were curated against the same versors the
|
|
vocabulary carries; the surface refers only to the lemma and its
|
|
curated descriptors — no synthesis, no LLM fallback.
|
|
- Reconstruction-over-storage: the surface is reconstructed from the
|
|
pack at call time; the lexicon is loaded once and cached because
|
|
ratified packs are immutable.
|
|
- Dual-correction: any lemma not in the pack returns ``None``;
|
|
callers fall through to ``_UNKNOWN_DOMAIN_SURFACE`` unchanged.
|
|
- Compilation-last: no tensors, no kernels — JSONL read and string
|
|
formatting only.
|
|
- Trust boundary: every surface produced here is explicitly tagged
|
|
``pack:en_core_cognition_v1`` so the audit contract distinguishes
|
|
pack-grounded surfaces from vault-grounded surfaces and from the
|
|
universal disclosure.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from functools import lru_cache
|
|
from pathlib import Path
|
|
|
|
PACK_ID: str = "en_core_cognition_v1"
|
|
|
|
_PACK_LEXICON_PATH = (
|
|
Path(__file__).resolve().parent.parent
|
|
/ "language_packs"
|
|
/ "data"
|
|
/ PACK_ID
|
|
/ "lexicon.jsonl"
|
|
)
|
|
|
|
|
|
@lru_cache(maxsize=1)
|
|
def _pack_index() -> dict[str, tuple[str, ...]]:
|
|
"""Load the cognition pack lexicon once and return ``{lemma: semantic_domains}``.
|
|
|
|
Ratified packs are immutable; safe to cache for the process lifetime.
|
|
Returns an empty dict if the pack is unavailable — callers must treat
|
|
a missing pack as "no pack-grounded surface available."
|
|
"""
|
|
if not _PACK_LEXICON_PATH.exists():
|
|
return {}
|
|
out: dict[str, tuple[str, ...]] = {}
|
|
for line in _PACK_LEXICON_PATH.read_text(encoding="utf-8").splitlines():
|
|
line = line.strip()
|
|
if not line:
|
|
continue
|
|
try:
|
|
entry = json.loads(line)
|
|
except json.JSONDecodeError:
|
|
continue
|
|
lemma = entry.get("lemma") or entry.get("surface")
|
|
if not lemma:
|
|
continue
|
|
domains = tuple(entry.get("semantic_domains", ()))
|
|
if domains:
|
|
out[lemma.lower()] = domains
|
|
return out
|
|
|
|
|
|
def pack_grounded_surface(lemma: str) -> str | None:
|
|
"""Return a deterministic pack-grounded surface for *lemma*, or ``None``.
|
|
|
|
The surface format is fixed:
|
|
|
|
"{lemma} — pack-grounded ({pack_id}): {d1}; {d2}; {d3}. No session evidence yet."
|
|
|
|
Only the lemma and up to three semantic_domains from the pack are
|
|
emitted; both come directly from the ratified pack lexicon, with no
|
|
rewording. The trailing disclosure is the constant trust-boundary
|
|
label that distinguishes pack-grounded surfaces from vault-grounded
|
|
surfaces (which would carry session evidence) and from the universal
|
|
"insufficient grounding" disclosure (which carries neither).
|
|
|
|
Returns ``None`` when:
|
|
- the lemma is empty or not a string,
|
|
- the pack lexicon file is unavailable,
|
|
- the lemma is not present in the pack,
|
|
- the pack entry has no ``semantic_domains``.
|
|
"""
|
|
if not lemma or not isinstance(lemma, str):
|
|
return None
|
|
key = lemma.strip().lower()
|
|
if not key:
|
|
return None
|
|
index = _pack_index()
|
|
domains = index.get(key)
|
|
if not domains:
|
|
return None
|
|
head = "; ".join(domains[:3])
|
|
return (
|
|
f"{key} — pack-grounded ({PACK_ID}): {head}. "
|
|
f"No session evidence yet."
|
|
)
|
|
|
|
|
|
def is_pack_lemma(lemma: str) -> bool:
|
|
"""Return True iff *lemma* has an entry with ``semantic_domains`` in the pack."""
|
|
if not lemma or not isinstance(lemma, str):
|
|
return False
|
|
return lemma.strip().lower() in _pack_index()
|