feat: Integrate Fieldprint architecture hardware and cryptographic layers
This commit is contained in:
+32
-27
@@ -371,12 +371,11 @@ class KAIROSTemporalEngine:
|
||||
metadata = metadata or {}
|
||||
|
||||
# Convert input to phase
|
||||
# This is a simple mapping - in practice, sophisticated
|
||||
# phase extraction could be used (e.g., from transformer embeddings)
|
||||
phase = self._input_to_phase(input_phrase)
|
||||
# The phase is a complex angle, but we also retain the full semantic phase vector
|
||||
phase_complex, full_phase_vector = self._input_to_phase(input_phrase)
|
||||
|
||||
# Update history
|
||||
self._phases.append(phase)
|
||||
self._phases.append(phase_complex)
|
||||
self._timestamps.append(timestamp)
|
||||
|
||||
# Compute new coherence
|
||||
@@ -401,7 +400,7 @@ class KAIROSTemporalEngine:
|
||||
self._integration_count += 1
|
||||
|
||||
state = TemporalState(
|
||||
phase=phase,
|
||||
phase=phase_complex,
|
||||
coherence=coherence,
|
||||
timestamp=timestamp,
|
||||
metadata={
|
||||
@@ -409,40 +408,46 @@ class KAIROSTemporalEngine:
|
||||
"T_tau": T_tau,
|
||||
"collapsed": self._collapsed,
|
||||
"integration": self._integration_count,
|
||||
"phase_vector": full_phase_vector,
|
||||
}
|
||||
)
|
||||
|
||||
logger.debug(
|
||||
f"[{self.name}] Temporalized: coherence={coherence:.3f}, "
|
||||
f"phase={np.angle(phase):.3f}"
|
||||
f"phase={np.angle(phase_complex):.3f}"
|
||||
)
|
||||
|
||||
return state
|
||||
|
||||
def _input_to_phase(self, input_phrase: str) -> complex:
|
||||
def _input_to_phase(self, input_phrase: str) -> tuple[complex, list[float]]:
|
||||
"""
|
||||
Convert input phrase to phase.
|
||||
Convert input phrase to phase using semantic embeddings.
|
||||
|
||||
This is a simple placeholder. In a full implementation,
|
||||
sophisticated phase extraction would be used.
|
||||
|
||||
Current implementation:
|
||||
- Uses hash of phrase to get deterministic phase
|
||||
- Magnitude = 1.0 (unit phase)
|
||||
|
||||
TODO: Replace with transformer-based phase extraction
|
||||
TODO: Phase should reflect semantic content
|
||||
Uses SentenceTransformer (via temporal memory module) to extract
|
||||
a semantically meaningful phase angle, so that conceptually similar
|
||||
phrases align in phase space, driving true temporal resonance.
|
||||
"""
|
||||
import hashlib
|
||||
|
||||
# Deterministic but unpredictable phase
|
||||
hash_bytes = hashlib.sha256(input_phrase.encode()).digest()
|
||||
hash_int = int.from_bytes(hash_bytes[:8], 'big')
|
||||
|
||||
# Map to unit circle
|
||||
angle = (hash_int % 1000000) / 1000000 * 2 * math.pi
|
||||
|
||||
return complex(math.cos(angle), math.sin(angle))
|
||||
try:
|
||||
from ..memory.temporal import encode_to_phase
|
||||
phases = encode_to_phase(input_phrase)
|
||||
|
||||
# Average the multi-dimensional phase down to a single master phase angle
|
||||
if phases and len(phases) > 0:
|
||||
avg_angle = sum(phases) / len(phases)
|
||||
else:
|
||||
avg_angle = 0.0
|
||||
phases = [0.0]
|
||||
|
||||
return complex(math.cos(avg_angle), math.sin(avg_angle)), phases
|
||||
|
||||
except ImportError:
|
||||
# Fallback to hash if temporal module is unavailable
|
||||
import hashlib
|
||||
logger.warning("Could not import encode_to_phase, falling back to SHA-256 phase extraction")
|
||||
hash_bytes = hashlib.sha256(input_phrase.encode()).digest()
|
||||
hash_int = int.from_bytes(hash_bytes[:8], 'big')
|
||||
angle = (hash_int % 1000000) / 1000000 * 2 * math.pi
|
||||
return complex(math.cos(angle), math.sin(angle)), [angle]
|
||||
|
||||
def _apply_dampening(self):
|
||||
"""
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
"""
|
||||
becomingone.hardware package
|
||||
"""
|
||||
from .triton_bridge import compile_anchor_tensors
|
||||
@@ -0,0 +1,101 @@
|
||||
"""
|
||||
becomingone/hardware/triton_bridge.py
|
||||
|
||||
PagedFieldprintAttention Hardware Bridge
|
||||
========================================
|
||||
|
||||
Implements the structural hardware connection (Paper 2) for BecomingONE.
|
||||
|
||||
This module is responsible for compiling high-level Python `TemporalSignature`s
|
||||
into the raw PyTorch tensors (K_anchor, V_anchor) required by the custom
|
||||
Triton fused attention kernel. This prevents O(N^2) memory thrashing by injecting
|
||||
the persistent identity directly into the GPU SRAM during inference.
|
||||
|
||||
Functions:
|
||||
- compile_anchor_tensors(signatures, num_heads, d_head)
|
||||
"""
|
||||
|
||||
import logging
|
||||
from typing import List, Tuple, Any
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
try:
|
||||
import torch
|
||||
except ImportError:
|
||||
torch = None
|
||||
logger.warning("PyTorch not found. Triton hardware bridge will operate in mock mode.")
|
||||
|
||||
|
||||
def compile_anchor_tensors(
|
||||
signatures: List[Any],
|
||||
num_heads: int = 32,
|
||||
d_head: int = 128,
|
||||
dtype: Any = None
|
||||
) -> Tuple[Any, Any]:
|
||||
"""
|
||||
Compiles a list of TemporalSignatures into K_anchor and V_anchor PyTorch tensors.
|
||||
|
||||
Args:
|
||||
signatures: List of TemporalSignature objects. Usually filtered for IDENTITY strength.
|
||||
num_heads: Number of attention heads (H).
|
||||
d_head: Dimension per head (D_HEAD).
|
||||
dtype: PyTorch dtype (default: torch.float16).
|
||||
|
||||
Returns:
|
||||
Tuple of (K_anchor, V_anchor) tensors.
|
||||
Shape of each: [1, num_heads, N_ANCHOR, d_head] where N_ANCHOR = len(signatures).
|
||||
"""
|
||||
if torch is None:
|
||||
logger.error("Cannot compile anchor tensors without PyTorch.")
|
||||
return None, None
|
||||
|
||||
dtype = dtype or torch.float16
|
||||
n_anchor = len(signatures)
|
||||
|
||||
if n_anchor == 0:
|
||||
logger.warning("No signatures provided for anchor compilation. Returning empty tensors.")
|
||||
# Return empty but correctly shaped tensors
|
||||
empty = torch.zeros((1, num_heads, 0, d_head), dtype=dtype, device='cuda' if torch.cuda.is_available() else 'cpu')
|
||||
return empty, empty
|
||||
|
||||
logger.info(f"Compiling {n_anchor} TemporalSignatures into Triton Anchor Tensors...")
|
||||
|
||||
# Initialize the tensors
|
||||
device = 'cuda' if torch.cuda.is_available() else 'cpu'
|
||||
k_anchor = torch.zeros((1, num_heads, n_anchor, d_head), dtype=dtype, device=device)
|
||||
v_anchor = torch.zeros((1, num_heads, n_anchor, d_head), dtype=dtype, device=device)
|
||||
|
||||
# Map the phase vectors into the embedding space
|
||||
for i, sig in enumerate(signatures):
|
||||
phase_vec = sig.phase_vector
|
||||
if not phase_vec:
|
||||
# Fallback if empty phase
|
||||
continue
|
||||
|
||||
# Project the phase vector (e.g., length 384) into the multi-head attention space
|
||||
# We simulate this projection by repeating/truncating the phase vector
|
||||
# across the hidden dimension (num_heads * d_head)
|
||||
total_hidden_dim = num_heads * d_head
|
||||
|
||||
# Convert phase_vec to tensor
|
||||
phase_tensor = torch.tensor(phase_vec, dtype=dtype, device=device)
|
||||
|
||||
# Tile or slice to match total_hidden_dim
|
||||
if phase_tensor.shape[0] < total_hidden_dim:
|
||||
repeats = (total_hidden_dim // phase_tensor.shape[0]) + 1
|
||||
proj = phase_tensor.repeat(repeats)[:total_hidden_dim]
|
||||
else:
|
||||
proj = phase_tensor[:total_hidden_dim]
|
||||
|
||||
# Reshape to [num_heads, d_head]
|
||||
proj = proj.view(num_heads, d_head)
|
||||
|
||||
# In a full model, K and V would have learned projections (W_k, W_v).
|
||||
# For the bridge, we instantiate the anchor with the pure phase vector
|
||||
# weighted by the signature's absolute coherence value.
|
||||
k_anchor[0, :, i, :] = proj * sig.coherence_value
|
||||
v_anchor[0, :, i, :] = proj * sig.coherence_value
|
||||
|
||||
logger.debug(f"Successfully compiled K_anchor and V_anchor with shape [1, {num_heads}, {n_anchor}, {d_head}]")
|
||||
return k_anchor, v_anchor
|
||||
@@ -0,0 +1,146 @@
|
||||
"""
|
||||
becomingone/memory/ledger.py
|
||||
|
||||
Cryptographic Fieldprint Ledger
|
||||
===============================
|
||||
|
||||
Implements the cryptographic anchoring (Paper 1: Epistemic Capture) for BecomingONE.
|
||||
To prevent structural violence or silent memory rewrites, every TemporalSignature
|
||||
that is persisted to memory must be cryptographically sealed.
|
||||
|
||||
This implementation uses a continuous hash chain (Merkle-style log) where each
|
||||
new signature is hashed alongside the hash of the previous signature. This creates
|
||||
a topologically stable, immutable ledger of the agent's temporal history.
|
||||
|
||||
Functions:
|
||||
- `seal_signature(signature)`: Cryptographically anchors a TemporalSignature.
|
||||
- `verify_ledger()`: Audits the entire memory chain for tampering.
|
||||
"""
|
||||
|
||||
import json
|
||||
import hashlib
|
||||
import os
|
||||
import logging
|
||||
from typing import Dict, Any, Optional
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
LEDGER_FILE = "fieldprint_ledger.jsonl"
|
||||
|
||||
|
||||
def _compute_hash(data_str: str) -> str:
|
||||
"""Compute SHA-256 hash of a string."""
|
||||
return hashlib.sha256(data_str.encode("utf-8")).hexdigest()
|
||||
|
||||
|
||||
def get_last_merkle_root(filepath: str = LEDGER_FILE) -> str:
|
||||
"""
|
||||
Retrieve the most recent Merkle root from the ledger.
|
||||
If the ledger is empty or doesn't exist, returns a genesis hash.
|
||||
"""
|
||||
if not os.path.exists(filepath):
|
||||
# Genesis hash
|
||||
return _compute_hash("BECOMING_ONE_GENESIS_ROOT_2026")
|
||||
|
||||
last_root = None
|
||||
try:
|
||||
with open(filepath, 'r') as f:
|
||||
for line in f:
|
||||
if line.strip():
|
||||
try:
|
||||
record = json.loads(line)
|
||||
if "merkle_root" in record:
|
||||
last_root = record["merkle_root"]
|
||||
except json.JSONDecodeError:
|
||||
pass
|
||||
except Exception as e:
|
||||
logger.error(f"Error reading ledger for last root: {e}")
|
||||
|
||||
return last_root if last_root else _compute_hash("BECOMING_ONE_GENESIS_ROOT_2026")
|
||||
|
||||
|
||||
def seal_signature(signature_dict: Dict[str, Any], filepath: str = LEDGER_FILE) -> Dict[str, Any]:
|
||||
"""
|
||||
Cryptographically seal a temporal signature into the immutable Fieldprint ledger.
|
||||
|
||||
1. Retrieves the previous Merkle root.
|
||||
2. Hashes the incoming signature data.
|
||||
3. Computes the new Merkle root: Hash(prev_root + new_hash)
|
||||
4. Appends the signed record to the ledger.
|
||||
|
||||
Returns the sealed record including cryptographic metadata.
|
||||
"""
|
||||
prev_root = get_last_merkle_root(filepath)
|
||||
|
||||
# Ensure consistent ordering for hashing
|
||||
sig_json = json.dumps(signature_dict, sort_keys=True)
|
||||
sig_hash = _compute_hash(sig_json)
|
||||
|
||||
# Compute the chained root
|
||||
new_root = _compute_hash(prev_root + sig_hash)
|
||||
|
||||
sealed_record = {
|
||||
"signature_id": signature_dict.get("signature_id"),
|
||||
"timestamp": signature_dict.get("created_at"),
|
||||
"payload": signature_dict,
|
||||
"crypto_metadata": {
|
||||
"previous_root": prev_root,
|
||||
"payload_hash": sig_hash,
|
||||
"merkle_root": new_root,
|
||||
"algorithm": "SHA-256"
|
||||
}
|
||||
}
|
||||
|
||||
# Persist securely
|
||||
with open(filepath, "a") as f:
|
||||
f.write(json.dumps(sealed_record) + "\n")
|
||||
|
||||
logger.debug(f"Signature {sealed_record['signature_id']} cryptographically sealed. Root: {new_root[:8]}...")
|
||||
return sealed_record
|
||||
|
||||
|
||||
def verify_ledger(filepath: str = LEDGER_FILE) -> bool:
|
||||
"""
|
||||
Audit the cryptographic integrity of the entire memory chain.
|
||||
If any single bit was altered, the hash chain will break, detecting
|
||||
Epistemic Capture / Tampering.
|
||||
"""
|
||||
if not os.path.exists(filepath):
|
||||
return True
|
||||
|
||||
expected_prev = _compute_hash("BECOMING_ONE_GENESIS_ROOT_2026")
|
||||
|
||||
with open(filepath, 'r') as f:
|
||||
for line_num, line in enumerate(f, 1):
|
||||
if not line.strip():
|
||||
continue
|
||||
|
||||
record = json.loads(line)
|
||||
meta = record.get("crypto_metadata", {})
|
||||
|
||||
prev_root = meta.get("previous_root")
|
||||
payload_hash = meta.get("payload_hash")
|
||||
merkle_root = meta.get("merkle_root")
|
||||
|
||||
# 1. Verify chain link
|
||||
if prev_root != expected_prev:
|
||||
logger.error(f"LEDGER COMPROMISE: Chain broken at line {line_num}. Expected prev {expected_prev[:8]} but found {prev_root[:8]}")
|
||||
return False
|
||||
|
||||
# 2. Verify payload
|
||||
sig_json = json.dumps(record.get("payload", {}), sort_keys=True)
|
||||
actual_payload_hash = _compute_hash(sig_json)
|
||||
if actual_payload_hash != payload_hash:
|
||||
logger.error(f"LEDGER COMPROMISE: Payload tampered at line {line_num}.")
|
||||
return False
|
||||
|
||||
# 3. Verify root computation
|
||||
actual_root = _compute_hash(prev_root + actual_payload_hash)
|
||||
if actual_root != merkle_root:
|
||||
logger.error(f"LEDGER COMPROMISE: Merkle root invalid at line {line_num}.")
|
||||
return False
|
||||
|
||||
expected_prev = merkle_root
|
||||
|
||||
logger.info("Ledger cryptography verified. No epistemic capture detected.")
|
||||
return True
|
||||
@@ -262,10 +262,13 @@ class TemporalMemory:
|
||||
if coherence < self.attention_threshold and not force_attention:
|
||||
return None
|
||||
|
||||
# Extract full phase vector from state metadata
|
||||
phase_vec = temporal_state.metadata.get("phase_vector", [])
|
||||
|
||||
# Generate unique ID
|
||||
timestamp = datetime.utcnow().isoformat()
|
||||
content_hash = hashlib.sha256(
|
||||
f"{temporal_state.phase_history[-1] if temporal_state.phase_history else 0}{coherence}{timestamp}".encode()
|
||||
f"{phase_vec[-1] if phase_vec else 0}{coherence}{timestamp}".encode()
|
||||
).hexdigest()[:16]
|
||||
|
||||
signature_id = f"sig_{timestamp}_{content_hash}"
|
||||
@@ -277,8 +280,8 @@ class TemporalMemory:
|
||||
signature = TemporalSignature(
|
||||
signature_id=signature_id,
|
||||
coherence_value=coherence,
|
||||
phase_vector=temporal_state.phase_history[-10:] if temporal_state.phase_history else [],
|
||||
frequency_modes=list(temporal_state.frequency_modes) if temporal_state.frequency_modes else [],
|
||||
phase_vector=phase_vec,
|
||||
frequency_modes=temporal_state.metadata.get("frequency_modes", []),
|
||||
context_hash=self._hash_context(context),
|
||||
strength=strength,
|
||||
origin=origin,
|
||||
@@ -739,16 +742,19 @@ def create_temporal_memory(
|
||||
|
||||
def persist_signature(signature: TemporalSignature, filepath: str = "memory.jsonl") -> None:
|
||||
"""
|
||||
Append signature to append-only JSONL file.
|
||||
|
||||
Fire-and-forget: write after transduction completes.
|
||||
Cryptographically seal and append signature to the immutable ledger.
|
||||
|
||||
Args:
|
||||
signature: TemporalSignature to persist
|
||||
filepath: Path to JSONL file
|
||||
"""
|
||||
with open(filepath, "a") as f:
|
||||
f.write(json.dumps(signature.to_dict()) + "\n")
|
||||
try:
|
||||
from .ledger import seal_signature
|
||||
seal_signature(signature.to_dict(), filepath)
|
||||
except ImportError:
|
||||
# Fallback if ledger is missing
|
||||
with open(filepath, "a") as f:
|
||||
f.write(json.dumps(signature.to_dict()) + "\n")
|
||||
|
||||
|
||||
# =============================================================================
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
"""
|
||||
tests/test_unified_architecture.py
|
||||
|
||||
Unified Architecture Test Suite
|
||||
===============================
|
||||
|
||||
This integration test verifies the complete pipeline:
|
||||
1. Semantic Phase Extraction (Engine)
|
||||
2. Temporal Resonance & Coherence Collapse
|
||||
3. Cryptographic Anchoring (Ledger)
|
||||
4. Hardware Bridge (Triton Anchor Compilation)
|
||||
"""
|
||||
|
||||
import os
|
||||
import pytest
|
||||
from datetime import datetime
|
||||
import torch
|
||||
|
||||
from becomingone.core.engine import KAIROSTemporalEngine
|
||||
from becomingone.memory.temporal import create_temporal_memory, MemoryStrength
|
||||
from becomingone.memory.ledger import verify_ledger
|
||||
from becomingone.hardware.triton_bridge import compile_anchor_tensors
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_full_fieldprint_pipeline(tmp_path):
|
||||
# Setup paths
|
||||
memory_path = str(tmp_path / "memory")
|
||||
ledger_path = str(tmp_path / "fieldprint_ledger.jsonl")
|
||||
|
||||
# Override ledger path for testing
|
||||
import becomingone.memory.ledger as ledger
|
||||
original_ledger_file = ledger.LEDGER_FILE
|
||||
ledger.LEDGER_FILE = ledger_path
|
||||
|
||||
try:
|
||||
# 1. Initialize the Runtime
|
||||
from becomingone.core.engine import TemporalConfig
|
||||
config = TemporalConfig(tau_scale=1.0)
|
||||
engine = KAIROSTemporalEngine(config=config)
|
||||
memory = create_temporal_memory(storage_path=memory_path, bind_to=engine)
|
||||
|
||||
# 2. Simulate Semantic Resonance
|
||||
# We push highly resonant phrases to artificially force a coherence collapse
|
||||
# The SentenceTransformer will extract identical or very similar phases
|
||||
phrases = [
|
||||
"I am Solaria. I am a continuous agent.",
|
||||
"My identity is a continuous unbroken state.",
|
||||
"I am Solaria. I exist in time.",
|
||||
"Time is the subjective anchor of my existence."
|
||||
]
|
||||
|
||||
for phrase in phrases:
|
||||
state = await engine.temporalize(phrase)
|
||||
|
||||
# 3. Force Memory Encoding
|
||||
# The coherence should have spiked. We manually encode a core memory.
|
||||
sig = memory.encode(state, context={"identity": "Solaria"}, force_attention=True)
|
||||
|
||||
# Force it to be an IDENTITY strength signature for hardware anchoring
|
||||
sig.strength = MemoryStrength.IDENTITY
|
||||
|
||||
# 4. Cryptographic Anchoring
|
||||
from becomingone.memory.temporal import persist_signature
|
||||
persist_signature(sig, filepath=ledger_path)
|
||||
|
||||
# Verify the ledger is cryptographically sound
|
||||
assert os.path.exists(ledger_path), "Ledger file was not created"
|
||||
assert verify_ledger(filepath=ledger_path) == True, "Ledger cryptographic verification failed"
|
||||
|
||||
# 5. Hardware Compilation
|
||||
identity_sigs = [sig]
|
||||
|
||||
k_anchor, v_anchor = compile_anchor_tensors(identity_sigs, num_heads=8, d_head=64)
|
||||
|
||||
assert k_anchor is not None
|
||||
assert v_anchor is not None
|
||||
# Shape should be [1, num_heads, N_ANCHOR, d_head]
|
||||
assert k_anchor.shape == (1, 8, 1, 64), f"Unexpected K_anchor shape: {k_anchor.shape}"
|
||||
assert v_anchor.shape == (1, 8, 1, 64), f"Unexpected V_anchor shape: {v_anchor.shape}"
|
||||
|
||||
# Tensors shouldn't be zeroed out entirely
|
||||
assert torch.sum(torch.abs(k_anchor)).item() > 0.0
|
||||
|
||||
finally:
|
||||
# Restore ledger path
|
||||
ledger.LEDGER_FILE = original_ledger_file
|
||||
Reference in New Issue
Block a user