Introduces the presentation axis as a fourth pack class (sibling to identity /
safety / ethics), orthogonal to the truth path. Same input + same packs +
same register ⇒ bit-for-bit reproducible surface; varying any of the three ⇒
genuinely different output. No stochastic sampling.
ADR-0068 (R1): RegisterPack frozen dataclass, loader, ratify script, seam test.
- default_neutral_v1 ratified as null register.
ADR-0069 (R2): realizer register parameter threaded through 9 composer entry
points; RuntimeConfig.register_pack_id; three byte-identity invariants
(A: None ≡ pre-R2 unregistered; B: None ≡ default_neutral_v1; C: trace_hash
invariant under register). Amended to default-with-lint after 167-call-site
scout: composers default to UNREGISTERED, AST lint enforces explicit
register= at runtime call sites.
ADR-0070 (R3): terse_v1 register, first non-neutral pack. realizer_overrides
schema with known-keys allow-list (disclosure_domain_count ∈ {1,2,3}).
build_pack_surface_candidate reads override with fail-soft clamp. New
invariant register_invariant_grounding asserts grounding_source +
trace_hash byte-identical across {None, neutral, terse}.
ADR-0071 (R4): seeded surface variation via convivial_v1.
chat/register_variation.py applies SHA-256-seeded marker selection from
bounded discourse-marker buckets. ChatResponse.pre_decoration_surface routes
truth-path surface to core/cognition/pipeline.py so trace_hash stays
invariant under register (the load-bearing architectural fix — initially
invariant C failed under convivial because decoration was leaking into
trace_hash via response.surface). Empty-string marker entries now
legitimate ("no marker this turn" is a valid seed pick). realizer_overrides
schema widened with per_intent nested block (validated against IntentTag
whitelist; wired but not exercised by convivial). Two new invariants:
seeded_variation_replay_equivalence (fresh runtimes → byte-identical) and
seeded_variation_turn_distinct (same prompt across turns → ≥2 distinct
surfaces).
ADR-0072 (R5, draft): telemetry + operator surface — TurnEvent gains
register_id and register_variant_id, core chat --register flag, core demo
register-tour. Status: Proposed; not yet implemented.
Three ratified register packs ship: default_neutral_v1 (null), terse_v1
(disclosure_domain_count=1), convivial_v1 (3 openings × 3 closings).
Verification:
- 84 register tests pass + 1 documented skip
- Curated lanes green: smoke 67, cognition 120+1s, teaching 17, packs 6,
runtime 19, algebra 132
- Cognition eval byte-identical to pre-register baseline:
public 100/100/91.7/100, holdout 100/100/83.3/100
- Full lane: 2608 passed, 4 skipped, 1 failed (pre-existing
test_cli_demo.py "Combined Demo" → "Run Every Demo" rename, unrelated)
Truth-path isolation: chat/register_variation.py is realizer-side; the seam
test (tests/test_register_pack_seam.py) refuses imports of packs.register
from intent classification, propagation, vault recall, trace hashing, and
algebra.
131 lines
4.7 KiB
Python
131 lines
4.7 KiB
Python
"""chat/example_surface.py — Phase 3.4: EXAMPLE intent composer.
|
|
|
|
When a prompt classifies as EXAMPLE — "Give me an example of X",
|
|
"Show me an instance of X", "Example of X" — the composer surfaces
|
|
a reviewed chain where X appears as the **object**, inverting the
|
|
typical "X is the subject" chain access pattern.
|
|
|
|
For "Give me an example of truth":
|
|
|
|
(light, cause, reveals, truth) exists in the cognition corpus
|
|
→ "Example of truth: light reveals truth."
|
|
|
|
This is the *converse* of NARRATIVE. Where NARRATIVE walks every
|
|
chain rooted on X as subject ("X reveals A; X grounds B"), EXAMPLE
|
|
walks chains where X is the object ("A reveals X; B grounds X").
|
|
Both consult the same aggregated teaching index — no new corpus
|
|
ratification required.
|
|
|
|
Design constraints (matching ADR-0052..0065 doctrine):
|
|
|
|
- **No content synthesis.** Every visible non-template token is
|
|
pack-sourced or a verbatim chain atom.
|
|
- **Deterministic ordering.** Examples sort by (intent, subject,
|
|
connective) so identical corpus state yields identical surfaces.
|
|
- **Dedup by subject.** Multiple chains can have the same object X
|
|
with the same subject Y (e.g. cause/verification both
|
|
``Y reveals X``). Emit one example per distinct subject.
|
|
- **Bounded count.** Default ``max_examples=3`` keeps the surface
|
|
readable.
|
|
|
|
Returns ``None`` when no chain references X as object — caller
|
|
falls through to pack-grounded DEFINITION (if X is pack-resident)
|
|
or to OOV invitation (if X is unknown).
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from chat.cross_pack_grounding import cross_pack_chains_for_object
|
|
from chat.pack_resolver import _pack_lexicon_for, resolve_lemma
|
|
from packs.register.loader import RegisterPack, UNREGISTERED
|
|
from chat.teaching_grounding import (
|
|
_all_chains_index,
|
|
_pack_for_corpus,
|
|
)
|
|
from generate.semantic_templates import humanize_predicate
|
|
|
|
|
|
def _object_domains_for_chain(chain) -> tuple[str, ...]:
|
|
"""Resolve object domains for both in-pack and cross-pack chains."""
|
|
object_pack_id = getattr(chain, "object_pack_id", None)
|
|
if object_pack_id:
|
|
return _pack_lexicon_for(object_pack_id).get(chain.object, ())
|
|
return _pack_for_corpus(chain.corpus_id).get(chain.object, ())
|
|
|
|
|
|
def example_grounded_surface(
|
|
object_lemma: str,
|
|
*,
|
|
max_examples: int = 3,
|
|
register: RegisterPack = UNREGISTERED,
|
|
) -> str | None:
|
|
"""Return a deterministic EXAMPLE-tier surface, or ``None``.
|
|
|
|
Aggregates every reviewed chain whose **object** equals
|
|
*object_lemma* across all registered teaching corpora. Dedups
|
|
by subject (the same subject acting under both cause + verification
|
|
on the same object produces one example, not two). Sorts
|
|
lexicographically for replay stability.
|
|
|
|
Returns ``None`` when no chain references *object_lemma* as
|
|
object — caller routes through pack-grounded DEFINITION (if
|
|
the lemma is pack-resident) or to OOV invitation.
|
|
"""
|
|
if not object_lemma or not isinstance(object_lemma, str):
|
|
return None
|
|
key = object_lemma.strip().lower()
|
|
if not key:
|
|
return None
|
|
if max_examples < 1:
|
|
return None
|
|
|
|
index = _all_chains_index()
|
|
matching: list = [chain for chain in index.values() if chain.object == key]
|
|
# ADR-0067 — merge cross-pack chains whose object equals the lemma.
|
|
matching.extend(cross_pack_chains_for_object(key))
|
|
if not matching:
|
|
return None
|
|
|
|
# Dedup by subject — same subject acting twice (cause +
|
|
# verification) on this object is one example. Stable sort
|
|
# by (intent, subject, connective).
|
|
seen_subjects: set[str] = set()
|
|
deduped: list = []
|
|
for chain in sorted(
|
|
matching, key=lambda c: (c.intent, c.subject, c.connective),
|
|
):
|
|
if chain.subject in seen_subjects:
|
|
continue
|
|
seen_subjects.add(chain.subject)
|
|
deduped.append(chain)
|
|
if len(deduped) >= max_examples:
|
|
break
|
|
|
|
first = deduped[0]
|
|
object_domains = _object_domains_for_chain(first)
|
|
if not object_domains:
|
|
resolved = resolve_lemma(first.object)
|
|
if resolved is None:
|
|
return None
|
|
object_domains = resolved[1]
|
|
head_object = "; ".join(
|
|
object_domains[: max(1, first.domains_object_k)]
|
|
)
|
|
|
|
corpora = tuple(sorted({c.corpus_id for c in deduped}))
|
|
corpora_tag = corpora[0] if len(corpora) == 1 else " + ".join(corpora)
|
|
|
|
clauses: list[str] = []
|
|
for chain in deduped:
|
|
connective = humanize_predicate(chain.connective)
|
|
clauses.append(f"{chain.subject} {connective} {chain.object}")
|
|
|
|
examples_text = "; ".join(clauses)
|
|
return (
|
|
f"{first.object} — example-grounded ({corpora_tag}): "
|
|
f"{head_object}. Example: {examples_text}. "
|
|
f"No session evidence yet."
|
|
)
|
|
|
|
|
|
__all__ = ["example_grounded_surface"]
|