Files
StarPilot/openpilot/starpilot/flm/live_tracking_actor.py

967 lines
48 KiB
Python

"""Response bootstrap and live observation actor; no Controls or native owner.
No production bootstrap policy is inferred from the diagnostic180-second limit.
The daemon supplies a separately qualified process, otherwise collection holds.
"""
from dataclasses import replace
from typing import cast
from openpilot.starpilot.flm.canonical_surface_adapter import NAMES, full_profile_sha256
from openpilot.starpilot.flm.live_trial_contract import LiveTrialBinding
from openpilot.starpilot.flm.live_tracking_ingress import LiveTrackingIngress
from openpilot.starpilot.flm.live_tracking_response import certificate_from_dict, validate_certificate, validate_response_witness
def _observed_probe_candidates(
ready,
prefix,
points,
*,
after_ns,
verify_limited=None,
checkpoint_indices=None,
stratified=False,
same_checkpoint=False,
phase_windows=(),
phase_fallback_after_ns=None,
fresh_limit=4,
discovery_headroom=False,
):
"""Only distinct original emissions with actual independent endpoints."""
if type(discovery_headroom) is not bool:
raise ValueError('explicit numerical discovery sampling policy required')
if type(fresh_limit) is not int or not 1 <= fresh_limit <= 4:
raise ValueError('one to four original numerical endpoints')
by_stamp = {row.control_ns: (index, row) for index, row in enumerate(prefix)}
eligible = []
starts = (0,) if checkpoint_indices is None else tuple(checkpoint_indices)
for control, output in reversed(ready):
entry = by_stamp.get(control.control_ns)
if (
entry is None
or control.control_ns <= after_ns
or (control.control_ns, output.apply_ns) not in points
or output.limited
and (verify_limited is None or not verify_limited(control, output))
or control != entry[1]
or any(control.control_ns == row[0].control_ns for row in eligible)
):
continue
anchors = tuple(index for index in starts if 0 <= index <= entry[0])
if not anchors:
continue
original_prefix = prefix[anchors[-1] : entry[0] + 1]
if not 1 <= len(original_prefix) <= 100:
continue
eligible.append((control, output, original_prefix))
if phase_windows:
for first, last, requested in phase_windows:
if not first < last:
continue
def phase(stamp, first=first, last=last):
return min(3, (stamp - first) * 4 // (last - first + 1))
missing = set(range(4)) - {phase(stamp) for stamp in requested if first <= stamp <= last}
buckets = {
slot: [row for row in eligible if first <= row[0].control_ns <= last and row[0].control_ns not in requested and phase(row[0].control_ns) == slot]
for slot in missing
}
# Do not spend bounded work on a window whose missing phase is no
# longer available under the ORIGINAL source/replay/age requirements.
if not missing or any(not values for values in buckets.values()):
continue
chosen = [
min(values, key=lambda row: (row[1].limited, abs(8 * (row[0].control_ns - first) - (2 * slot + 1) * (last - first + 1)), row[0].control_ns))
for slot, values in sorted(buckets.items())
]
return tuple(sorted(chosen, key=lambda row: row[0].control_ns))
if phase_fallback_after_ns is None:
return ()
eligible = [row for row in eligible if row[0].control_ns > phase_fallback_after_ns]
if discovery_headroom and fresh_limit == 1 and eligible:
# Bound serial live-stream work to one recent original measurement.
# Closed-window repairs above still request every missing time stratum.
return (min(eligible, key=lambda row: (row[1].limited, -row[0].control_ns)),)
if same_checkpoint and eligible:
# Each batch must retain one genuine original checkpoint. Process the
# earliest available one first, so its watermark cannot skip a newer one.
first_checkpoint = min(row[2][0].control_ns for row in eligible)
eligible = [row for row in eligible if row[2][0].control_ns == first_checkpoint]
# Prefer real original headroom BEFORE computing any perturbation or loss.
# A native-clipped endpoint still contributes when its original CAN proof is
# complete; no missing observation, changed limit, or numerical effect is filled.
if stratified and len(eligible) > 4:
first = min(row[0].control_ns for row in eligible)
last = max(row[0].control_ns for row in eligible)
selected = []
for slot in range(4):
bucket = [row for row in eligible if min(3, (row[0].control_ns - first) * 4 // (last - first + 1)) == slot]
if bucket:
selected.append(min(bucket, key=lambda row: (row[1].limited if discovery_headroom else False, row[0].control_ns)))
if len(selected) < 4:
remaining = [row for row in eligible if all(row[0].control_ns != used[0].control_ns for used in selected)]
remaining.sort(key=lambda row: row[0].control_ns)
selected.extend(remaining[: 4 - len(selected)])
else:
eligible.sort(key=lambda row: row[1].limited)
selected = eligible[:4]
selected = tuple(sorted(selected, key=lambda row: row[0].control_ns))
if len(selected) > fresh_limit:
# Clock-stratified work only. Missing whole-window phases are repaired
# above without this fresh-stream cap; the original four-point proof stays.
if discovery_headroom:
# Discovery needs observable native response. Choose only among original
# clock strata using limiter flags; no error, estimate or trial outcome
# is read. This never filters the whole physical comparison score.
from itertools import combinations
return min(
combinations(selected, fresh_limit),
key=lambda rows: (sum(row[1].limited for row in rows), -(rows[-1][0].control_ns - rows[0][0].control_ns), tuple(row[0].control_ns for row in rows)),
)
indices = (len(selected) - 1,) if fresh_limit == 1 else tuple(i * (len(selected) - 1) // (fresh_limit - 1) for i in range(fresh_limit))
return tuple(selected[i] for i in indices)
return selected
def _original_probe_windows(episodes, profile_hash, group, names):
"""Closed ORIGINAL geometry may queue numbers before the last lagged pose.
Every selected endpoint must ALREADY have its own independent physical pair.
Whole-episode publication still waits for the unchanged full pose watermark.
"""
windows = []
for row in episodes.completed.values():
if row['episode'].profile_sha256 == profile_hash and row['group'] == group and row['names'] == names:
windows.append((min(p.control_ns for p in row['points']), max(p.control_ns for p in row['points']), frozenset(row['requested'])))
for start, end, kind, _direction, profile in episodes.pending:
if kind not in ('large', 'subtle') or profile != profile_hash:
continue
source_tracking = getattr(episodes, 'source_tracking', False)
points = tuple(point for point in episodes.endpoints if start <= (point.reference_ns if source_tracking else point.control_ns) <= end)
original_controls = {point.control_ns for point in points}
requests = (
{stamp: value for stamp, value in episodes.probe_requests.items() if stamp in original_controls}
if source_tracking
else {stamp: value for stamp, value in episodes.probe_requests.items() if start <= stamp <= end}
)
if len(points) < 4 or any(value[:2] != (group, names) for value in requests.values()):
continue
# Source windows use their reference clock for membership, then retain
# each paired ORIGINAL command clock for actual native probe coverage.
# No point or command is moved/restamped to fit the new window boundary.
last = max(point.control_ns for point in points) if source_tracking else end
windows.append((min(p.control_ns for p in points), last, frozenset(requests)))
return tuple(sorted(windows, key=lambda row: row[0]))
def _group_direction_matches(group, kind, direction):
# A large maneuver has one steering direction; opposite-side hooks are
# correctly neutral there. A subtle weave contains both directions.
from openpilot.starpilot.flm.live_tracking import _group_direction_matches as matches
return matches(group, kind, direction)
def _probe_group_coverage(rows, names, *, kind, direction):
from openpilot.starpilot.flm.live_tracking import _required
matched = tuple(row for row in rows if row.kind == kind and row.direction == direction and getattr(row, 'native_gradient_complete', False))
counts = {
name: sum(
any(
feature.name == name
and feature.feature_energy > 1e-10
and feature.native_endpoints >= 4
and feature.native_separated / feature.native_endpoints >= 0.09
for feature in row.sensitivity
)
for row in matched
)
for name in names
}
# One unexcited maneuver never establishes that a hook cannot affect this car.
# Count repeated WHOLE matching maneuvers, retaining the original3/9 protocol.
unexcited = sum(
all(any(feature.name == name and feature.native_endpoints >= 4 and feature.feature_energy <= 1e-10 for feature in row.sensitivity) for name in names)
for row in matched
)
return max(counts.values(), default=0), not any(counts.values()) and unexcited >= _required(kind)
class LiveTrackingActor:
def __init__(self, bootstrap_process=None, *, probe_process=None, source_tracking=False):
if type(source_tracking) is not bool or source_tracking and bootstrap_process is not None:
raise ValueError('source tracking has no plant bootstrap process')
self.source_tracking = source_tracking
self.process = bootstrap_process
from openpilot.starpilot.flm.live_tracking_bootstrap_producer import ResponseSnapshotProcess
self.snapshot_process = ResponseSnapshotProcess()
self.probe_preparation = ResponseSnapshotProcess()
self.probe_process = probe_process
self.probe_token = None
self.last_probe_control_ns = 0
self.last_decode_ns = 0
self.probe_queue = []
self.probe_queue_key = None
self.probe_group_index = self.probe_group_samples = 0
self.probe_group_epoch = None
self.probe_group_profile = None
self.ingress = self.certificate = self.application = None
self.seed = self.token = self.attempted_epoch = None
self.pending_bootstrap_result = None
self.pending_probe_results = []
self.prepared_probe_context = None
self.reason = 'response_model_required'
self.diagnostic_result = None
self.last_publication_pose_ns = 0
self.initial_basis = None
self.restore_pending = False
self.response_recovery_generation = 0
self.native_key = self.hardware_inventory = ()
def interrupt(self, reason, *, context_changed=False):
state = None if self.ingress is None else self.ingress.optimizer.offer_state
retain_numeric = bool(not context_changed and self.seed is not None and self.token is not None and (state is None or state.get('accepted') is True))
# An immutable numerical job keeps its ORIGINAL token and deadline. This
# preserves no current source/native witness, active trial or command lease.
if not retain_numeric:
self.pending_probe_results.clear()
self.pending_bootstrap_result = None
self.snapshot_process.cancel(reason)
self.probe_preparation.cancel(reason)
if self.process is not None:
self.process.cancel(reason)
if self.probe_process is not None:
self.probe_process.cancel(reason)
self.probe_token = None
self.prepared_probe_context = None
self.probe_queue.clear()
self.probe_queue_key = None
if self.ingress is not None:
self.ingress.interrupt(reason, context_changed=context_changed, preserve_completed=retain_numeric)
self.reason = reason
def close(self, reason='live_tracking_actor_closed'):
self.pending_probe_results.clear()
self.pending_bootstrap_result = None
# Shutdown may wait for actual reaping; tick/interrupt only cancel/poll.
# Always attempt both reapers, including when one fails unexpectedly.
failure = None
closed = True
for process in (self.snapshot_process, self.probe_preparation, self.process, self.probe_process):
if process is not None:
try:
closed = process.close(reason) and closed
except BaseException as error:
if failure is None:
failure = error
closed = False
self.probe_token = None
self.prepared_probe_context = None
self.probe_queue.clear()
self.probe_queue_key = None
if self.ingress is not None:
self.ingress.interrupt(reason, context_changed=True)
self.reason = reason
if failure is not None:
raise failure
return closed
@property
def pending(self):
return any(process is not None and process.child is not None for process in (self.process, self.probe_process))
def binding_for(self, collector, source):
from openpilot.starpilot.flm.runtime_adapter_registry import digest, control_vm_regime
control = collector.ready[-1][0]
anchor = control.vehicle_model_anchor
if len(anchor) != 3 or control_vm_regime(control) != anchor:
raise ValueError('genuine current owner vehicle-model anchor required')
return LiveTrialBinding(
control.identity,
source.cp_sha256,
control.controller_revision,
control.baseline_revision,
source.source_epoch,
source.reset,
source.calibration_generation,
digest(anchor),
control.native_identity if control.native_required else '',
'bootstrap-pending-v1',
source.persistent_source_epoch,
control.native_required,
).validate()
def adopt_response(self, certificate, collector, accepted_full30=None):
if self.process is not None and self.process.child is not None:
self.process.cancel('independently_qualified_response_available')
certificate = validate_certificate(certificate)
if self.seed is None or replace(certificate.binding, physical_model_revision=self.seed.physical_model_revision) != self.seed:
raise ValueError('bootstrap response belongs to another current source')
accepted = tuple((name, 0.0) for name in NAMES) if accepted_full30 is None else accepted_full30
self.ingress = LiveTrackingIngress(certificate.binding, certificate, accepted, controller_domain=collector.adapter.command_family)
self.certificate = certificate
collector.adapter.replay.source_controller_revision = collector.adapter.controller_revision
self.ingress.replay = collector.adapter.replay
self.ingress.episodes.replay = collector.adapter.replay
self.probe_token = None
self.last_probe_control_ns = 0
collector.live_tracking = self.ingress
self.ingress.scoring_enabled = not self.restore_pending
from openpilot.starpilot.flm.live_tracking_requalification import basis_from_pose
try:
pose = collector.original_source_capture.rows[-1]
self.initial_basis = basis_from_pose(
certificate.binding, pose, now_ns=pose.completed_ns, native_key=self.native_key, hardware_inventory=self.hardware_inventory
)
except (AttributeError, IndexError, TypeError, ValueError):
# Missing hardware provenance withholds cross-drive persistence, not
# otherwise valid within-drive learning/current physical monitoring.
self.initial_basis = None
from openpilot.starpilot.flm.live_tracking_response import TrackingSourceContext
self.reason = 'fresh_current_source_window_required' if type(certificate) is TrackingSourceContext else 'fresh_physical_residual_window_required'
def hold_restore(self, pending):
self.restore_pending = bool(pending)
if self.ingress is not None:
self.ingress.scoring_enabled = not self.restore_pending
if self.restore_pending:
self.ingress.optimizer.interrupt('historical_restore_pending')
def _submit_probe_queue(self, token, now_ns):
from openpilot.starpilot.flm.live_tracking_probe_process import make_probe_batch
# The aggregate literal snapshot bound also applies to a batch. Split only
# numerical work; four genuine endpoints per episode remain mandatory.
for count in range(len(self.probe_queue), 0, -1):
try:
batch = make_probe_batch(tuple(item[0] for item in self.probe_queue[:count]), queued_ns=now_ns)
except ValueError:
continue
if self.probe_process.submit_probe(batch, token=token, now_ns=now_ns):
self.probe_token = token
del self.probe_queue[:count]
if not self.probe_queue:
self.probe_queue_key = None
return True
return False
self.probe_queue.clear()
self.probe_queue_key = None
self.reason = 'bounded_numerical_probe_transport_unavailable'
return False
def _probe_tick(self, collector, source, *, now_ns):
"""Queue optional numerical work; never update a controller in this actor."""
if self.probe_process is None or self.ingress is None:
return
if self.restore_pending:
self.probe_process.poll(token=None, now_ns=now_ns)
self.probe_queue.clear()
self.probe_queue_key = None
return
from openpilot.starpilot.flm.live_tracking_probe_process import make_probe_job, probe_replay_snapshot
if self.process is not None and self.process.child is not None:
return # At most one optional reconstruction/identification child.
optimizer = self.ingress.optimizer
self.reason = optimizer.reason
accepted = tuple((name, optimizer.accepted[name]) for name in NAMES)
profile_hash = full_profile_sha256(self.certificate.binding.baseline_revision, dict(accepted))
token = (self.token, self.certificate.model_revision, profile_hash)
try:
result = self.probe_process.poll_probe(token=token, binding=self.certificate.binding, now_ns=now_ns)
completed, self.pending_probe_results = self.pending_probe_results, []
if result is not None:
completed.append(result)
for result in completed:
for row in result if type(result) is tuple else (result,):
self.ingress.observe_probe(row, now_ns=now_ns)
self.probe_group_samples += 1
from openpilot.starpilot.flm.live_tracking import discovery_needs_probes
if optimizer.discovery is not None and not discovery_needs_probes(optimizer.discovery):
# Direction/coordinate selection already has genuine native probes.
# Its NEW uncensored baseline needs measured episodes, not another
# finite-difference replay of each endpoint. Reap optional old work
# nonblocking; no original samples or native grants are synthesized.
self.probe_preparation.cancel('independent_measurement_comparison')
self.probe_process.cancel('independent_measurement_comparison')
self.probe_queue.clear()
self.probe_queue_key = self.prepared_probe_context = self.probe_token = None
return
# Do not consume a one-shot prepared result while the numerical child
# cannot accept it. The original enqueue time/deadline remains binding;
# one existing preparation pipe holds it without blocking ingestion.
prepared = self.probe_preparation.poll(token=token, now_ns=now_ns) if self.probe_process.child is None else None
if prepared is not None and prepared.get('numeric') is not None:
expected, self.prepared_probe_context = self.prepared_probe_context, None
from openpilot.starpilot.flm.live_tracking_probe_process import _context_digest
if (
expected is None
or set(prepared) != {'numeric', 'job_sha256', 'context_sha256'}
or prepared['context_sha256'] != _context_digest(expected)
or type(prepared['job_sha256']) is not str
or len(prepared['job_sha256']) != 64
or any(char not in '0123456789abcdef' for char in prepared['job_sha256'])
or any(not 0 < row['queued_ns'] <= now_ns <= row['queued_ns'] + 30_000_000_000 for row in expected['batch'])
):
raise ValueError('owned inline numerical context or deadline differs')
numeric = self.probe_process.decode_report(
prepared['numeric'], expected=(prepared['job_sha256'], expected), prepared_sha=prepared['context_sha256'], binding=self.certificate.binding
)
for row in numeric if type(numeric) is tuple else (numeric,):
self.ingress.observe_probe(row, now_ns=now_ns)
self.probe_group_samples += 1
if prepared is not None and prepared.get('prepared') is not None:
expected, self.prepared_probe_context = self.prepared_probe_context, None
if expected is None:
raise ValueError('original parent numerical context unavailable')
if self.probe_process.submit_prepared_probe(prepared['prepared'], expected=expected, token=token, now_ns=now_ns):
self.probe_token = token
if self.probe_preparation.pid is not None:
return
if self.probe_queue and (cast(tuple[object, ...], self.probe_queue_key)[0] != token or now_ns - self.probe_queue[0][1] > 2_000_000_000):
self.probe_queue.clear()
self.probe_queue_key = None
if self.probe_process.child is not None or optimizer.offer_state is not None and optimizer.offer_state['phase'] == 'trial':
return
pair = collector.live_response_pair
if pair is None:
return
control, output, _pose = pair
from openpilot.starpilot.flm.live_tracking_response import verified_clipped_input
def known_input(candidate, applied):
return verified_clipped_input(collector.adapter.replay, candidate, applied, self.certificate.binding)
if output.limited and not known_input(control, output):
return # Missing original CAN/limiter proof is never a numerical input.
if control.control_ns <= self.last_probe_control_ns or self.ingress.profile(control) != profile_hash:
return
witness = self.ingress.monitor.witness(now_ns)
if witness is None:
return
history = tuple(row for row in self.ingress.control_history if row.control_ns <= control.control_ns)
checkpoints = [index for index, row in enumerate(history) if row.replay_snapshot]
if not checkpoints:
return
# Retain every genuine checkpoint in the existing bounded history. Each
# endpoint still selects its OWN latest preceding<=100-frame checkpoint.
# Restricting the parent view to two anchors can hide the middle of a
# maneuver while the serial numerical worker finishes an earlier batch.
first_checkpoint = checkpoints[0]
prefix = history[first_checkpoint:]
checkpoint_indices = tuple(index - first_checkpoint for index in checkpoints if index >= first_checkpoint)
# Use the worker's existing bounded full-checkpoint prefix. Restricting
# admission to its first120ms starved4Hz sampling after170ms physical
# lag. Every original frame is replayed; no missing endpoint is inferred.
if not prefix or prefix[-1] != control or not 1 <= len(prefix) <= 301:
if self.probe_queue:
self._submit_probe_queue(token, now_ns)
return
unsupported = ()
if collector.adapter.command_family == 'torque_pid':
from openpilot.starpilot.flm.pid_stages import UNSUPPORTED
unsupported = UNSUPPORTED
kind = self.ingress.episodes.mode
# Original prefix verification dominates optional numerical CPU. Measure
# every supported hook from that same genuine replay, rather than letting
# an unexcited first group starve all other coordinates. PID's four
# unmeasurable friction hooks remain excluded, never reported as measured.
group, names = 'all30', tuple(name for name in NAMES if name not in unsupported)
if not names:
return
ep = self.ingress.episodes
phase_windows = _original_probe_windows(ep, profile_hash, group, names)
if kind not in ('large', 'subtle') and not phase_windows:
return
self.probe_group_epoch = (kind, self.ingress.episodes.start)
queue_key = (token, prefix[0].control_ns, group, names)
if self.probe_queue and (len(self.probe_queue) >= 2 or self.probe_queue_key != queue_key or now_ns - self.probe_queue[0][1] >= 250_000_000):
self._submit_probe_queue(token, now_ns)
return
# Freeze up to four DISTINCT already-observed physical endpoints from
# the same original checkpoint. A4Hz coordinator must not require four
# separate process roundtrips within each short real maneuver.
points = {(point.control_ns, point.apply_ns) for point in self.ingress.episodes.endpoints}
selected = []
original_ready = tuple(
(candidate, applied) for candidate, applied in getattr(collector, 'probe_ready', collector.ready) if 0 <= now_ns - applied.apply_ns <= 2_000_000_000
)
# A scalar newest-selected watermark cannot describe unsampled holes.
# Repair a known whole window's missing ORIGINAL time phases first,
# including older unrequested endpoints still inside all existing bounds.
# Selection inspects only source clocks/request identities, never error,
# improvement, native effect magnitude or a predicted favorable result.
# A completed/drained prior window cannot accept fresh requests.
# Do not let its unrequested points consume the limited fresh-stream
# batch slots; explicit whole-window repairs above remain independent.
fresh_after = max(self.last_probe_control_ns, ep.start - 1)
if phase_windows:
candidates = _observed_probe_candidates(
original_ready,
prefix,
points,
after_ns=0,
verify_limited=known_input,
checkpoint_indices=checkpoint_indices,
stratified=True,
phase_windows=phase_windows,
phase_fallback_after_ns=fresh_after if kind == 'large' else None,
fresh_limit=4,
discovery_headroom=True,
)
elif kind == 'large':
candidates = _observed_probe_candidates(
original_ready,
prefix,
points,
after_ns=fresh_after,
verify_limited=known_input,
checkpoint_indices=checkpoint_indices,
stratified=True,
fresh_limit=4,
discovery_headroom=True,
)
else:
candidates = () # Short subtle windows are sampled as whole original batches.
for candidate, applied, original_prefix in candidates:
if self.ingress.episodes.request_probe(candidate.control_ns, group=group, names=names, queued_ns=now_ns):
selected.append((candidate, applied, original_prefix))
if not selected:
return
# Fork freezes the genuine source prefix without copying its nested
# checkpoint graph on the ingestion loop. The original worker still
# recomputes the complete controller/native evidence independently.
from openpilot.starpilot.flm.live_tracking_probe_process import original_probe_context, prepare_probe_wire
expected = original_probe_context(selected, accepted, self.certificate.binding, source, group=group, names=names, now_ns=now_ns)
def prepare_probe():
jobs = []
for endpoint, emission, original_prefix in selected:
snapshot = probe_replay_snapshot(collector.adapter.replay, original_prefix, endpoint_output=emission)
jobs.append(
make_probe_job(
replay_snapshot=snapshot,
control=endpoint,
output=emission,
accepted_full30=accepted,
binding=self.certificate.binding,
response_witness=witness,
source=source,
evidence_ns=now_ns,
queued_ns=now_ns,
current_vehicle_model_anchor=endpoint.vehicle_model_anchor,
group=group,
names=names,
prefix_controls=original_prefix,
)
)
# This existing child already owns a frozen original source snapshot.
# Reconstruct/validate the same numerical job HERE instead of paying a
# second Python startup and streaming it through another pipe.
import json
import os
import resource
import time
os.nice(10)
from openpilot.starpilot.flm.live_tracking_probe_worker import evaluate_job, MAX_OUTPUT
soft, hard = resource.getrlimit(resource.RLIMIT_CPU)
limit = min([20] + [value for value in (soft, hard) if value >= 0])
resource.setrlimit(resource.RLIMIT_CPU, (limit, hard))
memory_soft, memory_hard = resource.getrlimit(resource.RLIMIT_AS)
memory_limit = min([2 * 1024 * 1024 * 1024] + [value for value in (memory_soft, memory_hard) if value >= 0])
resource.setrlimit(resource.RLIMIT_AS, (memory_limit, memory_hard))
prepared = prepare_probe_wire(jobs, queued_ns=now_ns, expected=expected)
started_ns = time.monotonic_ns()
if not now_ns <= started_ns <= now_ns + 2_000_000_000:
raise ValueError('original numerical input deadline expired')
numeric = evaluate_job(json.loads(prepared['wire']), now_ns=started_ns)
if len(json.dumps(numeric, separators=(',', ':'), allow_nan=False).encode()) > MAX_OUTPUT:
raise ValueError('original numerical output bound')
return {'numeric': numeric, 'job_sha256': prepared['job_sha256'], 'context_sha256': prepared['context_sha256']}
if self.probe_preparation.submit_preparation(prepare_probe, token=token, epoch=self.probe_group_epoch, now_ns=now_ns):
self.prepared_probe_context = expected
self.last_probe_control_ns = max(self.last_probe_control_ns, max(item[0].control_ns for item in selected))
except (AttributeError, KeyError, TypeError, ValueError, OverflowError):
# Missing/unsupported source-state reconstruction is no sensitivity proof.
self.reason = 'genuine_native_sensitivity_unavailable'
def _advance_original_decoder(self, collector, now_ns):
# Historical verification is independent of current collection admission. At most64 original messages per4Hz tick;
# no skipped counter/checksum input, no endpoint or authority fabrication.
if now_ns - self.last_decode_ns >= 250_000_000:
self.last_decode_ns = now_ns
history = collector.adapter.replay.emissions
if history.events:
try:
history.decode(next(reversed(history.events.values())))
except (AttributeError, KeyError, TypeError, ValueError, OverflowError):
pass # Pending/invalid bytes still fail their exact verification.
def _retire_identified_history(self, collector):
"""Retain recent prefixes for an exact source or identified response.
Source tracking has no plant-bootstrap job requiring the pre-ingress tape.
Retiring old history never admits a response, command or numerical trial.
Pending workers own fork-frozen originals. Live endpoints are at most2s
old with at most1s checkpoint history; retain4s plus its preceding original
checkpoint. No decoder state, unconsumed CAN, certificate or episode score
is replaced. Release at most32 rows per structure per tick.
"""
binding = self.certificate.binding if self.certificate is not None else self.seed if self.source_tracking else None
if binding is None or not self.source_tracking and self.ingress is None:
return
replay = collector.adapter.replay
if (
replay.raw_mode is not True
or replay.identity != binding.identity
or replay.baseline_revision != binding.baseline_revision
or not replay.records
or getattr(replay, 'trace_archive', None) is not None
):
return
cutoff = replay.records[-1].control_ns - 4_000_000_000
anchors = [stamp for stamp, _ in replay.checkpoints if stamp <= cutoff]
if not anchors:
return
anchor = anchors[-1]
for _ in range(32):
if not replay.records or replay.records[0].control_ns >= anchor:
break
removed = replay.records.popleft()
replay.normalized.pop(removed.control_ns, None)
oldest = replay.records[0].control_ns
for _ in range(2):
if len(replay.checkpoints) < 2 or replay.checkpoints[1][0] > oldest:
break
replay.checkpoints.popleft()
emissions = replay.emissions
for _ in range(32):
if not emissions.events:
break
stamp = next(iter(emissions.events))
event = emissions.events[stamp]
if event.control_ns >= oldest or (emissions.decode_queue and emissions.decode_queue[0] <= stamp):
break # Never skip original input to the stateful CAN decoder.
emissions.events.popitem(last=False)
emissions.decode_errors.pop(stamp, None)
if emissions.decoder is not None:
emissions.decoder.verified.pop(stamp, None)
if emissions.by_control.get(event.control_ns) is event:
emissions.by_control.pop(event.control_ns)
if emissions.events:
first_frame = next(iter(emissions.events.values())).witness.frame + 1
for _ in range(32):
if not emissions.carriers or next(iter(emissions.carriers)) >= first_frame:
break
emissions.carriers.popitem(last=False)
context = getattr(collector.adapter, 'original_context_receipts', None)
if context is not None:
# An unconsumed native emission can still require an older original
# control. Keep it together with every retained replay/checkpoint row.
keep_from = min(oldest, next(iter(emissions.events.values())).control_ns) if emissions.events else oldest
for _ in range(32):
if not context.controls or next(iter(context.controls)) >= keep_from:
break
context.controls.popitem(last=False)
for _ in range(32):
if not context.outputs or next(iter(context.outputs.values())).control_ns >= keep_from:
break
context.outputs.popitem(last=False)
archive = getattr(collector.adapter, 'original_feedback_archive', None)
if archive is not None:
for records in (archive.publications, archive.consumptions):
for _ in range(32):
if not records or next(iter(records)) >= oldest:
break
records.popitem(last=False)
def _same_bootstrap_source(self, source, now_ns):
"""Only retain historical computation; this is never native admission."""
from openpilot.starpilot.flm.runtime_adapter_registry import SourceState
return bool(
self.seed is not None
and self.token is not None
and type(source) is SourceState
and source.enabled is True
and source.manual is False
and source.configuration_known is True
and all(type(stamp) is int for stamp in (source.observed_ns, source.expires_ns, now_ns))
and 0 < source.observed_ns <= now_ns <= source.expires_ns <= source.observed_ns + 500_000_000
and (source.cp_sha256, source.source_epoch, source.reset, source.calibration_generation, source.persistent_source_epoch)
== (self.seed.cp_sha256, self.seed.source_epoch, self.seed.reset_generation, self.seed.calibration_generation, self.seed.persistent_source_epoch)
)
def tick(self, collector, source, *, now_ns, current_native, native_key=(), hardware_inventory=(), allow_bootstrap=True, evidence_delay_only=False):
self.native_key, self.hardware_inventory = native_key, hardware_inventory
snapshot_result = self.snapshot_process.poll(token=self.token if self._same_bootstrap_source(source, now_ns) else None, now_ns=now_ns)
if self.probe_process is not None and self.ingress is None:
# Continue actual reaping after a previous source change removed ingress.
self.probe_process.poll(token=None, now_ns=now_ns)
if (self.source_tracking and collector is not None and
getattr(getattr(getattr(collector, 'adapter', None), 'replay', None), 'raw_mode', False) is True):
# A missing current pair withdraws learning; it must not suspend bounded
# historical decoding/retirement and grow the next collection pause.
self._advance_original_decoder(collector, now_ns)
self._retire_identified_history(collector)
if collector is None or source is None or not collector.ready or current_native is not True:
# A frozen response job describes ORIGINAL source/native observations,
# not permission to apply a correction now. Temporary input/native gaps
# must not cancel that computation after expensive snapshot preparation.
# Keep any completed report inert until a fresh exact binding and current
# native admission below can independently admit the numerical model.
same_source = collector is not None and self._same_bootstrap_source(source, now_ns)
retain = same_source and self.ingress is None
retain_probe = same_source and self.ingress is not None and self.certificate is not None and self.probe_token is not None
preparation = self.probe_preparation
# Inline numerical work owns the same original window as an external
# probe. Retain only that matching, uncanceled, unexpired frozen job;
# the interruption below still withdraws every live witness and offer.
retain_preparation = bool(
same_source and self.ingress is not None and self.certificate is not None
and self.prepared_probe_context is not None and preparation.pid is not None
and not preparation.canceled and 0 < preparation.started <= now_ns <= preparation.started + 30_000_000_000
and preparation.token == (self.token, self.certificate.model_revision,
full_profile_sha256(self.certificate.binding.baseline_revision, self.ingress.optimizer.accepted))
)
if self.process is not None:
result = self.process.poll(token=self.token if retain else None, now_ns=now_ns)
if retain and type(result) is dict:
self.pending_bootstrap_result = result
if not retain:
self.pending_bootstrap_result = None
if self.probe_process is not None:
if retain_probe:
# This is only an immutable historical derivative, never current
# permission. Keep its original 30s deadline and exact job binding.
result = self.probe_process.poll_probe(token=self.probe_token, binding=self.certificate.binding, now_ns=now_ns)
if result is not None and len(self.pending_probe_results) < 4:
self.pending_probe_results.append(result)
else:
self.pending_probe_results.clear()
self.probe_process.poll(token=None, now_ns=now_ns)
self.probe_queue.clear()
self.probe_queue_key = None
if self.ingress is not None:
self.ingress.interrupt('current_evidence_delayed' if evidence_delay_only else 'current_source_or_native_permission_unavailable',
preserve_completed=retain_probe or retain_preparation)
return None
try:
seed = self.binding_for(collector, source)
except (AttributeError, TypeError, ValueError):
if self.process is not None:
self.process.poll(token=None, now_ns=now_ns)
if self.probe_process is not None:
self.probe_process.poll(token=None, now_ns=now_ns)
self.probe_queue.clear()
self.probe_queue_key = None
if self.ingress is not None:
self.ingress.interrupt('actual_response_source_unavailable', context_changed=True)
self.reason = 'actual_response_source_unavailable'
return None
token = tuple(vars(seed).values())
if self.seed is not None and seed != self.seed:
self.prepared_probe_context = None
self.pending_probe_results.clear()
self.pending_bootstrap_result = None
if self.probe_process is not None:
self.probe_process.poll(token=None, now_ns=now_ns)
self.probe_queue.clear()
self.probe_queue_key = None
if self.ingress is not None:
self.ingress.interrupt('source_configuration_changed', context_changed=True)
self.ingress = self.certificate = None
collector.live_tracking = None
self.attempted_epoch = None
self.seed, self.token = seed, token
self._advance_original_decoder(collector, now_ns)
if self.ingress is not None and self.ingress.monitor.persistent_residual_failure(now_ns):
# This is numeric-model withdrawal, never admission of a replacement.
# Preserve the per-epoch attempt latch: no outcome-based cohort search.
self.interrupt('persistent_physical_response_drift', context_changed=True)
self.response_recovery_generation += 1
self.hold_restore(False)
self.ingress = self.certificate = self.application = self.initial_basis = None
collector.live_tracking = None
capture = collector.original_source_capture
if capture is not None:
self.attempted_epoch = capture.epoch
return None
if self.process is not None:
result, self.pending_bootstrap_result = self.pending_bootstrap_result, None
polled = self.process.poll(token=token, now_ns=now_ns)
if polled is not None:
result = polled
if type(result) is dict:
if result.get('production_admissible') is not True:
self.diagnostic_result = result
self.reason = 'diagnostic_response_not_production_admission'
elif result.get('status') == 'response_identified' and result.get('certificate') is not None:
self.adopt_response(certificate_from_dict(result['certificate']), collector)
else:
self.reason = str(result.get('reason', 'response_identification_unavailable'))
context_error = None
if self.ingress is None and self.source_tracking and allow_bootstrap:
from openpilot.starpilot.flm.live_tracking_response import source_context
capture = collector.original_source_capture
if capture is not None and capture.rows:
try:
context = source_context(seed, collector.ready[-1][0], capture.rows[-1], now_ns=now_ns)
self.adopt_response(context, collector)
except (AttributeError, KeyError, TypeError, ValueError, OverflowError) as error:
context_error = error
self.reason = 'current_original_tracking_sources_required'
if self.ingress is None and self.source_tracking:
from openpilot.starpilot.flm.source_stall_log import log_source_stall
log_source_stall(self, collector, now_ns=now_ns, bootstrap_allowed=allow_bootstrap, context_error=context_error)
self.reason = 'fresh_current_tracking_sources_required'
return None
if self.ingress is None:
if not allow_bootstrap:
self.reason = 'retained_response_requalification_pending'
return None
if self.process is None:
self.reason = 'production_bootstrap_budget_not_yet_qualified'
return None
capture = collector.original_source_capture
if not self.pending and capture is not None and self.attempted_epoch != capture.epoch:
if type(snapshot_result) is dict and self.snapshot_process.epoch == capture.epoch and self.snapshot_process.token == token:
snapshot = snapshot_result.get('snapshot')
if snapshot is not None and self.process.submit(snapshot, token=token, now_ns=now_ns):
self.attempted_epoch = capture.epoch
self.reason = 'initial_independent_response_identification'
elif snapshot is None:
self.reason = str(snapshot_result.get('error', 'original_response_snapshot_not_ready'))
elif self.snapshot_process.pid is None:
self.snapshot_process.submit(collector, seed, token=token, now_ns=now_ns)
self.reason = self.snapshot_process.reason
return None
if not self.source_tracking:
self._retire_identified_history(collector)
self._probe_tick(collector, source, now_ns=now_ns)
if self.restore_pending:
return None
offer = self._current_publication_offer(now_ns)
if offer is None:
return None
pose = validate_response_witness(offer.response_witness, self.certificate.binding, now_ns).last_pose_ns
if pose <= self.last_publication_pose_ns:
return None
self.last_publication_pose_ns = pose
return offer
def _current_publication_offer(self, now_ns):
from openpilot.starpilot.flm.live_tracking_response import response_witness_value, validate_response_witness
offer = self.ingress.latest_offer
if offer is None:
return None
try:
# Structural validation of the owned old message is not current permission.
offer.validate()
old = response_witness_value(offer.response_witness)
optimizer = self.ingress.optimizer
try:
current = validate_response_witness(optimizer.response_witness, self.certificate.binding, now_ns)
except (TypeError, ValueError):
self.ingress.interrupt('expired_response_witness' if optimizer._witness_expired(now_ns)
and offer.binding == self.certificate.binding and old.certificate == self.certificate
else 'fresh_response_witness_unavailable')
return None
state = optimizer.offer_state
if offer.binding != self.certificate.binding or old.certificate != self.certificate or state is None:
raise ValueError('trial publication identity changed')
if offer.trial_id != state['trial_id']:
prior = state.get('prior_accepted')
if (
prior is None
or prior.get('accepted') is not True
or (offer.trial_id, offer.phase, offer.target_sequence, offer.target_sha256)
!= (prior['trial_id'], prior['phase'], prior.get('target_sequence', optimizer.sequence), optimizer._hash(prior['target']))
):
raise ValueError('cached offer is not the owned predecessor')
state_changed = (
offer.trial_id != state['trial_id']
or offer.phase != state['phase']
or offer.target_sequence != state.get('target_sequence', optimizer.sequence)
or offer.target_sha256 != optimizer._hash(state['target'])
)
if state_changed or current.last_pose_ns > old.last_pose_ns:
# Issue from a genuinely newer qualified pose; never renew the old
# witness, the original trial deadline, or any native command lease.
offer = optimizer.offer(now_ns, publication=False)
if offer is None:
raise ValueError('current trial publication unavailable')
cast(LiveTrackingIngress, self.ingress).latest_offer = offer
validate_response_witness(offer.response_witness, self.certificate.binding, now_ns)
return offer
except (AttributeError, TypeError, ValueError):
self.ingress.interrupt('fresh_response_witness_unavailable')
return None
def mark_publication(self, offer):
if self.ingress is not None:
self.ingress.optimizer.mark_published(offer)
def observe_application(self, application, *, now_ns):
if self.ingress is None or not self.ingress.observe_application(application, now_ns=now_ns):
return False
self.application = application
return True
def observe_restored(self, application, offer, *, now_ns):
from openpilot.starpilot.flm.live_trial_owner import LiveTrialApplication
if self.ingress is None or type(application) is not LiveTrialApplication:
return False
if (
application.status != 'restored'
or application.binding != self.certificate.binding
or application.trial_id != offer.history_trial_id
or application.applied != offer.target
or application.applied_sha256 != offer.target_sha256
or not 0 < application.control_ns <= now_ns <= application.control_ns + 100_000_000
):
return False
validate_response_witness(offer.response_witness, self.certificate.binding, now_ns)
if full_profile_sha256(self.certificate.binding.baseline_revision, dict(application.applied)) != offer.target_sha256:
return False
self.ingress.latest_restore_offer = offer
self.application = application
self.ingress.optimizer.accepted = dict(application.applied)
self.ingress.optimizer.baseline.clear()
self.ingress.optimizer.offer_state = None
self.ingress.optimizer.future.clear()
self.hold_restore(False)
return True
def persistence_inputs(self, now_ns):
if self.ingress is None or self.application is None or self.ingress.latest_offer is None:
return None
offer = self.ingress.latest_offer
if (
offer.phase != 'confirmed'
or self.application.confirmed_target_sha256 != offer.target_sha256
or not self.ingress.optimizer.report(now_ns)['applicationAcknowledged']
):
return None
return offer, self.application, self.certificate