Restore FieldState slots in determinism proof
This commit is contained in:
parent
4e7c29b84a
commit
f8113a38ba
2 changed files with 5 additions and 3 deletions
|
|
@ -4,7 +4,7 @@ FieldState — the complete cognitive field at one moment.
|
|||
Invariant: versor_condition(F) < 1e-6 always.
|
||||
This is checked at injection and maintained structurally by versor_apply().
|
||||
|
||||
FieldState is immutable by design (frozen=True).
|
||||
FieldState is immutable by design (frozen=True, slots=True).
|
||||
The np.ndarray F is copied and validated at construction — the copy() call
|
||||
is the explicit contract boundary. Callers must not retain a mutable
|
||||
reference to the array passed in and expect coherence.
|
||||
|
|
@ -17,7 +17,7 @@ import numpy as np
|
|||
_EXPECTED_COMPONENTS = 32
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class FieldState:
|
||||
F: np.ndarray # shape (32,) float32 — Cl(4,1) multivector on the versor manifold
|
||||
node: int = 0 # current node index in the vocabulary manifold
|
||||
|
|
@ -28,6 +28,7 @@ class FieldState:
|
|||
# Enforce copy + dtype + shape at the construction boundary.
|
||||
# frozen=True prevents reassignment, but ndarray contents are still
|
||||
# mutable via the array object; copy() here is the defence.
|
||||
# slots=True closes __dict__ so no incidental attributes can be added.
|
||||
F = np.array(self.F, dtype=np.float32).copy()
|
||||
if F.shape != (_EXPECTED_COMPONENTS,):
|
||||
raise ValueError(
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ import hashlib
|
|||
import json
|
||||
import struct
|
||||
from copy import deepcopy
|
||||
from dataclasses import fields
|
||||
from typing import Any
|
||||
|
||||
import numpy as np
|
||||
|
|
@ -498,7 +499,7 @@ class TestDET10FieldStateIsSingleMultivector:
|
|||
"""FieldState must not hold a copy of the input tokens."""
|
||||
state = inject(["in", "the", "beginning"], _PinVocab())
|
||||
# No attribute should store the original token list
|
||||
for attr in vars(state).values():
|
||||
for attr in (getattr(state, field.name) for field in fields(state)):
|
||||
if isinstance(attr, (list, tuple)):
|
||||
# Allow small metadata tuples but not token-length sequences
|
||||
assert len(attr) <= 4, (
|
||||
|
|
|
|||
Loading…
Reference in a new issue