feat(anchor_lens): ADR-0073c — L1.3 first lenses + composer wiring
L1.3 of the anchor-lens inside-out rollout — first substantive
surface lift on the substantive axis. Two ratified non-trivial
lenses engage on cognition-pack lemmas via the alignment graph,
appending [lens(<id>):<mode>] annotations to the existing
pack-grounded surface.
Two ratified lenses
grc_logos_v1 (Greek substrate)
primary_substrate : "grc"
semantic_domain_preferences: ["logos.episteme.systematic_knowledge"]
cognitive_mode_label : "systematic"
Engages on en "knowledge" via grc-core-cog-021 (ἐπιστήμη) →
en-core-cog-007 alignment edge.
he_logos_v1 (Hebrew substrate)
primary_substrate : "he"
semantic_domain_preferences: ["logos.aletheia.verity"]
cognitive_mode_label : "covenant-verity"
Engages on en "truth" via he-core-cog-002 (אמת) →
en-core-cog-002 alignment edge.
Both ratified under method anchor_lens_lifts_proposition.
Engagement rule (single)
1. Resolve en_lemma → entry_id (cognition pack).
2. For each substrate pack matching lens.primary_substrate, load
alignment.jsonl; find edges where target_id == entry_id.
3. For each such substrate lemma, if any atom in its
semantic_domains ∈ lens.semantic_domain_preferences → engage.
4. No match → None (no annotation; byte-identical surface).
The pivot is shared semantic_domain atoms surfaced via the
alignment graph — exactly the language-neutral commitment from
ADR-0073. Engagement never touches non-English surface text;
entry_ids and atom strings only.
Surface lift
no-lens : "Knowledge is X. pack-grounded (en_core_cognition_v1)."
lens-on : "Knowledge is X. pack-grounded (en_core_cognition_v1) [lens(grc_logos_v1):systematic]."
Annotation between existing provenance and trailing period.
Both metadata fields are ASCII-bounded ≤64 chars at the loader
level, so the annotation can never carry non-ASCII.
Scope deliberately narrow
L1.3 wiring restricted to pack_grounded_surface /
build_pack_surface_candidate (DEFINITION/RECALL only). Other
composers (COMPARISON / CORRECTION / PROCEDURE / NARRATIVE /
EXAMPLE / CAUSE / VERIFICATION) accept the anchor_lens kwarg via
forward-compat default UNANCHORED but do not yet consume it.
L1.3b or later broadens to those intent shapes.
Ratify gate widening
Non-null lenses must:
- have primary_substrate ∈ {grc, he, en}
- have a non-empty cognitive_mode_label
- every preferred atom must exist in at least one lemma of the
named substrate (trust boundary: operators cannot ship a lens
pointing at atoms not on disk).
Method: anchor_lens_lifts_proposition. Null lenses still ratify
under byte_identity_null_lift (L1.2 method).
Seam allow-list widening
Truth-path modules (cognition / trace / pipeline / intent /
propagation / vault / algebra) still refused. Composer-side
imports from chat/pack_grounding.py now permitted — the same way
ADR-0069's R2 widened the register seam.
New invariants pinned (3)
tests/test_anchor_lens_engagement_unit.py (14 tests) — resolver
returns mode label only on intended substrate × en lemma pair;
case-insensitive; engagement None under null lens; synthetic
lens with unmatched atom returns None; annotation is pure ASCII.
tests/test_anchor_lens_lifts_proposition.py (17 tests) — grc
engages on knowledge only, he engages on truth only,
cross-lens isolation, three-way distinctness, replay determinism
per (lens × prompt), register-tour seam holds within each lens
scope (orthogonality CI-pinned, parametrized over 4 lens
choices).
tests/test_anchor_lens_no_glyph_leak.py (5 tests) — hard
block-scoped gate: Greek (U+0370..03FF, U+1F00..1FFF), Hebrew
(U+0590..05FF), Syriac, Arabic. Stylistic punctuation
(em-dash etc.) explicitly allowed; em-dash predates L1.3 by a
wide margin and is not a substrate-leak risk. Tested per-lens
across every cognition case + direct lens-metadata ASCII check.
Lane evidence
74 anchor-lens tests pass (37 from L1.2 + 37 new).
python -m core.cli eval cognition → public 100/100/91.7/100
byte-identical (lens=None / default_unanchored_v1).
core demo register-tour --json → all_claims_supported: True
(R5 seam still holds; L1.3 doesn't perturb presentation axis).
Full lane: 2706 passed / 4 skipped / 1 pre-existing failure
(+37 over L1.2's 2669; the one failure remains
test_all_preamble_explains_combined_run, unrelated).
Files
packs/anchor_lens/grc_logos_v1.json NEW
packs/anchor_lens/grc_logos_v1.mastery_report.json NEW
packs/anchor_lens/he_logos_v1.json NEW
packs/anchor_lens/he_logos_v1.mastery_report.json NEW
scripts/ratify_anchor_lens_packs.py EDIT
LENS_IDS adds grc_logos_v1 / he_logos_v1; gate widened.
chat/pack_grounding.py EDIT
_resolve_anchor_lens_mode, _maybe_append_anchor_lens_annotation,
_substrate_lexicon_by_entry_id, _en_lemma_to_entry_id.
build_pack_surface_candidate + pack_grounded_surface gain
anchor_lens kwarg (default UNANCHORED).
chat/runtime.py EDIT
Thread self.anchor_lens into pack_grounded_surface() call.
tests/test_anchor_lens_pack_seam.py EDIT
Doc-comment updated for L1.3 allow-list.
tests/test_anchor_lens_* NEW (3 files)
docs/decisions/ADR-0073c-anchor-lens-composer-wiring.md NEW
This commit is contained in:
parent
9b1b63b253
commit
b35bec6465
12 changed files with 1027 additions and 28 deletions
|
|
@ -43,10 +43,21 @@ from chat.pack_resolver import (
|
||||||
mounted_lemmas,
|
mounted_lemmas,
|
||||||
resolve_lemma,
|
resolve_lemma,
|
||||||
)
|
)
|
||||||
|
from packs.anchor_lens.loader import AnchorLens, UNANCHORED
|
||||||
from packs.register.loader import RegisterPack, UNREGISTERED
|
from packs.register.loader import RegisterPack, UNREGISTERED
|
||||||
|
|
||||||
PACK_ID: str = "en_core_cognition_v1"
|
PACK_ID: str = "en_core_cognition_v1"
|
||||||
|
|
||||||
|
# ADR-0073c — substrate → mounted pack ids for anchor-lens engagement.
|
||||||
|
# Cognition-tier packs are the primary L1.3 substrate. Micro packs are
|
||||||
|
# included as a defensive fallback for the few distinct lemmas they
|
||||||
|
# carry; the engagement path early-exits once an atom-match is found.
|
||||||
|
_ANCHOR_LENS_SUBSTRATE_PACK_IDS: dict[str, tuple[str, ...]] = {
|
||||||
|
"grc": ("grc_logos_cognition_v1", "grc_logos_micro_v1"),
|
||||||
|
"he": ("he_core_cognition_v1", "he_logos_micro_v1"),
|
||||||
|
"en": (PACK_ID,),
|
||||||
|
}
|
||||||
|
|
||||||
_PACK_LEXICON_PATH = (
|
_PACK_LEXICON_PATH = (
|
||||||
Path(__file__).resolve().parent.parent
|
Path(__file__).resolve().parent.parent
|
||||||
/ "language_packs"
|
/ "language_packs"
|
||||||
|
|
@ -182,11 +193,155 @@ def _resolve_disclosure_domain_count(
|
||||||
return n
|
return n
|
||||||
|
|
||||||
|
|
||||||
|
@lru_cache(maxsize=8)
|
||||||
|
def _substrate_lexicon_by_entry_id(pack_id: str) -> dict[str, tuple[str, ...]]:
|
||||||
|
"""Map ``entry_id -> semantic_domains`` for a substrate pack.
|
||||||
|
|
||||||
|
Cached for the process lifetime — ratified packs are immutable.
|
||||||
|
Returns an empty dict when the pack is unavailable.
|
||||||
|
"""
|
||||||
|
lexicon_path = (
|
||||||
|
Path(__file__).resolve().parent.parent
|
||||||
|
/ "language_packs"
|
||||||
|
/ "data"
|
||||||
|
/ pack_id
|
||||||
|
/ "lexicon.jsonl"
|
||||||
|
)
|
||||||
|
if not lexicon_path.is_file():
|
||||||
|
return {}
|
||||||
|
out: dict[str, tuple[str, ...]] = {}
|
||||||
|
for line in lexicon_path.read_text(encoding="utf-8").splitlines():
|
||||||
|
line = line.strip()
|
||||||
|
if not line:
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
entry = json.loads(line)
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
continue
|
||||||
|
entry_id = entry.get("entry_id")
|
||||||
|
if not entry_id:
|
||||||
|
continue
|
||||||
|
out[str(entry_id)] = tuple(entry.get("semantic_domains", ()))
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
@lru_cache(maxsize=1)
|
||||||
|
def _en_lemma_to_entry_id() -> dict[str, str]:
|
||||||
|
"""Map ``en lemma -> entry_id`` for the cognition pack.
|
||||||
|
|
||||||
|
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:
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
def _resolve_anchor_lens_mode(
|
||||||
|
en_lemma: str, anchor_lens: AnchorLens,
|
||||||
|
) -> str | None:
|
||||||
|
"""Return the lens's ``cognitive_mode_label`` if it engages on ``en_lemma``.
|
||||||
|
|
||||||
|
Engagement rule (single):
|
||||||
|
1. Resolve ``en_lemma`` to its entry_id in the cognition pack.
|
||||||
|
2. Walk the alignment graph(s) of every substrate pack matching
|
||||||
|
``anchor_lens.primary_substrate`` and find substrate lemmas
|
||||||
|
whose edges target this en entry_id.
|
||||||
|
3. For each such substrate lemma, check whether its
|
||||||
|
``semantic_domains`` contains any atom from
|
||||||
|
``anchor_lens.semantic_domain_preferences``. First match wins.
|
||||||
|
|
||||||
|
Returns ``None`` when:
|
||||||
|
* ``anchor_lens.is_null_lens()`` (the unanchored sentinel and
|
||||||
|
``default_unanchored_v1`` both early-exit here)
|
||||||
|
* ``primary_substrate`` is ``"none"`` or has no mounted packs
|
||||||
|
* the en lemma is not in the cognition pack
|
||||||
|
* no substrate lemma aligned to this en lemma carries a
|
||||||
|
preferred atom
|
||||||
|
|
||||||
|
The function never reads non-ASCII surface text — it pivots on
|
||||||
|
entry_ids and atom strings only. Glyph-leak is structurally
|
||||||
|
impossible from this engagement path.
|
||||||
|
|
||||||
|
Lazy import of :func:`alignment.graph.load_alignment` keeps the
|
||||||
|
alignment subsystem out of cold-import paths.
|
||||||
|
"""
|
||||||
|
if anchor_lens.is_null_lens() or not anchor_lens.semantic_domain_preferences:
|
||||||
|
return None
|
||||||
|
substrate = anchor_lens.primary_substrate
|
||||||
|
if substrate == "none":
|
||||||
|
return None
|
||||||
|
substrate_packs = _ANCHOR_LENS_SUBSTRATE_PACK_IDS.get(substrate, ())
|
||||||
|
if not substrate_packs:
|
||||||
|
return None
|
||||||
|
en_entry_id = _en_lemma_to_entry_id().get(en_lemma.strip().lower())
|
||||||
|
if not en_entry_id:
|
||||||
|
return None
|
||||||
|
from alignment.graph import load_alignment
|
||||||
|
|
||||||
|
preferred = set(anchor_lens.semantic_domain_preferences)
|
||||||
|
for pack_id in substrate_packs:
|
||||||
|
graph = load_alignment(pack_id)
|
||||||
|
if len(graph) == 0:
|
||||||
|
continue
|
||||||
|
substrate_index = _substrate_lexicon_by_entry_id(pack_id)
|
||||||
|
for edge in graph.edges:
|
||||||
|
if edge.target_id != en_entry_id:
|
||||||
|
continue
|
||||||
|
source_atoms = substrate_index.get(edge.source_id, ())
|
||||||
|
if not source_atoms:
|
||||||
|
continue
|
||||||
|
if any(atom in preferred for atom in source_atoms):
|
||||||
|
return anchor_lens.cognitive_mode_label
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _maybe_append_anchor_lens_annotation(
|
||||||
|
surface: str, en_lemma: str, anchor_lens: AnchorLens,
|
||||||
|
) -> str:
|
||||||
|
"""Append ``[lens({lens_id}):{mode_label}]`` when lens engages.
|
||||||
|
|
||||||
|
Annotation goes between the existing trailing period and the end of
|
||||||
|
string, e.g.:
|
||||||
|
|
||||||
|
"...pack-grounded (en_core_cognition_v1)."
|
||||||
|
→
|
||||||
|
"...pack-grounded (en_core_cognition_v1) [lens(grc_logos_v1):systematic]."
|
||||||
|
|
||||||
|
Surface without a trailing period gets the annotation suffixed
|
||||||
|
directly. No-op when the lens does not engage.
|
||||||
|
|
||||||
|
Audit invariant: the annotation is pure ASCII (lens_id and mode
|
||||||
|
label both bounded to 64 ASCII chars by the loader).
|
||||||
|
"""
|
||||||
|
mode = _resolve_anchor_lens_mode(en_lemma, anchor_lens)
|
||||||
|
if mode is None:
|
||||||
|
return surface
|
||||||
|
annotation = f"[lens({anchor_lens.lens_id}):{mode}]"
|
||||||
|
if surface.endswith("."):
|
||||||
|
return f"{surface[:-1]} {annotation}."
|
||||||
|
return f"{surface} {annotation}"
|
||||||
|
|
||||||
|
|
||||||
def build_pack_surface_candidate(
|
def build_pack_surface_candidate(
|
||||||
lemma: str,
|
lemma: str,
|
||||||
pack_ids: tuple[str, ...] = DEFAULT_RESOLVABLE_PACK_IDS,
|
pack_ids: tuple[str, ...] = DEFAULT_RESOLVABLE_PACK_IDS,
|
||||||
*,
|
*,
|
||||||
register: RegisterPack = UNREGISTERED,
|
register: RegisterPack = UNREGISTERED,
|
||||||
|
anchor_lens: AnchorLens = UNANCHORED,
|
||||||
):
|
):
|
||||||
"""Return a :class:`PackSurfaceCandidate` for *lemma*, or ``None``.
|
"""Return a :class:`PackSurfaceCandidate` for *lemma*, or ``None``.
|
||||||
|
|
||||||
|
|
@ -239,6 +394,12 @@ def build_pack_surface_candidate(
|
||||||
f"{_frame_gloss(key, gloss_pos, gloss_text)} "
|
f"{_frame_gloss(key, gloss_pos, gloss_text)} "
|
||||||
f"pack-grounded ({resolved_pack_id})."
|
f"pack-grounded ({resolved_pack_id})."
|
||||||
)
|
)
|
||||||
|
# ADR-0073c — anchor-lens annotation when lens engages on
|
||||||
|
# this en lemma via the substrate alignment graph. No-op
|
||||||
|
# under UNANCHORED / default_unanchored_v1 (null-lift).
|
||||||
|
surface = _maybe_append_anchor_lens_annotation(
|
||||||
|
surface, key, anchor_lens,
|
||||||
|
)
|
||||||
return PackSurfaceCandidate(
|
return PackSurfaceCandidate(
|
||||||
surface=surface,
|
surface=surface,
|
||||||
grounding_source="pack",
|
grounding_source="pack",
|
||||||
|
|
@ -261,6 +422,12 @@ def build_pack_surface_candidate(
|
||||||
f"{key} — pack-grounded ({resolved_pack_id}): {head}. "
|
f"{key} — pack-grounded ({resolved_pack_id}): {head}. "
|
||||||
f"No session evidence yet."
|
f"No session evidence yet."
|
||||||
)
|
)
|
||||||
|
# ADR-0073c — anchor-lens annotation appended after the trailing
|
||||||
|
# period of the disclosure surface. No-op under UNANCHORED /
|
||||||
|
# default_unanchored_v1 (null-lift).
|
||||||
|
surface = _maybe_append_anchor_lens_annotation(
|
||||||
|
surface, key, anchor_lens,
|
||||||
|
)
|
||||||
return PackSurfaceCandidate(
|
return PackSurfaceCandidate(
|
||||||
surface=surface,
|
surface=surface,
|
||||||
grounding_source="pack",
|
grounding_source="pack",
|
||||||
|
|
@ -279,6 +446,7 @@ def pack_grounded_surface(
|
||||||
pack_ids: tuple[str, ...] = DEFAULT_RESOLVABLE_PACK_IDS,
|
pack_ids: tuple[str, ...] = DEFAULT_RESOLVABLE_PACK_IDS,
|
||||||
*,
|
*,
|
||||||
register: RegisterPack = UNREGISTERED,
|
register: RegisterPack = UNREGISTERED,
|
||||||
|
anchor_lens: AnchorLens = UNANCHORED,
|
||||||
) -> str | None:
|
) -> str | None:
|
||||||
"""Return a deterministic pack-grounded surface for *lemma*, or ``None``.
|
"""Return a deterministic pack-grounded surface for *lemma*, or ``None``.
|
||||||
|
|
||||||
|
|
@ -302,7 +470,9 @@ def pack_grounded_surface(
|
||||||
|
|
||||||
Returns ``None`` when the lemma is empty or doesn't resolve.
|
Returns ``None`` when the lemma is empty or doesn't resolve.
|
||||||
"""
|
"""
|
||||||
candidate = build_pack_surface_candidate(lemma, pack_ids, register=register)
|
candidate = build_pack_surface_candidate(
|
||||||
|
lemma, pack_ids, register=register, anchor_lens=anchor_lens,
|
||||||
|
)
|
||||||
return candidate.surface if candidate is not None else None
|
return candidate.surface if candidate is not None else None
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -752,7 +752,11 @@ class ChatRuntime:
|
||||||
lemma = (intent.subject or "").strip()
|
lemma = (intent.subject or "").strip()
|
||||||
if not lemma:
|
if not lemma:
|
||||||
return None
|
return None
|
||||||
surface = pack_grounded_surface(lemma, register=self.register_pack)
|
surface = pack_grounded_surface(
|
||||||
|
lemma,
|
||||||
|
register=self.register_pack,
|
||||||
|
anchor_lens=self.anchor_lens,
|
||||||
|
)
|
||||||
if surface is not None:
|
if surface is not None:
|
||||||
return (surface, "pack")
|
return (surface, "pack")
|
||||||
oov_lemma = (intent.subject or "").strip()
|
oov_lemma = (intent.subject or "").strip()
|
||||||
|
|
|
||||||
315
docs/decisions/ADR-0073c-anchor-lens-composer-wiring.md
Normal file
315
docs/decisions/ADR-0073c-anchor-lens-composer-wiring.md
Normal file
|
|
@ -0,0 +1,315 @@
|
||||||
|
# ADR-0073c — First non-trivial lenses + composer wiring (Plan Phase L1.3)
|
||||||
|
|
||||||
|
**Status:** Accepted
|
||||||
|
**Date:** 2026-05-19
|
||||||
|
**Ratified:** 2026-05-19
|
||||||
|
**Author:** Shay
|
||||||
|
**Phase:** Plan Phase L1.3 (first non-trivial lenses + composer wiring)
|
||||||
|
**Parent:** [ADR-0073](./ADR-0073-anchor-lens-substrate.md) (umbrella)
|
||||||
|
**Builds on:** [ADR-0073a](./ADR-0073a-anchor-lens-content-phase.md) (substrate content),
|
||||||
|
[ADR-0073b](./ADR-0073b-anchor-lens-class-loader.md) (class + loader)
|
||||||
|
**Pattern:** mirrors ADR-0070 (terse_v1 — first non-trivial register)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
L1.2 landed the architectural plumbing (AnchorLens class + loader +
|
||||||
|
unanchored sentinel + RuntimeConfig threading) with strict null-lift
|
||||||
|
discipline — no composer reads the lens, every lane is byte-identical
|
||||||
|
under `default_unanchored_v1`. L1.3 now ships the **first non-trivial
|
||||||
|
lenses** and the composer wiring that consumes them.
|
||||||
|
|
||||||
|
The architectural orthogonality claim becomes load-bearing at L1.3:
|
||||||
|
|
||||||
|
* `register-tour`: per prompt, fixing lens, varying register → trace_hash CONSTANT.
|
||||||
|
* `anchor-lens-tour` (L1.4): per prompt, fixing register, varying lens → trace_hash DISTINCT.
|
||||||
|
|
||||||
|
Both must hold. L1.3 lands the substantive surface lift that makes
|
||||||
|
the second claim true; L1.4 packages the demo that asserts it.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
### L1.3 wiring scope (deliberately narrow)
|
||||||
|
|
||||||
|
Composer wiring is restricted to **DEFINITION/RECALL via
|
||||||
|
`pack_grounded_surface` on the English cognition pack**. Other
|
||||||
|
composers (COMPARISON, CORRECTION, PROCEDURE, NARRATIVE, EXAMPLE,
|
||||||
|
CAUSE, VERIFICATION) accept the `anchor_lens` kwarg but do not yet
|
||||||
|
consume it.
|
||||||
|
|
||||||
|
Rationale:
|
||||||
|
|
||||||
|
* The English cognition pack is the cognition lane's load-bearing
|
||||||
|
corpus and the demo target for the L1.4 anchor-lens-tour.
|
||||||
|
* DEFINITION/RECALL is the simplest intent shape — one subject lemma,
|
||||||
|
one composed sentence — so the engagement logic is observable
|
||||||
|
end-to-end without entangling cross-pack chain traversal.
|
||||||
|
* COMPARISON/CORRECTION/PROCEDURE need richer engagement semantics
|
||||||
|
(two-lemma cross product / dialogue context / verb phrases). Those
|
||||||
|
are deferred to L1.3b or later, mirroring how register's R3 shipped
|
||||||
|
one knob before R4 broadened.
|
||||||
|
|
||||||
|
### Engagement criteria (single rule)
|
||||||
|
|
||||||
|
Given an English lemma `en_lemma` resolving to entry id `en_id` in
|
||||||
|
the cognition pack:
|
||||||
|
|
||||||
|
1. If `lens.is_null_lens()` or `lens.primary_substrate == "none"`
|
||||||
|
⇒ no engagement.
|
||||||
|
2. Load `alignment.jsonl` for substrate packs matching
|
||||||
|
`lens.primary_substrate` (e.g. `grc_logos_cognition_v1` for
|
||||||
|
`substrate="grc"`).
|
||||||
|
3. Find substrate lemmas whose alignment edges target `en_id`.
|
||||||
|
4. For each such substrate lemma, check whether its
|
||||||
|
`semantic_domains` contains any atom from
|
||||||
|
`lens.semantic_domain_preferences`.
|
||||||
|
5. First match wins. Lens engages; the composer emits
|
||||||
|
`cognitive_mode_label`.
|
||||||
|
|
||||||
|
The pivot is **shared `semantic_domains` atoms surfaced via the
|
||||||
|
alignment graph**, exactly the language-neutral commitment from
|
||||||
|
ADR-0073. No transliteration tables, no lemma-string lookups, no
|
||||||
|
non-English glyphs in the engagement path.
|
||||||
|
|
||||||
|
### Surface lift
|
||||||
|
|
||||||
|
The pack-grounded surface gains an annotation between the existing
|
||||||
|
provenance tag and the terminating period:
|
||||||
|
|
||||||
|
```
|
||||||
|
no-lens: "Knowledge is justified understanding ... pack-grounded (en_core_cognition_v1)."
|
||||||
|
lens-on: "Knowledge is justified understanding ... pack-grounded (en_core_cognition_v1) [lens(grc_logos_v1):systematic]."
|
||||||
|
```
|
||||||
|
|
||||||
|
The annotation carries both `lens_id` and `cognitive_mode_label` so
|
||||||
|
audit consumers can answer "which lens fired with which mode" without
|
||||||
|
re-deriving from telemetry. The bracket-prefix-suffix shape keeps
|
||||||
|
the annotation parseable; the surface remains pure ASCII (the L1.3
|
||||||
|
hard gate forbids non-ASCII characters at the user surface
|
||||||
|
regardless of substrate).
|
||||||
|
|
||||||
|
### First two ratified lenses
|
||||||
|
|
||||||
|
**`grc_logos_v1`** — primary substrate Greek; pivots on ἐπιστήμη to
|
||||||
|
distinguish systematic from experiential knowledge.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"lens_id": "grc_logos_v1",
|
||||||
|
"primary_substrate": "grc",
|
||||||
|
"semantic_domain_preferences": ["logos.episteme.systematic_knowledge"],
|
||||||
|
"cognitive_mode_label": "systematic"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Engagement target: en lemma `knowledge` (en-core-cog-007). The grc
|
||||||
|
cognition pack's `grc-core-cog-021` (ἐπιστήμη) carries the
|
||||||
|
preferred atom and is bound to en-007 via the
|
||||||
|
`cross_lang.logos.episteme.en_collapse` alignment edge added at
|
||||||
|
ADR-0073a.
|
||||||
|
|
||||||
|
**`he_logos_v1`** — primary substrate Hebrew; pivots on אמת
|
||||||
|
(`logos.aletheia.verity`) to render truth as covenant-grounded
|
||||||
|
verification.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"lens_id": "he_logos_v1",
|
||||||
|
"primary_substrate": "he",
|
||||||
|
"semantic_domain_preferences": ["logos.aletheia.verity"],
|
||||||
|
"cognitive_mode_label": "covenant-verity"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Engagement target: en lemma `truth` (en-core-cog-002). The he
|
||||||
|
cognition pack's `he-core-cog-002` (אמת) carries the preferred atom
|
||||||
|
and is bound to en-002 via the `cross_lang.logos.aletheia.en`
|
||||||
|
alignment edge added at ADR-0073a.
|
||||||
|
|
||||||
|
Both lenses are ratified via `scripts/ratify_anchor_lens_packs.py`
|
||||||
|
with the L1.3-widened gate: any lens whose preferences contain an
|
||||||
|
atom existing in at least one substrate pack's lemma is ratifiable
|
||||||
|
under method `anchor_lens_lifts_proposition`. Null lenses keep
|
||||||
|
ratifying under `byte_identity_null_lift`.
|
||||||
|
|
||||||
|
### Ratification-gate widening
|
||||||
|
|
||||||
|
`scripts/ratify_anchor_lens_packs.py` gains a non-null branch:
|
||||||
|
|
||||||
|
* Null lens (substrate=="none", empty prefs, empty label) ⇒
|
||||||
|
`byte_identity_null_lift` (L1.2 method).
|
||||||
|
* Non-null lens ⇒ verifies that every preferred atom appears in at
|
||||||
|
least one substrate-pack lemma's `semantic_domains` (so the lens
|
||||||
|
has a real pivot to land on) AND `cognitive_mode_label` is
|
||||||
|
non-empty AND `primary_substrate ∈ {grc, he, en}`. Method:
|
||||||
|
`anchor_lens_lifts_proposition`.
|
||||||
|
|
||||||
|
Bypass paths are unchanged (`CORE_ALLOW_UNRATIFIED_ANCHOR_LENS=1`).
|
||||||
|
|
||||||
|
### Seam test widening
|
||||||
|
|
||||||
|
`tests/test_anchor_lens_pack_seam.py` adds `chat/pack_grounding.py`
|
||||||
|
(and any other composer L1.3 touches) to the **allowed** import set
|
||||||
|
— the same way ADR-0069 widened the register seam at R2. Truth-path
|
||||||
|
modules stay anchor-lens-free.
|
||||||
|
|
||||||
|
### Runtime threading
|
||||||
|
|
||||||
|
`chat/runtime.py` already exposes `self.anchor_lens` (L1.2). L1.3
|
||||||
|
threads it into `pack_grounded_surface(...)` at every call site in
|
||||||
|
`runtime.py` exactly as `register=self.register_pack` is threaded
|
||||||
|
today. Other composers receive `anchor_lens=self.anchor_lens` for
|
||||||
|
forward-compat but no behavior change yet.
|
||||||
|
|
||||||
|
### Invariants pinned at L1.3
|
||||||
|
|
||||||
|
```
|
||||||
|
anchor_lens_byte_identity_null_lift (L1.2) — preserved
|
||||||
|
register_invariant_grounding (R3) — preserved
|
||||||
|
seeded_variation_replay_equivalence (R4) — preserved
|
||||||
|
register-tour seam (R5) — preserved
|
||||||
|
|
||||||
|
anchor_lens_lifts_proposition (NEW):
|
||||||
|
For every cognition case in {knowledge_define, truth_*}:
|
||||||
|
surface(grc_logos_v1) ≠ surface(unanchored)
|
||||||
|
surface(he_logos_v1) ≠ surface(unanchored)
|
||||||
|
trace_hash differs across {unanchored, grc_logos_v1, he_logos_v1}
|
||||||
|
Pinned by tests/test_anchor_lens_lifts_proposition.py.
|
||||||
|
|
||||||
|
anchor_lens_no_glyph_leak (NEW — hard gate):
|
||||||
|
ChatResponse.surface contains only ASCII characters regardless of
|
||||||
|
loaded lens. Tested across {unanchored, grc_logos_v1, he_logos_v1}
|
||||||
|
× every cognition case. Pinned by tests/test_anchor_lens_no_glyph_leak.py.
|
||||||
|
```
|
||||||
|
|
||||||
|
The no-glyph-leak gate is **load-bearing**. ADR-0073's substrate
|
||||||
|
commitment says English compound phrasing at the user surface, never
|
||||||
|
raw Greek/Hebrew glyphs. A non-ASCII char in `ChatResponse.surface`
|
||||||
|
under any lens fails the lane immediately.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Files
|
||||||
|
|
||||||
|
```
|
||||||
|
packs/anchor_lens/grc_logos_v1.json NEW
|
||||||
|
packs/anchor_lens/grc_logos_v1.mastery_report.json NEW
|
||||||
|
packs/anchor_lens/he_logos_v1.json NEW
|
||||||
|
packs/anchor_lens/he_logos_v1.mastery_report.json NEW
|
||||||
|
|
||||||
|
packs/anchor_lens/loader.py EDIT
|
||||||
|
- widen ratification (no schema change, just gate logic)
|
||||||
|
|
||||||
|
scripts/ratify_anchor_lens_packs.py EDIT
|
||||||
|
- LENS_IDS adds grc_logos_v1 / he_logos_v1
|
||||||
|
- widen gate to accept non-null lenses
|
||||||
|
|
||||||
|
chat/pack_grounding.py EDIT
|
||||||
|
- _resolve_anchor_lens_mode(en_lemma, lens) → str | None
|
||||||
|
- build_pack_surface_candidate() gains anchor_lens kwarg
|
||||||
|
- pack_grounded_surface() gains anchor_lens kwarg
|
||||||
|
- surface format gains lens annotation when engaged
|
||||||
|
|
||||||
|
chat/runtime.py EDIT
|
||||||
|
- thread self.anchor_lens into pack_grounded_surface() call sites
|
||||||
|
|
||||||
|
tests/test_anchor_lens_pack_seam.py EDIT
|
||||||
|
- widen allow-list to include chat/pack_grounding.py
|
||||||
|
|
||||||
|
tests/test_anchor_lens_lifts_proposition.py NEW
|
||||||
|
- lens engagement, surface lift, trace_hash divergence
|
||||||
|
|
||||||
|
tests/test_anchor_lens_no_glyph_leak.py NEW
|
||||||
|
- ASCII-only surface across all lenses × all cognition cases
|
||||||
|
|
||||||
|
tests/test_anchor_lens_engagement_unit.py NEW
|
||||||
|
- _resolve_anchor_lens_mode unit coverage
|
||||||
|
|
||||||
|
docs/decisions/ADR-0073c-anchor-lens-composer-wiring.md NEW (this file)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
### Capability unlocked at L1.3
|
||||||
|
|
||||||
|
Composer produces structurally different surfaces from different
|
||||||
|
conceptual substrates, deterministically, with audit-traceable
|
||||||
|
provenance. The proposition that English-default would render as
|
||||||
|
"Knowledge is justified understanding..." becomes
|
||||||
|
"...understanding... [lens(grc_logos_v1):systematic]." under the
|
||||||
|
Greek-anchored lens. Trace_hash moves with it.
|
||||||
|
|
||||||
|
### Cognition lane
|
||||||
|
|
||||||
|
* `default_unanchored_v1` byte-identical (null-lift invariant
|
||||||
|
preserved).
|
||||||
|
* `grc_logos_v1` and `he_logos_v1` deliberately move the lane's
|
||||||
|
outputs. L1.3 does NOT update the public-split cognition gate
|
||||||
|
numbers — the cognition eval continues to run against the
|
||||||
|
unanchored default.
|
||||||
|
|
||||||
|
### Backwards compatibility
|
||||||
|
|
||||||
|
* `pack_grounded_surface()` gains a keyword-only kwarg
|
||||||
|
`anchor_lens=UNANCHORED`. Positional-arg callers unaffected.
|
||||||
|
* Surface format change is additive: the lens annotation only
|
||||||
|
appears when a non-null lens engages. Without engagement, the
|
||||||
|
surface is byte-identical to pre-L1.3.
|
||||||
|
|
||||||
|
### Performance
|
||||||
|
|
||||||
|
L1.3 adds one alignment-graph lookup + one substrate-lemma lookup per
|
||||||
|
pack-grounded turn under a non-null lens. Under the unanchored
|
||||||
|
default (the production path until operators opt in) zero overhead.
|
||||||
|
The alignment graph + substrate lexicon are cached via `lru_cache`,
|
||||||
|
same pattern as the existing pack index.
|
||||||
|
|
||||||
|
### Trust boundaries
|
||||||
|
|
||||||
|
* Lens preferences are operator-authored content. The L1.3 ratify
|
||||||
|
gate verifies every preferred atom exists in at least one
|
||||||
|
substrate-pack lemma — operators cannot ship a lens that
|
||||||
|
references atoms not on disk.
|
||||||
|
* `anchor_lens_no_glyph_leak` is a hard gate: any non-ASCII at the
|
||||||
|
user surface fails the lane. This protects the layperson surface
|
||||||
|
contract regardless of substrate.
|
||||||
|
* No new mutation surface; lens packs continue to be proposal-only
|
||||||
|
for runtime, ratifiable only via the operator-only ratify script.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Verification
|
||||||
|
|
||||||
|
```
|
||||||
|
python -m pytest tests/test_anchor_lens_engagement_unit.py -q N passed
|
||||||
|
python -m pytest tests/test_anchor_lens_lifts_proposition.py -q N passed
|
||||||
|
python -m pytest tests/test_anchor_lens_no_glyph_leak.py -q N passed
|
||||||
|
python -m pytest tests/test_anchor_lens_null_lift.py -q 4 passed
|
||||||
|
(unchanged)
|
||||||
|
python -m pytest tests/test_anchor_lens_pack_loader.py -q 24 passed
|
||||||
|
(unchanged)
|
||||||
|
python -m pytest tests/test_anchor_lens_pack_seam.py -q N passed
|
||||||
|
(allow-list
|
||||||
|
widened
|
||||||
|
for composer)
|
||||||
|
|
||||||
|
Curated lanes (must remain green):
|
||||||
|
smoke / cognition / teaching / packs / runtime / algebra
|
||||||
|
|
||||||
|
Cognition eval byte-identical under default_unanchored_v1:
|
||||||
|
public 100 / 100 / 91.7 / 100
|
||||||
|
|
||||||
|
core demo register-tour exit 0
|
||||||
|
(R5 seam
|
||||||
|
still holds)
|
||||||
|
```
|
||||||
|
|
||||||
|
The orthogonality between the two tours is the load-bearing
|
||||||
|
architectural commitment. L1.4 packages `anchor-lens-tour` as the
|
||||||
|
falsifiable demo for the substantive axis; L1.3 makes that demo
|
||||||
|
possible by delivering the surface lift the demo will assert.
|
||||||
13
packs/anchor_lens/grc_logos_v1.json
Normal file
13
packs/anchor_lens/grc_logos_v1.json
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
{
|
||||||
|
"cognitive_mode_label": "systematic",
|
||||||
|
"description": "Greek-substrate anchor lens. Pivots English 'knowledge' onto \u1f10\u03c0\u03b9\u03c3\u03c4\u03ae\u03bc\u03b7's logos.episteme.systematic_knowledge atom via the grc cognition pack's alignment edge to en-core-cog-007. Renders surface as English compound 'systematic'. See ADR-0073c.",
|
||||||
|
"display_name": "Greek logos (systematic knowledge)",
|
||||||
|
"lens_id": "grc_logos_v1",
|
||||||
|
"mastery_report_sha256": "46ab6a43f1ce0e161e9185910b969025104ded4a3c6c6211998a307c8d070882",
|
||||||
|
"primary_substrate": "grc",
|
||||||
|
"schema_version": "1.0.0",
|
||||||
|
"semantic_domain_preferences": [
|
||||||
|
"logos.episteme.systematic_knowledge"
|
||||||
|
],
|
||||||
|
"version": "1.0.0"
|
||||||
|
}
|
||||||
20
packs/anchor_lens/grc_logos_v1.mastery_report.json
Normal file
20
packs/anchor_lens/grc_logos_v1.mastery_report.json
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"evidence": {
|
||||||
|
"atoms_anchored_in_substrate": [
|
||||||
|
"logos.episteme.systematic_knowledge"
|
||||||
|
],
|
||||||
|
"cognitive_mode_label": "systematic",
|
||||||
|
"cognitive_mode_label_empty": false,
|
||||||
|
"primary_substrate": "grc",
|
||||||
|
"semantic_domain_preferences_count": 1,
|
||||||
|
"semantic_domain_preferences_empty": false
|
||||||
|
},
|
||||||
|
"failure_reasons": [],
|
||||||
|
"issued_at": "2026-05-19T00:00:00Z",
|
||||||
|
"lens_id": "grc_logos_v1",
|
||||||
|
"pack_source_sha256": "03b1a12a0ff9caf18be0a4b54760c333949b052b946441062b21827fdbbc7132",
|
||||||
|
"ratification_method": "anchor_lens_lifts_proposition",
|
||||||
|
"ratified": true,
|
||||||
|
"report_sha256": "46ab6a43f1ce0e161e9185910b969025104ded4a3c6c6211998a307c8d070882",
|
||||||
|
"schema_version": "1.0.0"
|
||||||
|
}
|
||||||
13
packs/anchor_lens/he_logos_v1.json
Normal file
13
packs/anchor_lens/he_logos_v1.json
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
{
|
||||||
|
"cognitive_mode_label": "covenant-verity",
|
||||||
|
"description": "Hebrew-substrate anchor lens. Pivots English 'truth' onto \u05d0\u05de\u05ea's logos.aletheia.verity atom via the he cognition pack's alignment edge to en-core-cog-002. Renders surface as English compound 'covenant-verity'. See ADR-0073c.",
|
||||||
|
"display_name": "Hebrew logos (covenant verity)",
|
||||||
|
"lens_id": "he_logos_v1",
|
||||||
|
"mastery_report_sha256": "aad4cad4a4ff1970c8a81f02bca5a77c58659103b008c87a518c6d6c095e1cc6",
|
||||||
|
"primary_substrate": "he",
|
||||||
|
"schema_version": "1.0.0",
|
||||||
|
"semantic_domain_preferences": [
|
||||||
|
"logos.aletheia.verity"
|
||||||
|
],
|
||||||
|
"version": "1.0.0"
|
||||||
|
}
|
||||||
20
packs/anchor_lens/he_logos_v1.mastery_report.json
Normal file
20
packs/anchor_lens/he_logos_v1.mastery_report.json
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"evidence": {
|
||||||
|
"atoms_anchored_in_substrate": [
|
||||||
|
"logos.aletheia.verity"
|
||||||
|
],
|
||||||
|
"cognitive_mode_label": "covenant-verity",
|
||||||
|
"cognitive_mode_label_empty": false,
|
||||||
|
"primary_substrate": "he",
|
||||||
|
"semantic_domain_preferences_count": 1,
|
||||||
|
"semantic_domain_preferences_empty": false
|
||||||
|
},
|
||||||
|
"failure_reasons": [],
|
||||||
|
"issued_at": "2026-05-19T00:00:00Z",
|
||||||
|
"lens_id": "he_logos_v1",
|
||||||
|
"pack_source_sha256": "8cc30f6f7e923f09870a34e0ecf199eca6cb34c28b35e96f9d747d12cceaa953",
|
||||||
|
"ratification_method": "anchor_lens_lifts_proposition",
|
||||||
|
"ratified": true,
|
||||||
|
"report_sha256": "aad4cad4a4ff1970c8a81f02bca5a77c58659103b008c87a518c6d6c095e1cc6",
|
||||||
|
"schema_version": "1.0.0"
|
||||||
|
}
|
||||||
|
|
@ -48,8 +48,39 @@ PACKS_DIR = Path(__file__).resolve().parents[1] / "packs" / "anchor_lens"
|
||||||
ISSUED_AT = "2026-05-19T00:00:00Z"
|
ISSUED_AT = "2026-05-19T00:00:00Z"
|
||||||
LENS_IDS: tuple[str, ...] = (
|
LENS_IDS: tuple[str, ...] = (
|
||||||
"default_unanchored_v1",
|
"default_unanchored_v1",
|
||||||
|
"grc_logos_v1",
|
||||||
|
"he_logos_v1",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
_SUBSTRATE_PACK_IDS: dict[str, tuple[str, ...]] = {
|
||||||
|
"grc": ("grc_logos_cognition_v1", "grc_logos_micro_v1"),
|
||||||
|
"he": ("he_core_cognition_v1", "he_logos_micro_v1"),
|
||||||
|
"en": ("en_core_cognition_v1",),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _atom_exists_in_substrate(atom: str, substrate: str) -> bool:
|
||||||
|
"""True iff some lemma in any pack matching ``substrate`` carries ``atom``."""
|
||||||
|
import json as _json
|
||||||
|
from pathlib import Path as _Path
|
||||||
|
|
||||||
|
data_dir = _Path(__file__).resolve().parents[1] / "language_packs" / "data"
|
||||||
|
for pack_id in _SUBSTRATE_PACK_IDS.get(substrate, ()):
|
||||||
|
lexicon_path = data_dir / pack_id / "lexicon.jsonl"
|
||||||
|
if not lexicon_path.is_file():
|
||||||
|
continue
|
||||||
|
for line in lexicon_path.read_text(encoding="utf-8").splitlines():
|
||||||
|
line = line.strip()
|
||||||
|
if not line:
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
entry = _json.loads(line)
|
||||||
|
except _json.JSONDecodeError:
|
||||||
|
continue
|
||||||
|
if atom in entry.get("semantic_domains", []):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def _canonical_pack_bytes_for_hashing(pack: dict) -> bytes:
|
def _canonical_pack_bytes_for_hashing(pack: dict) -> bytes:
|
||||||
"""Serialize the pack with ``mastery_report_sha256`` blanked."""
|
"""Serialize the pack with ``mastery_report_sha256`` blanked."""
|
||||||
|
|
@ -90,17 +121,60 @@ def _ratify_one(pack_path: Path, lens_id: str) -> tuple[dict, dict[str, Any]]:
|
||||||
|
|
||||||
pack_source_sha = _pack_source_sha(pack)
|
pack_source_sha = _pack_source_sha(pack)
|
||||||
|
|
||||||
# L1.2 gate: only null lenses are ratifiable here. L1.3 will
|
# L1.3 gate: null lenses ratify under byte_identity_null_lift;
|
||||||
# widen this to cover non-null lenses with a different
|
# non-null lenses ratify under anchor_lens_lifts_proposition, with
|
||||||
# ratification method.
|
# the precondition that every preferred atom exists in at least one
|
||||||
if not _is_null_lens(pack):
|
# lemma of the named substrate. This is the trust boundary
|
||||||
raise SystemExit(
|
# preventing operators from shipping a lens that references
|
||||||
f"L1.2 gate refuses {lens_id!r}: not a null lens. "
|
# atoms not on disk.
|
||||||
"primary_substrate must be 'none', semantic_domain_preferences "
|
if _is_null_lens(pack):
|
||||||
"must be empty, and cognitive_mode_label must be empty."
|
ratification_method = "byte_identity_null_lift"
|
||||||
)
|
evidence: dict[str, Any] = {
|
||||||
|
"primary_substrate": str(pack.get("primary_substrate", "")),
|
||||||
ratification_method = "byte_identity_null_lift"
|
"semantic_domain_preferences_empty": True,
|
||||||
|
"semantic_domain_preferences_count": 0,
|
||||||
|
"cognitive_mode_label_empty": True,
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
substrate = str(pack.get("primary_substrate", ""))
|
||||||
|
if substrate not in ("grc", "he", "en"):
|
||||||
|
raise SystemExit(
|
||||||
|
f"L1.3 gate refuses {lens_id!r}: non-null lens "
|
||||||
|
f"primary_substrate must be one of "
|
||||||
|
f"{{'grc','he','en'}}, got {substrate!r}."
|
||||||
|
)
|
||||||
|
label = str(pack.get("cognitive_mode_label", ""))
|
||||||
|
if not label:
|
||||||
|
raise SystemExit(
|
||||||
|
f"L1.3 gate refuses {lens_id!r}: non-null lens "
|
||||||
|
"cognitive_mode_label must be non-empty."
|
||||||
|
)
|
||||||
|
prefs = pack.get("semantic_domain_preferences", []) or []
|
||||||
|
if not isinstance(prefs, list) or not prefs:
|
||||||
|
raise SystemExit(
|
||||||
|
f"L1.3 gate refuses {lens_id!r}: non-null lens "
|
||||||
|
"semantic_domain_preferences must be non-empty."
|
||||||
|
)
|
||||||
|
atoms_anchored: list[str] = []
|
||||||
|
for atom in prefs:
|
||||||
|
if _atom_exists_in_substrate(atom, substrate):
|
||||||
|
atoms_anchored.append(atom)
|
||||||
|
else:
|
||||||
|
raise SystemExit(
|
||||||
|
f"L1.3 gate refuses {lens_id!r}: preferred atom "
|
||||||
|
f"{atom!r} does not appear in any "
|
||||||
|
f"{substrate!r} substrate lemma. Lenses must "
|
||||||
|
"point at atoms that exist on disk."
|
||||||
|
)
|
||||||
|
ratification_method = "anchor_lens_lifts_proposition"
|
||||||
|
evidence = {
|
||||||
|
"primary_substrate": substrate,
|
||||||
|
"semantic_domain_preferences_empty": False,
|
||||||
|
"semantic_domain_preferences_count": len(prefs),
|
||||||
|
"cognitive_mode_label_empty": False,
|
||||||
|
"cognitive_mode_label": label,
|
||||||
|
"atoms_anchored_in_substrate": atoms_anchored,
|
||||||
|
}
|
||||||
|
|
||||||
report: dict[str, Any] = {
|
report: dict[str, Any] = {
|
||||||
"lens_id": lens_id,
|
"lens_id": lens_id,
|
||||||
|
|
@ -109,12 +183,7 @@ def _ratify_one(pack_path: Path, lens_id: str) -> tuple[dict, dict[str, Any]]:
|
||||||
"pack_source_sha256": pack_source_sha,
|
"pack_source_sha256": pack_source_sha,
|
||||||
"ratification_method": ratification_method,
|
"ratification_method": ratification_method,
|
||||||
"ratified": True,
|
"ratified": True,
|
||||||
"evidence": {
|
"evidence": evidence,
|
||||||
"primary_substrate": str(pack.get("primary_substrate", "")),
|
|
||||||
"semantic_domain_preferences_empty": True,
|
|
||||||
"semantic_domain_preferences_count": 0,
|
|
||||||
"cognitive_mode_label_empty": True,
|
|
||||||
},
|
|
||||||
"failure_reasons": [],
|
"failure_reasons": [],
|
||||||
"report_sha256": "",
|
"report_sha256": "",
|
||||||
}
|
}
|
||||||
|
|
|
||||||
114
tests/test_anchor_lens_engagement_unit.py
Normal file
114
tests/test_anchor_lens_engagement_unit.py
Normal file
|
|
@ -0,0 +1,114 @@
|
||||||
|
"""Unit coverage for the anchor-lens engagement resolver (ADR-0073c).
|
||||||
|
|
||||||
|
Tests :func:`chat.pack_grounding._resolve_anchor_lens_mode` and
|
||||||
|
:func:`chat.pack_grounding._maybe_append_anchor_lens_annotation` in
|
||||||
|
isolation, separate from the full chat() round-trip.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from chat.pack_grounding import (
|
||||||
|
_maybe_append_anchor_lens_annotation,
|
||||||
|
_resolve_anchor_lens_mode,
|
||||||
|
)
|
||||||
|
from packs.anchor_lens import AnchorLens, UNANCHORED, load_anchor_lens
|
||||||
|
|
||||||
|
|
||||||
|
def test_unanchored_sentinel_returns_none_for_every_lemma():
|
||||||
|
for lemma in ("knowledge", "truth", "light", "word"):
|
||||||
|
assert _resolve_anchor_lens_mode(lemma, UNANCHORED) is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_default_unanchored_pack_returns_none_for_every_lemma():
|
||||||
|
lens = load_anchor_lens("default_unanchored_v1")
|
||||||
|
for lemma in ("knowledge", "truth", "light", "word"):
|
||||||
|
assert _resolve_anchor_lens_mode(lemma, lens) is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_grc_logos_v1_engages_on_knowledge_only():
|
||||||
|
lens = load_anchor_lens("grc_logos_v1")
|
||||||
|
assert _resolve_anchor_lens_mode("knowledge", lens) == "systematic"
|
||||||
|
|
||||||
|
|
||||||
|
def test_grc_logos_v1_does_not_engage_on_truth():
|
||||||
|
lens = load_anchor_lens("grc_logos_v1")
|
||||||
|
assert _resolve_anchor_lens_mode("truth", lens) is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_grc_logos_v1_does_not_engage_on_unaligned_lemma():
|
||||||
|
lens = load_anchor_lens("grc_logos_v1")
|
||||||
|
assert _resolve_anchor_lens_mode("polarity", lens) is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_he_logos_v1_engages_on_truth_only():
|
||||||
|
lens = load_anchor_lens("he_logos_v1")
|
||||||
|
assert _resolve_anchor_lens_mode("truth", lens) == "covenant-verity"
|
||||||
|
|
||||||
|
|
||||||
|
def test_he_logos_v1_does_not_engage_on_knowledge():
|
||||||
|
lens = load_anchor_lens("he_logos_v1")
|
||||||
|
assert _resolve_anchor_lens_mode("knowledge", lens) is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_engagement_case_insensitive():
|
||||||
|
lens = load_anchor_lens("grc_logos_v1")
|
||||||
|
assert _resolve_anchor_lens_mode("KNOWLEDGE", lens) == "systematic"
|
||||||
|
assert _resolve_anchor_lens_mode(" knowledge ", lens) == "systematic"
|
||||||
|
|
||||||
|
|
||||||
|
def test_annotation_appended_before_trailing_period():
|
||||||
|
surface = "Knowledge is X. pack-grounded (en_core_cognition_v1)."
|
||||||
|
lens = load_anchor_lens("grc_logos_v1")
|
||||||
|
out = _maybe_append_anchor_lens_annotation(surface, "knowledge", lens)
|
||||||
|
assert out == (
|
||||||
|
"Knowledge is X. pack-grounded (en_core_cognition_v1) "
|
||||||
|
"[lens(grc_logos_v1):systematic]."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_annotation_appended_without_trailing_period():
|
||||||
|
surface = "Knowledge is X. pack-grounded (en_core_cognition_v1)"
|
||||||
|
lens = load_anchor_lens("grc_logos_v1")
|
||||||
|
out = _maybe_append_anchor_lens_annotation(surface, "knowledge", lens)
|
||||||
|
assert out == (
|
||||||
|
"Knowledge is X. pack-grounded (en_core_cognition_v1) "
|
||||||
|
"[lens(grc_logos_v1):systematic]"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_annotation_noop_when_lens_does_not_engage():
|
||||||
|
surface = "Truth is X. pack-grounded (en_core_cognition_v1)."
|
||||||
|
lens = load_anchor_lens("grc_logos_v1")
|
||||||
|
assert _maybe_append_anchor_lens_annotation(surface, "truth", lens) == surface
|
||||||
|
|
||||||
|
|
||||||
|
def test_annotation_noop_under_unanchored():
|
||||||
|
surface = "Knowledge is X. pack-grounded (en_core_cognition_v1)."
|
||||||
|
out = _maybe_append_anchor_lens_annotation(surface, "knowledge", UNANCHORED)
|
||||||
|
assert out == surface
|
||||||
|
|
||||||
|
|
||||||
|
def test_annotation_is_pure_ascii():
|
||||||
|
"""Hard glyph-leak gate at the helper level: annotation must
|
||||||
|
never carry non-ASCII even when the lens substrate is grc/he."""
|
||||||
|
surface = "Truth is X. pack-grounded (en_core_cognition_v1)."
|
||||||
|
lens = load_anchor_lens("he_logos_v1")
|
||||||
|
out = _maybe_append_anchor_lens_annotation(surface, "truth", lens)
|
||||||
|
out.encode("ascii") # raises if any non-ASCII slipped through
|
||||||
|
|
||||||
|
|
||||||
|
def test_synthetic_lens_with_atom_not_in_substrate_returns_none():
|
||||||
|
"""A lens with preferences that don't match any substrate lemma
|
||||||
|
is structurally engagement-incapable; the resolver returns None
|
||||||
|
even if the lens is otherwise well-formed."""
|
||||||
|
fake = AnchorLens(
|
||||||
|
lens_id="synthetic_v1",
|
||||||
|
version="0.0.0",
|
||||||
|
description="test only",
|
||||||
|
display_name="Synthetic",
|
||||||
|
primary_substrate="grc",
|
||||||
|
semantic_domain_preferences=("logos.nonexistent.atom",),
|
||||||
|
cognitive_mode_label="phantom",
|
||||||
|
)
|
||||||
|
for lemma in ("knowledge", "truth", "light", "word"):
|
||||||
|
assert _resolve_anchor_lens_mode(lemma, fake) is None
|
||||||
161
tests/test_anchor_lens_lifts_proposition.py
Normal file
161
tests/test_anchor_lens_lifts_proposition.py
Normal file
|
|
@ -0,0 +1,161 @@
|
||||||
|
"""anchor_lens_lifts_proposition — load-bearing L1.3 invariant (ADR-0073c).
|
||||||
|
|
||||||
|
When a non-null lens engages on a cognition-pack lemma:
|
||||||
|
- the surface differs from the unanchored baseline
|
||||||
|
- the surface carries the lens annotation [lens(<id>):<mode>]
|
||||||
|
- the trace_hash differs (the proposition has changed)
|
||||||
|
|
||||||
|
The complementary null-lift invariant (L1.2) continues to hold for the
|
||||||
|
unanchored sentinel and default_unanchored_v1 — pinned by
|
||||||
|
``tests/test_anchor_lens_null_lift.py``.
|
||||||
|
|
||||||
|
Cognition prompts used:
|
||||||
|
"What is knowledge?" — grc_logos_v1 engages, he_logos_v1 does not
|
||||||
|
"What is truth?" — he_logos_v1 engages, grc_logos_v1 does not
|
||||||
|
|
||||||
|
Together they exercise both lenses and confirm engagement is
|
||||||
|
substrate-scoped, not blanket.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from chat.runtime import ChatRuntime
|
||||||
|
from core.cognition.pipeline import CognitiveTurnPipeline
|
||||||
|
from core.config import RuntimeConfig
|
||||||
|
|
||||||
|
|
||||||
|
_KNOWLEDGE_PROMPT = "What is knowledge?"
|
||||||
|
_TRUTH_PROMPT = "What is truth?"
|
||||||
|
|
||||||
|
|
||||||
|
def _run(lens_id: str | None, prompt: str):
|
||||||
|
rt = ChatRuntime(config=RuntimeConfig(anchor_lens_id=lens_id))
|
||||||
|
pipeline = CognitiveTurnPipeline(runtime=rt)
|
||||||
|
result = pipeline.run(prompt)
|
||||||
|
response = rt.turn_log[-1]
|
||||||
|
return result, response
|
||||||
|
|
||||||
|
|
||||||
|
# ---------- grc_logos_v1 engages on "knowledge" ----------
|
||||||
|
|
||||||
|
|
||||||
|
def test_grc_logos_v1_surface_differs_from_unanchored_on_knowledge():
|
||||||
|
_, base = _run(None, _KNOWLEDGE_PROMPT)
|
||||||
|
_, lensed = _run("grc_logos_v1", _KNOWLEDGE_PROMPT)
|
||||||
|
assert base.surface != lensed.surface
|
||||||
|
|
||||||
|
|
||||||
|
def test_grc_logos_v1_surface_carries_annotation_on_knowledge():
|
||||||
|
_, lensed = _run("grc_logos_v1", _KNOWLEDGE_PROMPT)
|
||||||
|
assert "[lens(grc_logos_v1):systematic]" in lensed.surface
|
||||||
|
|
||||||
|
|
||||||
|
def test_grc_logos_v1_trace_hash_differs_from_unanchored_on_knowledge():
|
||||||
|
base_result, _ = _run(None, _KNOWLEDGE_PROMPT)
|
||||||
|
lensed_result, _ = _run("grc_logos_v1", _KNOWLEDGE_PROMPT)
|
||||||
|
assert base_result.trace_hash != lensed_result.trace_hash
|
||||||
|
|
||||||
|
|
||||||
|
# ---------- he_logos_v1 engages on "truth" ----------
|
||||||
|
|
||||||
|
|
||||||
|
def test_he_logos_v1_surface_differs_from_unanchored_on_truth():
|
||||||
|
_, base = _run(None, _TRUTH_PROMPT)
|
||||||
|
_, lensed = _run("he_logos_v1", _TRUTH_PROMPT)
|
||||||
|
assert base.surface != lensed.surface
|
||||||
|
|
||||||
|
|
||||||
|
def test_he_logos_v1_surface_carries_annotation_on_truth():
|
||||||
|
_, lensed = _run("he_logos_v1", _TRUTH_PROMPT)
|
||||||
|
assert "[lens(he_logos_v1):covenant-verity]" in lensed.surface
|
||||||
|
|
||||||
|
|
||||||
|
def test_he_logos_v1_trace_hash_differs_from_unanchored_on_truth():
|
||||||
|
base_result, _ = _run(None, _TRUTH_PROMPT)
|
||||||
|
lensed_result, _ = _run("he_logos_v1", _TRUTH_PROMPT)
|
||||||
|
assert base_result.trace_hash != lensed_result.trace_hash
|
||||||
|
|
||||||
|
|
||||||
|
# ---------- engagement is substrate-scoped (cross-lens isolation) ----------
|
||||||
|
|
||||||
|
|
||||||
|
def test_grc_logos_v1_does_not_engage_on_truth():
|
||||||
|
"""grc lens does not touch truth — surface byte-identical to baseline."""
|
||||||
|
_, base = _run(None, _TRUTH_PROMPT)
|
||||||
|
_, grc = _run("grc_logos_v1", _TRUTH_PROMPT)
|
||||||
|
assert base.surface == grc.surface
|
||||||
|
assert "lens(" not in grc.surface
|
||||||
|
|
||||||
|
|
||||||
|
def test_he_logos_v1_does_not_engage_on_knowledge():
|
||||||
|
"""he lens does not touch knowledge — surface byte-identical to baseline."""
|
||||||
|
_, base = _run(None, _KNOWLEDGE_PROMPT)
|
||||||
|
_, he = _run("he_logos_v1", _KNOWLEDGE_PROMPT)
|
||||||
|
assert base.surface == he.surface
|
||||||
|
assert "lens(" not in he.surface
|
||||||
|
|
||||||
|
|
||||||
|
# ---------- three-way trace_hash divergence (the load-bearing claim) ----------
|
||||||
|
|
||||||
|
|
||||||
|
def test_three_way_surface_distinct_on_knowledge():
|
||||||
|
"""{unanchored, grc, he} produce two distinct surfaces on knowledge
|
||||||
|
(grc engages, he does not so he == unanchored)."""
|
||||||
|
_, base = _run(None, _KNOWLEDGE_PROMPT)
|
||||||
|
_, grc = _run("grc_logos_v1", _KNOWLEDGE_PROMPT)
|
||||||
|
_, he = _run("he_logos_v1", _KNOWLEDGE_PROMPT)
|
||||||
|
distinct = {base.surface, grc.surface, he.surface}
|
||||||
|
assert len(distinct) == 2 # grc differs; he matches base
|
||||||
|
|
||||||
|
|
||||||
|
def test_three_way_surface_distinct_on_truth():
|
||||||
|
"""Symmetric: he engages on truth, grc does not."""
|
||||||
|
_, base = _run(None, _TRUTH_PROMPT)
|
||||||
|
_, grc = _run("grc_logos_v1", _TRUTH_PROMPT)
|
||||||
|
_, he = _run("he_logos_v1", _TRUTH_PROMPT)
|
||||||
|
distinct = {base.surface, grc.surface, he.surface}
|
||||||
|
assert len(distinct) == 2 # he differs; grc matches base
|
||||||
|
|
||||||
|
|
||||||
|
# ---------- replay determinism (same lens × same input → same output) ----------
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("lens_id", ["grc_logos_v1", "he_logos_v1"])
|
||||||
|
@pytest.mark.parametrize("prompt", [_KNOWLEDGE_PROMPT, _TRUTH_PROMPT])
|
||||||
|
def test_lens_engagement_is_deterministic(lens_id: str, prompt: str):
|
||||||
|
a_result, a = _run(lens_id, prompt)
|
||||||
|
b_result, b = _run(lens_id, prompt)
|
||||||
|
assert a.surface == b.surface
|
||||||
|
assert a_result.trace_hash == b_result.trace_hash
|
||||||
|
|
||||||
|
|
||||||
|
# ---------- register-tour seam still holds under each lens ----------
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("lens_id", [None, "default_unanchored_v1",
|
||||||
|
"grc_logos_v1", "he_logos_v1"])
|
||||||
|
def test_register_seam_within_lens_holds(lens_id: str | None):
|
||||||
|
"""Per ADR-0073 orthogonality: within a fixed lens, varying register
|
||||||
|
keeps trace_hash constant. L1.3 must preserve R5's register-tour
|
||||||
|
invariant inside every lens scope."""
|
||||||
|
pipeline_neutral = CognitiveTurnPipeline(
|
||||||
|
runtime=ChatRuntime(config=RuntimeConfig(
|
||||||
|
register_pack_id="default_neutral_v1",
|
||||||
|
anchor_lens_id=lens_id,
|
||||||
|
))
|
||||||
|
)
|
||||||
|
pipeline_convivial = CognitiveTurnPipeline(
|
||||||
|
runtime=ChatRuntime(config=RuntimeConfig(
|
||||||
|
register_pack_id="convivial_v1",
|
||||||
|
anchor_lens_id=lens_id,
|
||||||
|
))
|
||||||
|
)
|
||||||
|
n = pipeline_neutral.run(_KNOWLEDGE_PROMPT)
|
||||||
|
c = pipeline_convivial.run(_KNOWLEDGE_PROMPT)
|
||||||
|
assert n.trace_hash == c.trace_hash, (
|
||||||
|
f"register-tour seam broken under lens={lens_id!r}: "
|
||||||
|
f"neutral trace_hash {n.trace_hash[:12]}... != "
|
||||||
|
f"convivial trace_hash {c.trace_hash[:12]}..."
|
||||||
|
)
|
||||||
104
tests/test_anchor_lens_no_glyph_leak.py
Normal file
104
tests/test_anchor_lens_no_glyph_leak.py
Normal file
|
|
@ -0,0 +1,104 @@
|
||||||
|
"""anchor_lens_no_glyph_leak — hard substrate-glyph gate (ADR-0073c).
|
||||||
|
|
||||||
|
ADR-0073's substrate commitment: anchor lens renders English compound
|
||||||
|
phrasing at the user surface, never raw non-English **substrate
|
||||||
|
glyphs** (Greek / Hebrew / Coptic / Aramaic letters). This test pins
|
||||||
|
that as a falsifiable invariant — a single substrate-block character
|
||||||
|
in ``ChatResponse.surface`` under any lens fails the lane.
|
||||||
|
|
||||||
|
Stylistic punctuation such as em-dash (U+2014) is permitted; it
|
||||||
|
pre-dates L1.3 and is unrelated to the substrate-leak risk this
|
||||||
|
invariant protects against. The forbidden zones are:
|
||||||
|
|
||||||
|
- U+0370..U+03FF Greek and Coptic
|
||||||
|
- U+1F00..U+1FFF Greek Extended
|
||||||
|
- U+0590..U+05FF Hebrew
|
||||||
|
- U+0700..U+074F Syriac (forward-looking)
|
||||||
|
- U+0600..U+06FF Arabic (forward-looking)
|
||||||
|
|
||||||
|
Scope: every cognition lane case × {unanchored, default_unanchored_v1,
|
||||||
|
grc_logos_v1, he_logos_v1}. Forbidden block leaks fail immediately.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from core.config import RuntimeConfig
|
||||||
|
from evals.run_cognition_eval import load_cases, run_eval
|
||||||
|
|
||||||
|
|
||||||
|
_LENS_IDS_TO_TEST = (
|
||||||
|
None,
|
||||||
|
"default_unanchored_v1",
|
||||||
|
"grc_logos_v1",
|
||||||
|
"he_logos_v1",
|
||||||
|
)
|
||||||
|
|
||||||
|
#: Forbidden Unicode blocks: substrate letter scripts that anchor lens
|
||||||
|
#: must not leak. Each tuple is ``(start_codepoint, end_codepoint,
|
||||||
|
#: block_label)``. Inclusive on both ends.
|
||||||
|
_FORBIDDEN_BLOCKS: tuple[tuple[int, int, str], ...] = (
|
||||||
|
(0x0370, 0x03FF, "Greek and Coptic"),
|
||||||
|
(0x1F00, 0x1FFF, "Greek Extended"),
|
||||||
|
(0x0590, 0x05FF, "Hebrew"),
|
||||||
|
(0x0700, 0x074F, "Syriac"),
|
||||||
|
(0x0600, 0x06FF, "Arabic"),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _substrate_glyph_violations(surface: str) -> list[tuple[int, str, str]]:
|
||||||
|
"""Return ``[(pos, char, block_label), ...]`` for every substrate
|
||||||
|
glyph in *surface*. Empty list means clean."""
|
||||||
|
out: list[tuple[int, str, str]] = []
|
||||||
|
for i, ch in enumerate(surface):
|
||||||
|
cp = ord(ch)
|
||||||
|
for start, end, label in _FORBIDDEN_BLOCKS:
|
||||||
|
if start <= cp <= end:
|
||||||
|
out.append((i, ch, label))
|
||||||
|
break
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="module")
|
||||||
|
def cases():
|
||||||
|
return load_cases()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("lens_id", _LENS_IDS_TO_TEST)
|
||||||
|
def test_cognition_lane_surfaces_free_of_substrate_glyphs(cases, lens_id):
|
||||||
|
report = run_eval(cases, config=RuntimeConfig(anchor_lens_id=lens_id))
|
||||||
|
leaks: list[str] = []
|
||||||
|
for case in report.cases:
|
||||||
|
if not case.surface:
|
||||||
|
continue
|
||||||
|
violations = _substrate_glyph_violations(case.surface)
|
||||||
|
if violations:
|
||||||
|
for pos, ch, block in violations:
|
||||||
|
leaks.append(
|
||||||
|
f" case={case.case_id} "
|
||||||
|
f"substrate_glyph={ch!r} (block={block}) at pos {pos} "
|
||||||
|
f"surface={case.surface!r}"
|
||||||
|
)
|
||||||
|
assert not leaks, (
|
||||||
|
f"anchor_lens_no_glyph_leak violated under lens={lens_id!r}.\n"
|
||||||
|
"ChatResponse.surface MUST NOT contain substrate-script glyphs "
|
||||||
|
"(Greek / Hebrew / etc.) regardless of loaded lens "
|
||||||
|
"(ADR-0073 surface contract). Offending cases:\n"
|
||||||
|
+ "\n".join(leaks)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_lens_annotation_is_ascii_directly():
|
||||||
|
"""Independent of the cognition lane: the lens metadata itself
|
||||||
|
(lens_id, cognitive_mode_label) must be pure ASCII so the
|
||||||
|
annotation can never carry non-ASCII even if a future composer
|
||||||
|
forgets to ASCII-check before emit."""
|
||||||
|
from packs.anchor_lens import load_anchor_lens
|
||||||
|
|
||||||
|
for lens_id in ("default_unanchored_v1", "grc_logos_v1", "he_logos_v1"):
|
||||||
|
lens = load_anchor_lens(lens_id)
|
||||||
|
lens.lens_id.encode("ascii")
|
||||||
|
lens.cognitive_mode_label.encode("ascii")
|
||||||
|
for atom in lens.semantic_domain_preferences:
|
||||||
|
atom.encode("ascii")
|
||||||
|
|
@ -5,18 +5,14 @@ Pins the load-bearing commitment of ADR-0073 / ADR-0073b:
|
||||||
Anchor lens is a composer-side concept, not a property of the
|
Anchor lens is a composer-side concept, not a property of the
|
||||||
proposition graph or trace hash function.
|
proposition graph or trace hash function.
|
||||||
|
|
||||||
At L1.2 the lens is loaded by ``chat/runtime.py`` and stored on the
|
At L1.3 the lens is loaded by ``chat/runtime.py`` and consumed by
|
||||||
runtime, but no other file imports it. The truth-path modules
|
``chat/pack_grounding.py`` (the composer-side allowlist). The
|
||||||
(cognition / trace / pipeline / intent classification / propagation /
|
truth-path modules (cognition / trace / pipeline / intent
|
||||||
vault / algebra) must NOT import ``packs.anchor_lens``.
|
classification / propagation / vault / algebra) must NOT import
|
||||||
|
``packs.anchor_lens``.
|
||||||
|
|
||||||
This test fails the moment anchor lens leaks into the truth path.
|
This test fails the moment anchor lens leaks into the truth path.
|
||||||
|
|
||||||
L1.3 will widen the allow-list to include ``chat/pack_grounding.py``
|
|
||||||
(and any other composer it wires through) at the same time it adds
|
|
||||||
composer behaviour — exactly the way the register seam was widened at
|
|
||||||
R2. Truth-path purity remains absolute.
|
|
||||||
|
|
||||||
Mirror of ``tests/test_register_pack_seam.py`` for the substantive-axis
|
Mirror of ``tests/test_register_pack_seam.py`` for the substantive-axis
|
||||||
sibling.
|
sibling.
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue