feat(realize): R0 — one told fact becomes a SPECULATIVE, reboot-stable vault entry
REALIZE roadmap Step 3, slice R0: the boundary that turns comprehension from an
EVAL ARTIFACT into accumulating living knowledge. A comprehended declarative fact is
integrated into the held self as a structured vault entry (versor, metadata) — NOT a
new store — so it inherits exact cga_inner recall, EpistemicStatus stamping, and
bit-exact Shape B+ persistence for free. Scope: docs/analysis/REALIZE-scope-2026-06-06.md.
generate/realize/realize.py — realize_comprehension(Comprehension|Refusal, ctx) ->
Realized(record, created) | NotRealized(reason):
- eligibility: a Comprehension (not Refusal) with NO queries and EXACTLY ONE
non-negated relation whose subject grounds IN-VOCABULARY. Everything else is a
typed NotRealized with zero vault writes (wrong=0).
- in-vocab-subject only: OOV grounding is non-deterministic across reboots (an
empirically-confirmed substrate gap), so OOV subjects are declined in R0.
- SPECULATIVE always (COHERENT is never a default — ADR-0021); provenance via
MeaningSpan source_span + structure_canonical; content_hash + replay_hash via
canonical-JSON SHA-256 (floats forbidden).
- idempotency: dedup by content_hash within the session (exact-canonical,
span-inclusive — safe direction only, never drops a distinct fact).
- durable schema admits a 2nd substrate later via structure_kind/structure_canonical.
- stores via the existing VaultStore.store path: no new embedder, no normalization
(closure stays algebra/versor.py), no parallel learning path.
Explicitly OUT of R0: COHERENT promotion, teaching-loop proposals, trace-folding,
relation-space recall, the arithmetic/binding_graph path.
tests/test_realize_r0.py (10) — eligibility (refusal/query/multi-relation/OOV all
write nothing); record fields; idempotency (re-told fact doesn't grow the vault);
SPECULATIVE status firewall (recall(min_status=COHERENT) excludes it); the
falsifiable exit gate (told -> realize -> snapshot -> reboot -> recall: byte-exact
content_hash + score + versor bytes, speculative, versor_condition<1e-6); and
replay_hash re-derivable after reboot. Gate verified to BITE (COHERENT default,
refusal-writes, reprojection-on-load all fail it).
INV-21: generate/realize/realize.py added to ALLOWED_VAULT_WRITERS — a sanctioned
writer (same VaultStore.store path, SPECULATIVE default, nothing on Refusal).
Adversarially reviewed (3 lenses: invariants/wrong0/honesty, determinism/boundary,
scope/adjustments) — no critical/high/medium findings; low/nit honesty wrinkles
folded (state-dependent-placement wording, span-inclusive-dedup note, direct
versor-bytes gate assert, replay_hash re-derivation test). 10 R0 + 90 smoke green;
lane SHAs 8/9 (sole miss = public_demo env flake; deductive_logic + math_teaching
unchanged -> no GSM8K coupling).
This commit is contained in:
parent
7feb940b9a
commit
43fcd08ce8
4 changed files with 405 additions and 0 deletions
15
generate/realize/__init__.py
Normal file
15
generate/realize/__init__.py
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
"""REALIZE — integrate comprehended structure into the held self (roadmap Step 3)."""
|
||||
|
||||
from generate.realize.realize import (
|
||||
NotRealized,
|
||||
Realized,
|
||||
RealizedRecord,
|
||||
realize_comprehension,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
"NotRealized",
|
||||
"Realized",
|
||||
"RealizedRecord",
|
||||
"realize_comprehension",
|
||||
]
|
||||
189
generate/realize/realize.py
Normal file
189
generate/realize/realize.py
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
"""REALIZE slice R0 — one told fact becomes a realized vault entry.
|
||||
|
||||
The boundary that turns comprehension from an EVAL ARTIFACT into accumulating living
|
||||
knowledge: a comprehended declarative fact is integrated into the held self as a
|
||||
SPECULATIVE, provenance-rich vault entry that survives reboot and recalls exactly.
|
||||
|
||||
A realized record is NOT a new store — it is a structured vault entry
|
||||
``(versor, metadata)`` so it inherits exact ``cga_inner`` recall, ``EpistemicStatus``
|
||||
stamping, and bit-exact Shape B+ persistence for free (see
|
||||
``docs/analysis/REALIZE-scope-2026-06-06.md``).
|
||||
|
||||
Slice R0 deliberately boring (everything else grows from this without corrupting the
|
||||
field): one told fact, SPECULATIVE only, in-vocab subject only, single non-negated
|
||||
declarative relation, dedup by content hash. Explicitly OUT of R0: COHERENT
|
||||
promotion, teaching-loop proposals, the quantitative ``binding_graph`` path,
|
||||
trace-folding, and relation-space recall.
|
||||
|
||||
wrong=0 at this layer: a ``Refusal`` (or any ineligible / ungrounded input) realizes
|
||||
NOTHING — it is returned as ``NotRealized(reason)``, never coerced into a vault entry.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
import numpy as np
|
||||
|
||||
from formation.hashing import sha256_of
|
||||
from generate.meaning_graph.reader import Comprehension, Refusal
|
||||
from session.context import SessionContext
|
||||
from teaching.epistemic import EpistemicStatus
|
||||
|
||||
# The known failure modes of the session embedding path (probe_ingest):
|
||||
# RuntimeError on cross-turn versor-condition violation; Key/Index/ValueError on a
|
||||
# degenerate grounding. Any of them is a clean no-op, never a crashed turn.
|
||||
_GROUNDING_FAILURES = (RuntimeError, KeyError, IndexError, ValueError)
|
||||
|
||||
#: R0 realizes only the neutral MeaningGraph substrate. The record shape already
|
||||
#: admits a second substrate (the quantitative binding-graph) via ``structure_kind``.
|
||||
_STRUCTURE_KIND_MEANING_GRAPH = "meaning_graph"
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class RealizedRecord:
|
||||
"""The realized-knowledge record (mirrors the stored vault metadata)."""
|
||||
|
||||
structure_kind: str
|
||||
structure_canonical: str
|
||||
relation_predicate: str
|
||||
entity_names: tuple[str, ...]
|
||||
source_span: str
|
||||
content_hash: str
|
||||
replay_hash: str
|
||||
epistemic_status: str
|
||||
tier: str
|
||||
vault_index: int
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class Realized:
|
||||
"""The fact is realized. ``created`` is False on an idempotent dedup hit
|
||||
(the fact was already realized this session — no new vault entry written)."""
|
||||
|
||||
record: RealizedRecord
|
||||
created: bool
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class NotRealized:
|
||||
"""Nothing was realized (no vault write). ``reason`` is for audit, not control."""
|
||||
|
||||
reason: str
|
||||
|
||||
|
||||
def realize_comprehension(
|
||||
comprehension: Comprehension | Refusal, ctx: SessionContext
|
||||
) -> Realized | NotRealized:
|
||||
"""Realize a comprehended declarative fact into ``ctx``'s vault, or decline.
|
||||
|
||||
Eligibility (R0): a ``Comprehension`` (not a ``Refusal``) with NO queries and
|
||||
EXACTLY ONE non-negated relation whose subject argument grounds in-vocabulary.
|
||||
Everything else is a typed ``NotRealized`` — no vault write (wrong=0).
|
||||
"""
|
||||
if isinstance(comprehension, Refusal):
|
||||
return NotRealized("refusal")
|
||||
if not isinstance(comprehension, Comprehension):
|
||||
return NotRealized("not_a_comprehension")
|
||||
if comprehension.queries:
|
||||
return NotRealized("query_bearing") # a question is recall, not intake
|
||||
|
||||
graph = comprehension.meaning_graph
|
||||
if len(graph.relations) != 1:
|
||||
return NotRealized("not_single_relation") # multi-relation intake is ambiguous in R0
|
||||
rel = graph.relations[0]
|
||||
if rel.negated:
|
||||
return NotRealized("negated_relation")
|
||||
if not rel.arguments:
|
||||
return NotRealized("empty_relation") # defensive — arity>=1 by construction
|
||||
|
||||
subject_id = rel.arguments[0]
|
||||
entity = next((e for e in graph.entities if e.entity_id == subject_id), None)
|
||||
if entity is None:
|
||||
return NotRealized("ungrounded_subject") # defensive — graph invariant
|
||||
|
||||
subject_token = entity.name
|
||||
# In-vocab gate: OOV grounding is NOT reproducible across reboots, so an OOV
|
||||
# subject cannot be realized deterministically yet (R0 scope; a substrate gap).
|
||||
try:
|
||||
ctx.vocab.index_of(subject_token)
|
||||
except (KeyError, IndexError):
|
||||
return NotRealized("oov_subject")
|
||||
|
||||
# Side-effect-free embedding (no state/vault/referent mutation). Closure stays
|
||||
# algebra/versor.py's job — REALIZE adds no normalization. NOTE: the field point
|
||||
# composes with the CURRENT session state, so placement is deterministic for a
|
||||
# GIVEN session state (the fact is realized at the held self's current field
|
||||
# position), not purely subject-determined.
|
||||
try:
|
||||
field_state = ctx.probe_ingest([subject_token])
|
||||
except _GROUNDING_FAILURES:
|
||||
return NotRealized("grounding_failed")
|
||||
versor = np.asarray(field_state.F, dtype=np.float32)
|
||||
|
||||
structure_canonical = graph.to_canonical_string()
|
||||
source_span = rel.span.to_canonical_string()
|
||||
content_hash = sha256_of(structure_canonical)
|
||||
status = EpistemicStatus.SPECULATIVE # COHERENT is never a default (ADR-0021)
|
||||
replay_hash = sha256_of(
|
||||
{
|
||||
"content_hash": content_hash,
|
||||
"source_span": source_span,
|
||||
"epistemic_status": status.value,
|
||||
}
|
||||
)
|
||||
entity_names = tuple(sorted(e.name for e in graph.entities))
|
||||
|
||||
# Idempotency: a re-told fact (same content_hash) does not grow the vault. Dedup
|
||||
# is exact-canonical (the content_hash is span-INCLUSIVE), so the SAFE direction
|
||||
# only — it never drops a genuinely distinct fact; it may fail to collapse the
|
||||
# same fact re-stated at a different offset (a span-free key is a later R1 option).
|
||||
# ``vault._metadata`` is read directly here (no public iterator exists yet);
|
||||
# this is the established project pattern and an intentional boundary for R0.
|
||||
for idx, meta in enumerate(ctx.vault._metadata):
|
||||
if meta.get("kind") == "realized" and meta.get("content_hash") == content_hash:
|
||||
return Realized(record=_record_from_metadata(meta, idx), created=False)
|
||||
|
||||
metadata = {
|
||||
"kind": "realized",
|
||||
"structure_kind": _STRUCTURE_KIND_MEANING_GRAPH,
|
||||
"structure_canonical": structure_canonical,
|
||||
"relation_predicate": rel.predicate,
|
||||
"entity_names": list(entity_names),
|
||||
"source_span": source_span,
|
||||
"content_hash": content_hash,
|
||||
"replay_hash": replay_hash,
|
||||
"tier": "session",
|
||||
}
|
||||
vault_index = ctx.vault.store(versor, metadata, epistemic_status=status)
|
||||
return Realized(
|
||||
record=RealizedRecord(
|
||||
structure_kind=_STRUCTURE_KIND_MEANING_GRAPH,
|
||||
structure_canonical=structure_canonical,
|
||||
relation_predicate=rel.predicate,
|
||||
entity_names=entity_names,
|
||||
source_span=source_span,
|
||||
content_hash=content_hash,
|
||||
replay_hash=replay_hash,
|
||||
epistemic_status=status.value,
|
||||
tier="session",
|
||||
vault_index=vault_index,
|
||||
),
|
||||
created=True,
|
||||
)
|
||||
|
||||
|
||||
def _record_from_metadata(meta: dict, idx: int) -> RealizedRecord:
|
||||
"""Reconstruct a RealizedRecord from a stored vault metadata dict."""
|
||||
return RealizedRecord(
|
||||
structure_kind=meta.get("structure_kind", _STRUCTURE_KIND_MEANING_GRAPH),
|
||||
structure_canonical=meta.get("structure_canonical", ""),
|
||||
relation_predicate=meta.get("relation_predicate", ""),
|
||||
entity_names=tuple(meta.get("entity_names", [])),
|
||||
source_span=meta.get("source_span", ""),
|
||||
content_hash=meta.get("content_hash", ""),
|
||||
replay_hash=meta.get("replay_hash", ""),
|
||||
epistemic_status=meta.get("epistemic_status", "speculative"),
|
||||
tier=meta.get("tier", "session"),
|
||||
vault_index=idx,
|
||||
)
|
||||
|
|
@ -643,6 +643,11 @@ ALLOWED_VAULT_WRITERS: frozenset[str] = frozenset({
|
|||
"session/context.py",
|
||||
"vault/store.py",
|
||||
"generate/proposition.py",
|
||||
# REALIZE (roadmap Step 3): integrates a comprehended declarative fact into the
|
||||
# held self as a SPECULATIVE, provenance-rich vault entry. A sanctioned writer —
|
||||
# it stores via the same VaultStore.store path (no parallel memory), defaults to
|
||||
# SPECULATIVE (never COHERENT), and writes nothing on a Refusal (wrong=0).
|
||||
"generate/realize/realize.py",
|
||||
})
|
||||
|
||||
PROJECT_ROOT_FOR_INV21 = Path(__file__).resolve().parent.parent
|
||||
|
|
|
|||
196
tests/test_realize_r0.py
Normal file
196
tests/test_realize_r0.py
Normal file
|
|
@ -0,0 +1,196 @@
|
|||
"""REALIZE slice R0 — one told fact survives reboot and recalls exactly, SPECULATIVE.
|
||||
|
||||
The load-bearing exit gate (test_r0_exit_gate_*) is falsifiable: it FAILS if REALIZE
|
||||
is decoration (a Refusal that silently writes, a COHERENT default, a missing
|
||||
provenance span, a reprojection mutating the versor on load, or a non-deterministic
|
||||
placement). The other tests pin eligibility, idempotency, and the SPECULATIVE
|
||||
status firewall (remembered != evidence).
|
||||
"""
|
||||
|
||||
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, realize_comprehension
|
||||
from session.context import SessionContext
|
||||
from teaching.epistemic import EpistemicStatus
|
||||
|
||||
_HIGH_INTERVAL = 10**9 # never auto-reproject in R0 tests (adjustment: reproject boundary)
|
||||
|
||||
|
||||
@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):
|
||||
return realize_comprehension(comprehend(text), ctx)
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Eligibility — wrong=0: ineligible input realizes NOTHING (no vault write)
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
|
||||
def test_refusal_realizes_nothing(vocab_persona) -> None:
|
||||
ctx = _ctx(vocab_persona)
|
||||
res = _realize("The weather is nice today.", ctx) # comprehend -> Refusal
|
||||
assert isinstance(res, NotRealized) and res.reason == "refusal"
|
||||
assert len(ctx.vault._metadata) == 0 # no vault write
|
||||
|
||||
|
||||
def test_query_bearing_realizes_nothing(vocab_persona) -> None:
|
||||
ctx = _ctx(vocab_persona)
|
||||
res = _realize("Is truth a concept?", ctx) # a question is recall, not intake
|
||||
assert isinstance(res, NotRealized) and res.reason == "query_bearing"
|
||||
assert len(ctx.vault._metadata) == 0
|
||||
|
||||
|
||||
def test_multi_relation_realizes_nothing(vocab_persona) -> None:
|
||||
ctx = _ctx(vocab_persona)
|
||||
res = _realize("Truth is a concept. Knowledge is a thought.", ctx)
|
||||
assert isinstance(res, NotRealized) and res.reason == "not_single_relation"
|
||||
assert len(ctx.vault._metadata) == 0
|
||||
|
||||
|
||||
def test_oov_subject_realizes_nothing(vocab_persona) -> None:
|
||||
# "rhea" is out-of-vocabulary; OOV grounding is not reproducible across reboots,
|
||||
# so R0 declines rather than realize a non-deterministic point.
|
||||
ctx = _ctx(vocab_persona)
|
||||
res = _realize("Rhea is a raven.", ctx)
|
||||
assert isinstance(res, NotRealized) and res.reason == "oov_subject"
|
||||
assert len(ctx.vault._metadata) == 0
|
||||
|
||||
|
||||
def test_single_in_vocab_declarative_is_realized(vocab_persona) -> None:
|
||||
ctx = _ctx(vocab_persona)
|
||||
res = _realize("Truth is a concept.", ctx)
|
||||
assert isinstance(res, Realized) and res.created is True
|
||||
r = res.record
|
||||
assert r.structure_kind == "meaning_graph"
|
||||
assert r.relation_predicate == "member"
|
||||
assert r.epistemic_status == "speculative" # never COHERENT by default
|
||||
assert r.tier == "session"
|
||||
assert r.source_span # provenance present
|
||||
assert r.content_hash and r.replay_hash
|
||||
assert "truth" in r.entity_names and "concept" in r.entity_names
|
||||
assert len(ctx.vault._metadata) == 1
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Idempotency — a re-told fact does not grow the vault (dedup by content_hash)
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
|
||||
def test_retold_fact_is_idempotent(vocab_persona) -> None:
|
||||
ctx = _ctx(vocab_persona)
|
||||
first = _realize("Truth is a concept.", ctx)
|
||||
second = _realize("Truth is a concept.", ctx)
|
||||
assert isinstance(first, Realized) and first.created is True
|
||||
assert isinstance(second, Realized) and second.created is False # dedup hit
|
||||
assert second.record.content_hash == first.record.content_hash
|
||||
assert len(ctx.vault._metadata) == 1 # NOT grown
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Status firewall — SPECULATIVE is candidate memory, NOT evidence
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
|
||||
def test_speculative_record_is_not_admitted_as_evidence(vocab_persona) -> None:
|
||||
ctx = _ctx(vocab_persona)
|
||||
res = _realize("Truth is a concept.", ctx)
|
||||
assert isinstance(res, Realized)
|
||||
query = ctx.probe_ingest(["truth"]).F
|
||||
# default recall surfaces it as a CANDIDATE...
|
||||
default_hits = ctx.vault.recall(query, top_k=5)
|
||||
assert any(h["metadata"].get("kind") == "realized" for h in default_hits)
|
||||
# ...but min_status=COHERENT must NOT return it (remembered != evidence).
|
||||
coherent_hits = ctx.vault.recall(query, top_k=5, min_status=EpistemicStatus.COHERENT)
|
||||
assert not any(h["metadata"].get("kind") == "realized" for h in coherent_hits)
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Exit gate — told -> realize -> snapshot -> reboot -> recall, byte-exact
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
|
||||
def test_r0_exit_gate_survives_reboot_and_recalls_exactly(vocab_persona) -> None:
|
||||
vocab, persona = vocab_persona
|
||||
ctx = _ctx(vocab_persona)
|
||||
|
||||
res = _realize("Truth is a concept.", ctx)
|
||||
assert isinstance(res, Realized) and res.created
|
||||
pre_query = ctx.probe_ingest(["truth"]).F
|
||||
pre_hits = ctx.vault.recall(pre_query, top_k=5)
|
||||
pre = next(h for h in pre_hits if h["metadata"].get("kind") == "realized")
|
||||
pre_score = pre["score"]
|
||||
pre_content_hash = pre["metadata"]["content_hash"]
|
||||
pre_versor_bytes = pre["versor"].tobytes()
|
||||
|
||||
# reboot: snapshot -> NEW context -> restore (no reprojection on load)
|
||||
snap = ctx.snapshot()
|
||||
rebooted = SessionContext(vocab=vocab, persona=persona, vault_reproject_interval=_HIGH_INTERVAL)
|
||||
rebooted.restore(snap)
|
||||
|
||||
post_query = rebooted.probe_ingest(["truth"]).F
|
||||
post_hits = rebooted.vault.recall(post_query, top_k=5)
|
||||
post = next(h for h in post_hits if h["metadata"].get("kind") == "realized")
|
||||
|
||||
# content_hash byte-identical, recall score byte-identical (exact f32 restore)
|
||||
assert post["metadata"]["content_hash"] == pre_content_hash
|
||||
assert post["score"] == pre_score
|
||||
assert post["metadata"]["epistemic_status"] == "speculative"
|
||||
# the restored versor is byte-identical (DIRECT catch of any reprojection/
|
||||
# normalization on load) and still a valid versor.
|
||||
assert post["versor"].tobytes() == pre_versor_bytes
|
||||
assert versor_condition(post["versor"]) < 1e-6
|
||||
# provenance survived the reboot
|
||||
assert post["metadata"]["source_span"]
|
||||
|
||||
|
||||
def test_r0_replay_hash_is_rederivable_after_reboot(vocab_persona) -> None:
|
||||
# The replay_hash is the determinism anchor: re-deriving it from the RESTORED
|
||||
# metadata must reproduce the stored value byte-for-byte (closes the obligation
|
||||
# that replay_hash is a real replay proof, not just asserted structure).
|
||||
from formation.hashing import sha256_of
|
||||
|
||||
vocab, persona = vocab_persona
|
||||
ctx = _ctx(vocab_persona)
|
||||
assert isinstance(_realize("Truth is a concept.", ctx), Realized)
|
||||
|
||||
rebooted = SessionContext(vocab=vocab, persona=persona, vault_reproject_interval=_HIGH_INTERVAL)
|
||||
rebooted.restore(ctx.snapshot())
|
||||
meta = next(m for m in rebooted.vault._metadata if m.get("kind") == "realized")
|
||||
rederived = sha256_of(
|
||||
{
|
||||
"content_hash": meta["content_hash"],
|
||||
"source_span": meta["source_span"],
|
||||
"epistemic_status": meta["epistemic_status"],
|
||||
}
|
||||
)
|
||||
assert rederived == meta["replay_hash"]
|
||||
|
||||
|
||||
def test_r0_placement_is_deterministic_across_fresh_contexts(vocab_persona) -> None:
|
||||
# Realizing the SAME fact in two independent fresh contexts (same vocab) yields
|
||||
# the identical content_hash AND identical stored versor bytes — guards
|
||||
# idempotency + placement determinism (in-vocab subject).
|
||||
a = _ctx(vocab_persona)
|
||||
b = _ctx(vocab_persona)
|
||||
ra = _realize("Truth is a concept.", a)
|
||||
rb = _realize("Truth is a concept.", b)
|
||||
assert isinstance(ra, Realized) and isinstance(rb, Realized)
|
||||
assert ra.record.content_hash == rb.record.content_hash
|
||||
va = a.vault.recall(a.probe_ingest(["truth"]).F, top_k=1)[0]["versor"]
|
||||
vb = b.vault.recall(b.probe_ingest(["truth"]).F, top_k=1)[0]["versor"]
|
||||
assert va.tobytes() == vb.tobytes()
|
||||
Loading…
Reference in a new issue