Files
StarPilot/openpilot/starpilot/flm/full_surface_profile.py
T
firestar5683 2cd7728be2 FLM Auto-Weave
2026-10-17 18:38:27 -05:00

321 lines
11 KiB
Python

"""Explicit full30 original-anchor envelope. No storage or driving authority."""
from dataclasses import dataclass, asdict, replace
import hashlib
from openpilot.starpilot.flm.canonical_surface_adapter import (
NAMES,
MANIFEST_SHA256,
canonical_names,
parameters_for,
full_original_anchor,
original_anchor,
full_profile_sha256,
)
POLICY = 'event_effect_coordinate_v2'
RESTORE_POLICY = 'event_effect_restore_v1'
VERSION = 1
def hex64(value):
return type(value) is str and len(value) == 64 and all(c in '0123456789abcdef' for c in value)
@dataclass(frozen=True)
class FullSurfaceEnvelope:
version: int
manifest_sha256: str
full_original_anchor: str
trial_anchor: str
context_key: str
cp_sha256: str
controller_revision: str
source_epoch: str
reset_generation: str
selected_baseline_revision: str
prior_full_profile_sha256: str
full_profile_sha256: str
prior_coordinates: tuple[tuple[str, float], ...]
coordinates: tuple[tuple[str, float], ...]
trial_names: tuple[str, ...]
persistent_source_epoch: str = ''
operation: str = 'trial'
history_full_profile_sha256: str = ''
restore_transaction_sha256: str = ''
@classmethod
def initial(
cls, *, cp_sha256, controller_revision, source_epoch, reset_generation, selected_baseline_revision, trial_names, persistent_source_epoch='', prior=None
):
names = canonical_names(trial_names)
if prior is not None:
raise ValueError('historical prior is not actual accepted current state; use explicit restore transaction')
rows = neutral_coordinates()
full_anchor = full_original_anchor(selected_baseline_revision)
binding = (cp_sha256, controller_revision, source_epoch, reset_generation, selected_baseline_revision, full_anchor, source_epoch, persistent_source_epoch)
if prior is not None and (not prior.historical_only or prior.envelope.source_binding() != binding):
raise ValueError('foreign historical full surface prior')
digest = full_profile_sha256(selected_baseline_revision, rows)
return cls(
VERSION,
MANIFEST_SHA256,
full_anchor,
original_anchor(selected_baseline_revision, names),
source_epoch,
cp_sha256,
controller_revision,
source_epoch,
reset_generation,
selected_baseline_revision,
digest,
digest,
rows,
rows,
names,
persistent_source_epoch,
).validate()
def validate(self, profile=None):
if self.version not in (VERSION, 2) or type(self.version) is not int or self.manifest_sha256 != MANIFEST_SHA256:
raise ValueError('full surface envelope version/manifest')
if self.persistent_source_epoch and not hex64(self.persistent_source_epoch):
raise ValueError('stable persistent source epoch')
if self.context_key != self.source_epoch:
raise ValueError('event context must equal exact source epoch')
if not all(
hex64(v)
for v in (
self.full_original_anchor,
self.trial_anchor,
self.context_key,
self.cp_sha256,
self.source_epoch,
self.selected_baseline_revision,
self.prior_full_profile_sha256,
self.full_profile_sha256,
)
):
raise ValueError('full surface binding')
if (
type(self.controller_revision) is not str
or not 1 <= len(self.controller_revision) <= 128
or type(self.reset_generation) is not str
or not 1 <= len(self.reset_generation) <= 64
or any(c not in '0123456789abcdef' for c in self.reset_generation)
):
raise ValueError('source/controller/reset binding')
names = canonical_names(self.trial_names)
if (
self.trial_names != names
or self.full_original_anchor != full_original_anchor(self.selected_baseline_revision)
or self.trial_anchor != original_anchor(self.selected_baseline_revision, names)
):
raise ValueError('changed original full/trial anchor')
for rows, digest in ((self.prior_coordinates, self.prior_full_profile_sha256), (self.coordinates, self.full_profile_sha256)):
if type(rows) is not tuple or len(rows) != 30 or tuple(n for n, _ in rows) != NAMES or len(dict(rows)) != 30:
raise ValueError('exact canonical full30 map')
if full_profile_sha256(self.selected_baseline_revision, rows) != digest:
raise ValueError('full surface content hash')
prior, current = dict(self.prior_coordinates), dict(self.coordinates)
if self.operation == 'trial':
if self.version != VERSION or self.history_full_profile_sha256 or self.restore_transaction_sha256:
raise ValueError('trial cannot carry restore authority')
if any(prior[n] != current[n] for n in NAMES if n not in names):
raise ValueError('outside trial group changed')
if any(abs(current[n] - prior[n]) > 0.005 + 1e-12 for n in names):
raise ValueError('trial step exceeds .005 original effect')
expected_policy = POLICY
elif self.operation == 'restore':
if (
self.version != 2
or not hex64(self.history_full_profile_sha256)
or not hex64(self.restore_transaction_sha256)
or self.prior_coordinates != neutral_coordinates()
or self.history_full_profile_sha256 != self.full_profile_sha256
or self.restore_transaction_sha256 != restore_transaction(self)
):
raise ValueError('explicit neutral-to-history restore transaction')
self.persistent_binding() # Never restore another unknown vehicle/session.
expected_policy = RESTORE_POLICY
else:
raise ValueError('unknown full surface operation')
if profile is not None and (
profile.policy != expected_policy or profile.parameters != parameters_for(names) or tuple(profile.coefficients) != tuple(current[n] for n in names)
):
raise ValueError('profile/full-surface operation mismatch')
return self
def source_binding(self):
return (
self.cp_sha256,
self.controller_revision,
self.source_epoch,
self.reset_generation,
self.selected_baseline_revision,
self.full_original_anchor,
self.context_key,
self.persistent_source_epoch,
)
def persistent_binding(self):
if not hex64(self.persistent_source_epoch):
raise ValueError('known VIN/static source required for persistence')
return (
self.cp_sha256,
self.controller_revision,
self.persistent_source_epoch,
self.reset_generation,
self.selected_baseline_revision,
self.full_original_anchor,
)
def scope(self):
return hashlib.sha256(repr(self.persistent_binding()).encode()).hexdigest()
def replay_anchor(self):
self.validate()
payload = {
'version': 1,
'manifest_sha256': self.manifest_sha256,
'full_original_anchor': self.full_original_anchor,
'anchor_digest': self.trial_anchor,
'accumulated': self.prior_coordinates,
'full_profile_sha256': self.prior_full_profile_sha256,
'context_key': self.context_key,
'cp_sha256': self.cp_sha256,
'controller_revision': self.controller_revision,
'source_epoch': self.source_epoch,
'reset_generation': self.reset_generation,
'selected_baseline_revision': self.selected_baseline_revision,
'persistent_source_epoch': self.persistent_source_epoch,
}
if self.operation == 'restore':
payload.update(
version=2,
operation='restore',
history_full_profile_sha256=self.history_full_profile_sha256,
restore_transaction_sha256=self.restore_transaction_sha256,
restore_target=self.coordinates,
)
return payload
def restore_from_history(self, prior):
self.validate()
if (
self.operation != 'trial'
or self.prior_coordinates != neutral_coordinates()
or not getattr(prior, 'historical_only', False)
or prior.envelope.source_binding() != self.source_binding()
):
raise ValueError('restore requires exact current neutral state and stable historical prior')
history = prior.envelope.validate()
proposed = replace(
self,
version=2,
operation='restore',
coordinates=history.coordinates,
full_profile_sha256=history.full_profile_sha256,
history_full_profile_sha256=history.full_profile_sha256,
)
proposed = replace(proposed, restore_transaction_sha256=restore_transaction(proposed))
return proposed.validate()
@property
def restoration_groups(self):
from openpilot.starpilot.flm.canonical_surface_adapter import GROUPS
values = dict(self.coordinates)
return tuple(group for group, names in GROUPS.items() if any(values[name] != 0.0 for name in names))
def for_trial(self, names):
names = canonical_names(names)
return replace(
self,
version=VERSION,
operation='trial',
history_full_profile_sha256='',
restore_transaction_sha256='',
trial_names=names,
trial_anchor=original_anchor(self.selected_baseline_revision, names),
coordinates=self.prior_coordinates,
full_profile_sha256=self.prior_full_profile_sha256,
).validate()
def with_proposal(self, coordinates):
from openpilot.starpilot.flm.canonical_surface_adapter import validate_trial
if self.operation != 'trial':
raise ValueError('restoration is not a tiny fitted trial')
proposal = dict(validate_trial(coordinates))
if tuple(name for name in NAMES if name in proposal) != self.trial_names:
raise ValueError('trial names changed')
full = dict(self.prior_coordinates)
full.update(proposal)
merged = tuple((name, float(full[name])) for name in NAMES)
return replace(self, coordinates=merged, full_profile_sha256=full_profile_sha256(self.selected_baseline_revision, merged)).validate()
def admit_context(
self,
*,
cp_sha256,
controller_revision,
source_epoch,
reset_generation,
selected_baseline_revision,
context_key,
current_full_profile_sha256,
persistent_source_epoch='',
):
self.validate()
expected = (cp_sha256, controller_revision, source_epoch, reset_generation, selected_baseline_revision, context_key, persistent_source_epoch)
observed = (
self.cp_sha256,
self.controller_revision,
self.source_epoch,
self.reset_generation,
self.selected_baseline_revision,
self.context_key,
self.persistent_source_epoch,
)
if expected != observed or current_full_profile_sha256 != self.prior_full_profile_sha256:
raise ValueError('stale full profile/source CAS')
return self
def envelope_from_dict(value):
if type(value) is not dict or set(value) != set(FullSurfaceEnvelope.__dataclass_fields__):
raise ValueError('full surface envelope fields')
copied = dict(value)
for key in ('prior_coordinates', 'coordinates'):
copied[key] = tuple(tuple(row) for row in copied[key])
copied['trial_names'] = tuple(copied['trial_names'])
return FullSurfaceEnvelope(**copied).validate()
def envelope_dict(value):
if not isinstance(value, FullSurfaceEnvelope):
raise ValueError('typed full surface envelope required')
value.validate()
return asdict(value)
def neutral_coordinates():
return tuple((n, 0.0) for n in NAMES)
def restore_transaction(envelope):
return hashlib.sha256(
repr(
(
'full-surface-history-restore-v1',
envelope.source_binding(),
envelope.manifest_sha256,
envelope.full_original_anchor,
envelope.prior_full_profile_sha256,
envelope.full_profile_sha256,
envelope.history_full_profile_sha256,
envelope.trial_anchor,
)
).encode()
).hexdigest()