core/docs/decisions/ADR-0073c-anchor-lens-composer-wiring.md
Shay b35bec6465 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
2026-05-19 20:06:02 -07:00

12 KiB
Raw Permalink Blame History

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 (umbrella) Builds on: ADR-0073a (substrate content), ADR-0073b (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.

{
  "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.

{
  "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.