R0 keyed a realized fact by its subject's field versor, which is NOT injective: two facts about one subject embed to byte-identical versors and collide at inf on metric recall (proven). R1 adds the missing structural key. - RealizedRecord/metadata carry ordered `relation_arguments` (the relation-space key R0's sorted `entity_names` discards) and a span-free `structure_key`. - `recall_realized(ctx, subject=/predicate=/content_hash=/structure_key=/ structure_kind=/entity=)` retrieves realized facts by EXACT structural metadata (no metric / ANN), via a new read-only `VaultStore.iter_metadata()` accessor. - Idempotency now dedups on the span-free `structure_key`, so the same proposition told from a different source/offset collapses (R0's span-inclusive content_hash could not). Guarded by an ambiguous-entity-name refusal — a wrong=0 defense, since `Entity.name` is non-unique in the model (only `entity_id` is enforced). - `content_hash` retained for provenance + replay_hash; `vault_index` pinned to the live deque position. Design adversarially verified (docs/analysis/REALIZE-R1-DETERMINE-scope-2026-06-06.md); the false "established pattern" private-access comment is removed in favor of the public accessor. wrong=0 + versor_condition<1e-6 + exact CGA recall preserved; vault/store.py adds only a read-only accessor (no normalization). Green: 23 realize + 110 invariant/vault + 90 smoke; ruff check clean.
220 lines
9.5 KiB
Python
220 lines
9.5 KiB
Python
"""REALIZE slice R1 — structural identity & recall.
|
|
|
|
The R0 store keys a realized fact by its subject's FIELD versor. That versor is
|
|
not an injective identity: two facts about the same subject embed to the
|
|
*byte-identical* versor, so metric recall returns both at score ``inf`` and
|
|
cannot tell them apart (proven by ``test_metric_recall_collides_on_same_subject``).
|
|
|
|
R1 adds the missing key: a realized fact carries its ordered
|
|
``relation_arguments`` and a span-free ``structure_key``, and
|
|
``recall_realized`` retrieves facts by their EXACT structural metadata
|
|
(subject / predicate / content_hash / structure_key) — exact and deterministic,
|
|
no metric, no vault mutation. Span-free idempotency dedups the same proposition
|
|
told from a different source/offset (which R0's span-inclusive content_hash
|
|
missed).
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
|
|
from algebra.versor import versor_condition
|
|
from chat.runtime import ChatRuntime
|
|
from generate.meaning_graph.reader import comprehend
|
|
from generate.realize import (
|
|
NotRealized,
|
|
Realized,
|
|
RealizedRecord,
|
|
realize_comprehension,
|
|
recall_realized,
|
|
)
|
|
from session.context import SessionContext
|
|
|
|
_HIGH_INTERVAL = 10**9 # never auto-reproject in these tests
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def vocab_persona():
|
|
rt = ChatRuntime(no_load_state=True)
|
|
return rt._context.vocab, rt._context.persona
|
|
|
|
|
|
def _ctx(vocab_persona) -> SessionContext:
|
|
vocab, persona = vocab_persona
|
|
return SessionContext(vocab=vocab, persona=persona, vault_reproject_interval=_HIGH_INTERVAL)
|
|
|
|
|
|
def _realize(text: str, ctx: SessionContext, source_id: str = "input"):
|
|
return realize_comprehension(comprehend(text, source_id=source_id), ctx)
|
|
|
|
|
|
# --------------------------------------------------------------------------- #
|
|
# The problem: the field versor is NOT an injective key (collision is real)
|
|
# --------------------------------------------------------------------------- #
|
|
|
|
|
|
def test_metric_recall_collides_on_same_subject(vocab_persona) -> None:
|
|
"""Two distinct facts about the same subject store at the byte-identical
|
|
versor, so metric recall returns both at ``inf`` — structurally blind.
|
|
This is the falsifiable justification for structural recall."""
|
|
ctx = _ctx(vocab_persona)
|
|
a = _realize("Truth is a concept.", ctx)
|
|
b = _realize("Truth is a thought.", ctx)
|
|
assert isinstance(a, Realized) and isinstance(b, Realized)
|
|
assert a.record.content_hash != b.record.content_hash # genuinely distinct facts
|
|
# byte-identical stored versors -> the metric cannot separate them
|
|
assert ctx.vault._versors[0].tobytes() == ctx.vault._versors[1].tobytes()
|
|
hits = ctx.vault.recall(ctx.probe_ingest(["truth"]).F, top_k=5)
|
|
realized = [h for h in hits if h["metadata"].get("kind") == "realized"]
|
|
assert len(realized) == 2
|
|
assert all(h["score"] == float("inf") for h in realized) # both collide at inf
|
|
|
|
|
|
# --------------------------------------------------------------------------- #
|
|
# Structural recall — exact metadata match, deterministic, distinct
|
|
# --------------------------------------------------------------------------- #
|
|
|
|
|
|
def test_structural_recall_by_subject_returns_all_same_subject_facts(vocab_persona) -> None:
|
|
ctx = _ctx(vocab_persona)
|
|
_realize("Truth is a concept.", ctx)
|
|
_realize("Truth is a thought.", ctx)
|
|
_realize("Knowledge is a concept.", ctx) # different subject
|
|
got = recall_realized(ctx, subject="truth")
|
|
assert all(isinstance(r, RealizedRecord) for r in got)
|
|
assert len(got) == 2 # both truth facts, NOT the knowledge fact
|
|
hashes = {r.content_hash for r in got}
|
|
assert len(hashes) == 2 # distinctly recalled
|
|
assert all(r.relation_arguments[0] == "truth" for r in got)
|
|
|
|
|
|
def test_structural_recall_by_content_hash_disambiguates(vocab_persona) -> None:
|
|
ctx = _ctx(vocab_persona)
|
|
a = _realize("Truth is a concept.", ctx)
|
|
_realize("Truth is a thought.", ctx)
|
|
assert isinstance(a, Realized)
|
|
got = recall_realized(ctx, content_hash=a.record.content_hash)
|
|
assert len(got) == 1
|
|
assert got[0].content_hash == a.record.content_hash
|
|
assert "concept" in got[0].entity_names
|
|
|
|
|
|
def test_structural_recall_by_predicate(vocab_persona) -> None:
|
|
ctx = _ctx(vocab_persona)
|
|
_realize("Truth is a concept.", ctx)
|
|
_realize("Truth is a thought.", ctx)
|
|
assert len(recall_realized(ctx, predicate="member")) == 2
|
|
assert recall_realized(ctx, predicate="no_such_predicate") == ()
|
|
|
|
|
|
def test_structural_recall_conjoins_filters(vocab_persona) -> None:
|
|
ctx = _ctx(vocab_persona)
|
|
_realize("Truth is a concept.", ctx)
|
|
_realize("Truth is a thought.", ctx)
|
|
_realize("Knowledge is a concept.", ctx)
|
|
got = recall_realized(ctx, subject="truth", predicate="member")
|
|
assert len(got) == 2
|
|
assert recall_realized(ctx, subject="knowledge", predicate="member")[0].relation_arguments == (
|
|
"knowledge",
|
|
"concept",
|
|
)
|
|
|
|
|
|
def test_structural_recall_empty_on_no_match(vocab_persona) -> None:
|
|
ctx = _ctx(vocab_persona)
|
|
_realize("Truth is a concept.", ctx)
|
|
assert recall_realized(ctx, subject="nonexistent") == ()
|
|
assert recall_realized(ctx) == recall_realized(ctx, subject=None) # no filter -> all realized
|
|
|
|
|
|
def test_structural_recall_survives_reboot(vocab_persona) -> None:
|
|
vocab, persona = vocab_persona
|
|
ctx = _ctx(vocab_persona)
|
|
a = _realize("Truth is a concept.", ctx)
|
|
assert isinstance(a, Realized)
|
|
rebooted = SessionContext(vocab=vocab, persona=persona, vault_reproject_interval=_HIGH_INTERVAL)
|
|
rebooted.restore(ctx.snapshot())
|
|
got = recall_realized(rebooted, subject="truth")
|
|
assert len(got) == 1
|
|
assert got[0].content_hash == a.record.content_hash
|
|
assert got[0].relation_arguments == ("truth", "concept")
|
|
# field versor still valid after the round trip (recall is structural, but the
|
|
# stored placement must remain a versor)
|
|
v = rebooted.vault._versors[got[0].vault_index]
|
|
assert versor_condition(v) < 1e-6
|
|
|
|
|
|
def test_record_carries_ordered_relation_arguments(vocab_persona) -> None:
|
|
ctx = _ctx(vocab_persona)
|
|
a = _realize("Truth is a concept.", ctx)
|
|
assert isinstance(a, Realized)
|
|
# ordered (subject, object) — NOT the sorted entity_names
|
|
assert a.record.relation_arguments == ("truth", "concept")
|
|
assert a.record.entity_names == ("concept", "truth") # sorted, unchanged from R0
|
|
|
|
|
|
# --------------------------------------------------------------------------- #
|
|
# Span-free idempotency — the same proposition from a different source dedups
|
|
# --------------------------------------------------------------------------- #
|
|
|
|
|
|
def test_structure_key_is_span_free_but_content_hash_is_not(vocab_persona) -> None:
|
|
a_ctx = _ctx(vocab_persona)
|
|
b_ctx = _ctx(vocab_persona)
|
|
ra = _realize("Truth is a concept.", a_ctx, source_id="docA")
|
|
rb = _realize("Truth is a concept.", b_ctx, source_id="docB")
|
|
assert isinstance(ra, Realized) and isinstance(rb, Realized)
|
|
# same proposition, different provenance:
|
|
assert ra.record.structure_key == rb.record.structure_key # span/source-free
|
|
assert ra.record.content_hash != rb.record.content_hash # span-INCLUSIVE differs
|
|
|
|
|
|
def test_span_free_idempotency_dedups_across_source(vocab_persona) -> None:
|
|
ctx = _ctx(vocab_persona)
|
|
first = _realize("Truth is a concept.", ctx, source_id="docA")
|
|
second = _realize("Truth is a concept.", ctx, source_id="docB")
|
|
assert isinstance(first, Realized) and first.created is True
|
|
# R0's content_hash dedup would MISS this (different span -> different hash);
|
|
# the span-free structure_key catches it.
|
|
assert isinstance(second, Realized) and second.created is False
|
|
assert len(ctx.vault._metadata) == 1
|
|
|
|
|
|
def test_distinct_facts_not_collapsed_by_structure_key(vocab_persona) -> None:
|
|
ctx = _ctx(vocab_persona)
|
|
_realize("Truth is a concept.", ctx)
|
|
_realize("Truth is a thought.", ctx) # same subject+predicate, different object
|
|
assert len(ctx.vault._metadata) == 2 # NOT collapsed
|
|
keys = {m["structure_key"] for m in ctx.vault._metadata}
|
|
assert len(keys) == 2
|
|
|
|
|
|
def test_ineligible_input_still_realizes_nothing(vocab_persona) -> None:
|
|
# R1 does not loosen R0's wrong=0 floor.
|
|
ctx = _ctx(vocab_persona)
|
|
assert isinstance(_realize("Is truth a concept?", ctx), NotRealized)
|
|
assert isinstance(_realize("The weather is nice today.", ctx), NotRealized)
|
|
assert len(ctx.vault._metadata) == 0
|
|
|
|
|
|
def test_duplicate_entity_names_refused(vocab_persona) -> None:
|
|
"""wrong=0 defense: the model permits distinct entity_ids to share a NAME.
|
|
A name-keyed structure_key would collapse a converse/homonym fact onto an
|
|
existing one (dropping a distinct proposition), so realize refuses the
|
|
ambiguous graph rather than risk the silent drop. Latent in today's reader
|
|
(entity_id == name), but proven to bite via a hand-built graph."""
|
|
from generate.meaning_graph.model import Entity, MeaningGraph, MeaningSpan, Relation
|
|
from generate.meaning_graph.reader import Comprehension
|
|
|
|
span = MeaningSpan(source_id="input", start=0, end=10, text="dup vs dup")
|
|
graph = MeaningGraph(
|
|
entities=(
|
|
Entity(entity_id="dup_1", name="dup", span=span),
|
|
Entity(entity_id="dup_2", name="dup", span=span),
|
|
),
|
|
relations=(Relation(predicate="member", arguments=("dup_1", "dup_2"), span=span),),
|
|
)
|
|
ctx = _ctx(vocab_persona)
|
|
res = realize_comprehension(Comprehension(meaning_graph=graph, queries=()), ctx)
|
|
assert isinstance(res, NotRealized) and res.reason == "ambiguous_entity_names"
|
|
assert len(ctx.vault._metadata) == 0
|