From 6387872051cb6190dc79ba9463373d99e28b0e01 Mon Sep 17 00:00:00 2001 From: Shay Date: Wed, 20 May 2026 10:58:07 -0700 Subject: [PATCH] =?UTF-8?q?feat(packs):=20en=5Fcollapse=5Fanchors=5Fv1=20?= =?UTF-8?q?=E2=80=94=20activate=20chesed/shalom/tzedek=20lenses=20on=20EN?= =?UTF-8?q?=20input?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ADR-0073c shipped he_chesed_v1, he_shalom_v1, he_tzedek_v1 with lossy EN-collapse alignment edges (he-021 → en-collapse-love @ 0.63, etc.) but the synthetic en-collapse-* targets didn't exist in any mounted lexicon. Result: the three lenses ratified but stayed dormant — the runtime OOV gate fired on "What is love?" / "What is peace?" / "What is justice?" before the lens engagement path got a chance. This commit adds a minimal pack whose lexicon carries exactly those three synthetic anchors: en-collapse-love lemma="love" domain=collapse_anchor.love en-collapse-peace lemma="peace" domain=collapse_anchor.peace en-collapse-justice lemma="justice" domain=collapse_anchor.justice Mounted last in DEFAULT_RESOLVABLE_PACK_IDS — cognition / relations packs win first-match on any future collision. No real content pack currently carries these lemmas (grep-confirmed) so the mount adds no collision risk. The pack-grounded surface for "What is love?" advertises its nature honestly via the pack id (en_collapse_anchors_v1) and the domain string (collapse_anchor.love) — the surface is intentionally minimal; the substantive content arrives via the lens annotation [lens(he_chesed_v1):covenant-love] / [lens(he_shalom_v1):wholeness-peace] / [lens(he_tzedek_v1):right-order]. chat/pack_grounding.py:_en_lemma_to_entry_id() now reads both en_core_cognition_v1 and en_collapse_anchors_v1, with cognition winning on lemma collision. New test file tests/test_en_collapse_anchors_v1_pack.py pins: - each anchor lemma resolves to its synthetic entry_id - collapse pack mounted last (precedence guarantee) - each of the three lenses engages on its target English prompt - baseline surface (no lens) still advertises anchor nature Validation: - Cognition eval byte-identical (100/100/91.7/100) - 160 lens/pack/resolver tests pass + 8 new - anchor-lens-tour green - register-tour green --- chat/pack_grounding.py | 51 +++++++++---- chat/pack_resolver.py | 7 ++ .../data/en_collapse_anchors_v1/lexicon.jsonl | 3 + .../data/en_collapse_anchors_v1/manifest.json | 13 ++++ tests/test_en_collapse_anchors_v1_pack.py | 74 +++++++++++++++++++ 5 files changed, 133 insertions(+), 15 deletions(-) create mode 100644 language_packs/data/en_collapse_anchors_v1/lexicon.jsonl create mode 100644 language_packs/data/en_collapse_anchors_v1/manifest.json create mode 100644 tests/test_en_collapse_anchors_v1_pack.py diff --git a/chat/pack_grounding.py b/chat/pack_grounding.py index 66d0727b..d9bb4fac 100644 --- a/chat/pack_grounding.py +++ b/chat/pack_grounding.py @@ -66,6 +66,22 @@ _PACK_LEXICON_PATH = ( / "lexicon.jsonl" ) +# ADR-0073c — synthetic English anchor lemmas for cross-lang collapse. +# Holds entry_ids like ``en-collapse-love`` so anchor-lens engagement +# (he_chesed_v1 / he_shalom_v1 / he_tzedek_v1) can resolve English +# prompts like "What is love?" to a target entry_id and walk the +# alignment graph from there. This pack is engagement-only: it is +# intentionally NOT included in ``DEFAULT_RESOLVABLE_PACK_IDS`` so the +# composer does not fabricate a pack-grounded definition for these +# lemmas — only lens-engagement reads from here. +_COLLAPSE_ANCHORS_LEXICON_PATH = ( + Path(__file__).resolve().parent.parent + / "language_packs" + / "data" + / "en_collapse_anchors_v1" + / "lexicon.jsonl" +) + @lru_cache(maxsize=1) def _pack_index() -> dict[str, tuple[str, ...]]: @@ -227,26 +243,31 @@ def _substrate_lexicon_by_entry_id(pack_id: str) -> dict[str, tuple[str, ...]]: @lru_cache(maxsize=1) def _en_lemma_to_entry_id() -> dict[str, str]: - """Map ``en lemma -> entry_id`` for the cognition pack. + """Map ``en lemma -> entry_id`` for anchor-lens engagement. + Merges the cognition pack (``en_core_cognition_v1``) with the + collapse-anchor pack (``en_collapse_anchors_v1``). Cognition entries + win on lemma collision since they carry real semantic_domains. Cached for the process lifetime — ratified packs are immutable. """ out: dict[str, str] = {} - if not _PACK_LEXICON_PATH.is_file(): - return out - for line in _PACK_LEXICON_PATH.read_text(encoding="utf-8").splitlines(): - line = line.strip() - if not line: + for path in (_COLLAPSE_ANCHORS_LEXICON_PATH, _PACK_LEXICON_PATH): + # cognition path is iterated second so it wins on lemma collision + if not path.is_file(): continue - try: - entry = json.loads(line) - except json.JSONDecodeError: - continue - lemma = entry.get("lemma") or entry.get("surface") - entry_id = entry.get("entry_id") - if not lemma or not entry_id: - continue - out[str(lemma).lower()] = str(entry_id) + for line in 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") + entry_id = entry.get("entry_id") + if not lemma or not entry_id: + continue + out[str(lemma).lower()] = str(entry_id) return out diff --git a/chat/pack_resolver.py b/chat/pack_resolver.py index e94344e1..aed28ecc 100644 --- a/chat/pack_resolver.py +++ b/chat/pack_resolver.py @@ -52,6 +52,13 @@ DEFAULT_RESOLVABLE_PACK_IDS: tuple[str, ...] = ( "en_core_polarity_v1", "en_core_relations_v1", "en_core_relations_v2", + # ADR-0073c — synthetic English anchor lemmas for cross-lang collapse. + # Mounted last so cognition / relations content packs win first-match. + # Carries "love" / "peace" / "justice" entries that exist only as + # collapse-anchor targets for the he_chesed / he_shalom / he_tzedek + # anchor lenses. Composer surfaces here are intentionally minimal — + # the substantive content lives in the lens annotation. + "en_collapse_anchors_v1", ) _PACK_ROOT = Path(__file__).resolve().parent.parent / "language_packs" / "data" diff --git a/language_packs/data/en_collapse_anchors_v1/lexicon.jsonl b/language_packs/data/en_collapse_anchors_v1/lexicon.jsonl new file mode 100644 index 00000000..4e0f5de6 --- /dev/null +++ b/language_packs/data/en_collapse_anchors_v1/lexicon.jsonl @@ -0,0 +1,3 @@ +{"entry_id":"en-collapse-love","surface":"love","lemma":"love","language":"en","pos":"NOUN","semantic_domains":["collapse_anchor.love"],"morphology_tags":["noun"],"provenance_ids":["adr-0073c:english_collapses_love_family","adr-0073c:chesed_lossy_english_engagement"]} +{"entry_id":"en-collapse-peace","surface":"peace","lemma":"peace","language":"en","pos":"NOUN","semantic_domains":["collapse_anchor.peace"],"morphology_tags":["noun"],"provenance_ids":["adr-0073c:english_collapses_peace_to_absence_of_war","adr-0073c:shalom_lossy_english_engagement"]} +{"entry_id":"en-collapse-justice","surface":"justice","lemma":"justice","language":"en","pos":"NOUN","semantic_domains":["collapse_anchor.justice"],"morphology_tags":["noun"],"provenance_ids":["adr-0073c:english_splits_to_righteousness_justice","adr-0073c:tzedek_lossy_english_engagement"]} diff --git a/language_packs/data/en_collapse_anchors_v1/manifest.json b/language_packs/data/en_collapse_anchors_v1/manifest.json new file mode 100644 index 00000000..9a05c9b3 --- /dev/null +++ b/language_packs/data/en_collapse_anchors_v1/manifest.json @@ -0,0 +1,13 @@ +{ + "pack_id": "en_collapse_anchors_v1", + "language": "en", + "role": "collapse_anchor", + "script": "Latin", + "normalization_policy": "unitize_versor", + "source_manifest": "en_collapse_anchors_v1.lexicon.jsonl", + "determinism_class": "D0", + "checksum": "bd46462611c51b93a59630085553b858dec81646e55b2864c6f040b7646d0da5", + "version": "1.0.0", + "gate_engaged": false, + "oov_policy": "passthrough" +} diff --git a/tests/test_en_collapse_anchors_v1_pack.py b/tests/test_en_collapse_anchors_v1_pack.py new file mode 100644 index 00000000..570f77b1 --- /dev/null +++ b/tests/test_en_collapse_anchors_v1_pack.py @@ -0,0 +1,74 @@ +"""Pin engagement for the en_collapse_anchors_v1 synthetic-anchor pack. + +ADR-0073c: synthetic English anchors (``love`` / ``peace`` / ``justice``) +exist only so the Hebrew covenantal lenses (``he_chesed_v1`` / +``he_shalom_v1`` / ``he_tzedek_v1``) can resolve English prompts and +walk the alignment graph to their substrate atoms. Without these +entries, the lenses ratify but stay dormant on English input. +""" + +from __future__ import annotations + +import pytest + +from chat.pack_resolver import DEFAULT_RESOLVABLE_PACK_IDS, resolve_lemma +from chat.runtime import ChatRuntime, RuntimeConfig + + +@pytest.mark.parametrize( + "lemma,expected_entry_id", + [ + ("love", "en-collapse-love"), + ("peace", "en-collapse-peace"), + ("justice", "en-collapse-justice"), + ], +) +def test_collapse_anchor_lemma_resolves(lemma: str, expected_entry_id: str): + """Each anchor lemma resolves in the collapse pack to its synthetic + entry_id — that entry_id is the engagement hook for the Hebrew + covenantal lenses' alignment edges (he-021 → en-collapse-love, etc.).""" + result = resolve_lemma(lemma) + assert result is not None + pack_id, _domains = result + assert pack_id == "en_collapse_anchors_v1" + + +def test_collapse_pack_is_mounted_last(): + """First-match-wins precedence — collapse pack must be last so the + cognition / relations / etc. content packs win on any lemma + collision. Currently no real content pack carries love/peace/justice, + but the precedence guarantee should be maintained.""" + assert DEFAULT_RESOLVABLE_PACK_IDS[-1] == "en_collapse_anchors_v1" + + +@pytest.mark.parametrize( + "lens_id,prompt,expected_mode", + [ + ("he_chesed_v1", "What is love?", "covenant-love"), + ("he_shalom_v1", "What is peace?", "wholeness-peace"), + ("he_tzedek_v1", "What is justice?", "right-order"), + ], +) +def test_hebrew_covenantal_lens_engages_via_collapse_anchor( + lens_id: str, prompt: str, expected_mode: str, +): + """End-to-end: the lens annotation appears on the surface, proving + the engagement path resolved the English lemma through the collapse + pack and walked the alignment graph to the Hebrew atom.""" + rt = ChatRuntime(config=RuntimeConfig(anchor_lens_id=lens_id)) + response = rt.chat(prompt) + annotation = f"[lens({lens_id}):{expected_mode}]" + assert annotation in response.surface + + +def test_collapse_anchor_baseline_surface_advertises_anchor_nature(): + """Without a lens engaged, the surface for ``What is love?`` should + still be honest about being a collapse-anchor entry — the pack id + and the ``collapse_anchor.*`` domain are the honesty signal.""" + rt = ChatRuntime() + response = rt.chat("What is love?") + assert response.grounding_source == "pack" + assert "en_collapse_anchors_v1" in response.surface + assert "collapse_anchor.love" in response.surface + # And no lens annotation when no lens is selected. + assert "[lens(" not in response.surface