refactor(generate): remove redundant forbidden-site _close_final_state; rename "Drift fix 2"
generate/stream.py is a CLAUDE.md-forbidden normalization site, yet _close_final_state re-closed the walk's final state with unitize_versor. The walk is built entirely from versor_apply / Spin-manifold rotors (persona voicing, recall transitions, propagate_step), so versor_condition < 1e-6 holds on the output BY CONSTRUCTION — the final unitize was a true no-op (measured: final_state versor_condition = 2.98e-17 WITH and WITHOUT it). - Remove _close_final_state + its unitize_versor import; GenerationResult.final_state=current. - Reframe the "Drift fix 2" comment -> "recall-confidence weighting" (a selection policy, not normalization; mislabeled per the L10 Decision 0 bright line). - Test-first: add test_generated_final_state_satisfies_versor_condition_by_construction (exercises voicing + seeded-vault recall); green before AND after removal. Brings stream.py into forbidden-sites compliance.
This commit is contained in:
parent
d47741f5df
commit
8c394b8818
2 changed files with 40 additions and 22 deletions
|
|
@ -18,7 +18,6 @@ import numpy as np
|
|||
from field.state import FieldState
|
||||
from field.propagate import propagate_step
|
||||
from algebra.rotor import rotor_power, word_transition_rotor
|
||||
from algebra.versor import unitize_versor
|
||||
from generate.admissibility import (
|
||||
AdmissibilityRegion,
|
||||
AdmissibilityTraceStep,
|
||||
|
|
@ -129,17 +128,6 @@ def _voiced_state(state: FieldState, persona) -> FieldState:
|
|||
)
|
||||
|
||||
|
||||
def _close_final_state(state: FieldState) -> FieldState:
|
||||
return FieldState(
|
||||
F=unitize_versor(state.F),
|
||||
node=state.node,
|
||||
step=state.step,
|
||||
holonomy=state.holonomy,
|
||||
energy=state.energy,
|
||||
valence=state.valence,
|
||||
)
|
||||
|
||||
|
||||
def _softmax(scores: list[float]) -> list[float]:
|
||||
"""Numerically stable softmax over a list of floats."""
|
||||
if not scores:
|
||||
|
|
@ -170,16 +158,15 @@ def _recall_state(state: FieldState, vault, top_k: int) -> tuple[FieldState, int
|
|||
if not hits:
|
||||
return state, 0
|
||||
|
||||
# Drift fix 2: score-weighted vault recall transitions.
|
||||
# Recall-confidence weighting (a selection policy, NOT normalization/repair).
|
||||
#
|
||||
# Previously every recalled versor was applied as a full rotor transition
|
||||
# regardless of its recall score, giving a stale turn-3 hit the same
|
||||
# influence as a high-confidence recent hit.
|
||||
#
|
||||
# Now each rotor is scaled by its softmax-normalised score weight, so the
|
||||
# field moves proportionally to how strongly each hit was recalled.
|
||||
# Hits with infinite score (exact self-matches) receive full weight 1.0
|
||||
# and short-circuit the softmax path.
|
||||
# Each recalled versor is applied as a rotor transition on the (telemetry-
|
||||
# only) generation walk, scaled by its softmax-normalised recall score, so a
|
||||
# stale low-confidence hit moves the field less than a high-confidence recent
|
||||
# one (previously every hit applied at full weight). Hits with infinite score
|
||||
# (exact self-matches) get full weight 1.0 and short-circuit the softmax path.
|
||||
# Transitions are word_transition_rotor / propagate_step (closure-preserving
|
||||
# by construction) — recall weighting, not a "drift fix".
|
||||
finite_hits = [h for h in hits if h["score"] != float("inf")]
|
||||
exact_hits = [h for h in hits if h["score"] == float("inf")]
|
||||
|
||||
|
|
@ -638,7 +625,7 @@ def generate(
|
|||
|
||||
return GenerationResult(
|
||||
tokens=tokens,
|
||||
final_state=_close_final_state(current),
|
||||
final_state=current,
|
||||
trajectory=trajectory,
|
||||
salience_top_k=salience_budget,
|
||||
candidates_used=candidates_used,
|
||||
|
|
|
|||
|
|
@ -92,6 +92,37 @@ def test_minimum_engine_loop_is_deterministic_and_stores_generated_state() -> No
|
|||
assert not np.array_equal(recalled[0]["versor"], initial.F)
|
||||
|
||||
|
||||
def test_generated_final_state_satisfies_versor_condition_by_construction() -> None:
|
||||
"""The generation walk closes by construction — no final re-closure needed.
|
||||
|
||||
Persona voicing (``versor_apply``), score-weighted recall transitions
|
||||
(``propagate_step`` = ``versor_apply``), and the walk rotors are all built
|
||||
from ``versor_apply`` / Spin-manifold rotors, so ``versor_condition < 1e-6``
|
||||
holds on the OUTPUT by construction. This is the regression lock that lets
|
||||
``generate()`` drop the forbidden-site ``_close_final_state`` re-closure
|
||||
(CLAUDE.md: no hot-path normalizers in ``generate/stream.py``). Exercises
|
||||
the recall path (seeded vault) and a non-identity voicing motor, not just
|
||||
the bare walk.
|
||||
"""
|
||||
vocab = _minimal_vocab()
|
||||
persona = PersonaMotor.identity()
|
||||
persona.M = _positive_unit_reflector(7) # real M·F·reverse(M) voicing
|
||||
|
||||
vault = VaultStore()
|
||||
vault.store(inject(["pneuma"], vocab).F, metadata={"role": "assistant"})
|
||||
vault.store(inject(["truth"], vocab).F, metadata={"role": "assistant"})
|
||||
|
||||
result = generate(
|
||||
inject(["logos", "arche"], vocab), vocab, persona, max_tokens=6, vault=vault
|
||||
)
|
||||
|
||||
vc = versor_condition(result.final_state.F)
|
||||
assert vc < 1e-6, (
|
||||
f"generated final_state versor_condition {vc:.3e} >= 1e-6 — the walk "
|
||||
"must close by construction without a final re-closure"
|
||||
)
|
||||
|
||||
|
||||
def test_session_context_respond_preserves_and_vaults_final_state() -> None:
|
||||
session = SessionContext(vocab=_minimal_vocab())
|
||||
initial = session.ingest(["logos", "arche"])
|
||||
|
|
|
|||
Loading…
Reference in a new issue