Files
digital-drosophila/models/male-cns-lif/olfactory-conditioning-lab-v1/engineering_compare.py
T
2026-09-30 16:46:21 +08:00

414 lines
27 KiB
Python

"""Read-only CPU comparisons for the UNREGISTERED AN engineering gate.
load_run(path, allow_legacy_am=False) reads actual AJ/AM/AN artifact schemas.
Call close_run(record) after using explicitly loaded memory-mapped traces.
compare_fresh(left, right, legacy_am=None) and compare_segments(monolithic,
segments) accept loaded dictionaries or paths and return JSON-safe reports.
No report is written, no GPU is imported, no training/biological PASS is claimed.
The caller owns external source/input/root SHA pins and case selection. These
comparisons do not replace seal verification or prove unseen inputs unchanged.
AM did not save its raw spike ring: its fresh terminal ring is explicitly
reconstructed from sparse events, never described as independently recorded.
Reference queue joint hashes include LOCAL tick headers; cross-segment checks
compare the separate ordered-edge/accepted-mask hashes and counts instead.
"""
from __future__ import annotations
import csv
import hashlib
import json
from pathlib import Path
import re
import numpy as np
STATE_KEYS = ('step', 'neuron_idx', 'counts', 'v', 'g', 'ref')
REQUEST_FIELDS = ('tick', 'neuron_idx', 'attempted', 'accepted', 'rejected')
TRACE_FILES = {'drive': 'apl-drive.float32.npy', 'state': 'apl-state.float32.npy',
'generated': 'apl-inhibition.float32.npy', 'applied': 'apl-applied.float32.npy'}
HASH_FIELDS = ('v_sha256', 'g_sha256', 'ref_sha256')
QUEUE_FIELDS = ('count', 'accepted_count', 'ordered_edge_sha256', 'accepted_mask_sha256')
def require(ok, message):
if not ok:
raise ValueError(message)
def bit_equal(a, b):
return (isinstance(a, np.ndarray) and isinstance(b, np.ndarray) and a.dtype == b.dtype and a.shape == b.shape and
np.array_equal(np.ascontiguousarray(a).view(np.uint8), np.ascontiguousarray(b).view(np.uint8)))
def _sha(value):
return isinstance(value, str) and re.fullmatch('[0-9a-f]{64}', value) is not None
def _json(path):
def pairs(values):
result = {}
for key, value in values:
require(key not in result, 'Duplicate JSON key: ' + key)
result[key] = value
return result
return json.loads(Path(path).read_text(encoding='utf-8'), object_pairs_hook=pairs,
parse_constant=lambda value: (_ for _ in ()).throw(ValueError('Nonfinite JSON: ' + value)))
def _jsonl(path):
with Path(path).open(encoding='utf-8') as stream:
return [json.loads(line) for line in stream if line.strip()]
def _npz(path, keys):
with np.load(path, allow_pickle=False) as archive:
require(len(archive.files) == len(keys) and set(archive.files) == set(keys), 'Unexpected array keys: ' + str(path))
return {key: archive[key].copy() for key in keys}
def reconstructed_fresh_ring(state, steps, neurons):
ring = np.zeros((19, neurons), np.uint8)
for tick in range(max(0, steps - 19), steps):
first, last = np.searchsorted(state['step'], (tick, tick + 1))
ring[tick % 19, state['neuron_idx'][first:last]] = 1
return ring
def normalized_ring(terminal):
ring, phase = terminal['spike_ring'], int(terminal['next_tick'])
return ring[(np.arange(19) + phase % 19) % 19]
def _requests(path):
with Path(path).open(encoding='utf-8', newline='') as stream:
reader = csv.DictReader(stream)
require(tuple(reader.fieldnames or ()) == REQUEST_FIELDS, 'requests.csv must use the exact five AJ fields in order')
rows = []
for row in reader:
require(set(row) == set(REQUEST_FIELDS), 'Extra/missing request CSV field')
rows.append([int(row[key]) for key in REQUEST_FIELDS])
return np.asarray(rows, dtype=np.int64).reshape(-1, 5)
def load_run(directory, *, allow_legacy_am=False):
directory = Path(directory).resolve(strict=True)
require(directory.is_dir(), 'Output is not a directory')
require(not any('error' in p.name.lower() or 'failure' in p.name.lower() for p in directory.iterdir()),
'Run contains error/failure evidence')
summary = _json(directory / 'summary.json')
require(summary.get('complete') is True and summary.get('pass_all') is True and summary.get('all_finite') is True and
summary.get('steps') == summary.get('completed_ticks'), 'Run is incomplete or failed')
state = _npz(directory / 'state.npz', STATE_KEYS)
steps, neurons = summary['steps'], len(state['v'])
require(summary.get('nodes') == neurons and summary.get('precision') == 'float64' and
summary.get('apl_precision') == 'float32' and summary.get('apl_delay_steps') == 18, 'Unexpected AN/AM numerical schema')
timing = _json(directory / 'apl-timing-audit.json')
pending = np.load(directory / 'apl-pending-tail.float32.npy', mmap_mode='r', allow_pickle=False)
terminal_path = directory / 'terminal-queues.npz'
if terminal_path.is_file():
terminal = _npz(terminal_path, ('spike_ring', 'apl_state', 'apl_pending', 'next_tick'))
origin = 'recorded_terminal_queues'
else:
require(allow_legacy_am and (directory / 'adapter-provenance.json').is_file(), 'Recorded terminal queues are missing')
bits = timing.get('final_apl_state_u32_bits')
require(isinstance(bits, list) and len(bits) == 2 and all(type(v) is int and 0 <= v < 2**32 for v in bits),
'AM has no exact terminal APL bits')
terminal = {'spike_ring': reconstructed_fresh_ring(state, steps, neurons),
'apl_state': np.asarray(bits, dtype=np.uint32).view(np.float32), 'apl_pending': np.asarray(pending),
'next_tick': np.asarray(steps, np.int64)}
origin = 'AM_spike_ring_derived_from_fresh_events_APL_bits_from_timing'
require(bit_equal(terminal['apl_pending'], pending), 'Terminal/pending file mismatch')
require(timing.get('final_apl_state_u32_bits') == terminal['apl_state'].view(np.uint32).tolist(), 'Terminal APL bit metadata mismatch')
continued = summary.get('checkpoint_continuation_used', False)
require(type(continued) is bool, 'Invalid continuation scope flag')
offset = summary.get('global_tick_offset', 0)
require(not continued or (type(offset) is int and offset > 0 and summary.get('global_next_tick') == offset + steps),
'Continued output lacks an explicit global clock')
require(continued or offset == 0, 'Fresh output has a nonzero global offset')
traces = {name: np.load(directory / file, mmap_mode='r', allow_pickle=False)
for name, file in TRACE_FILES.items() if (directory / file).is_file()}
reference = summary.get('diagnostic_mode') == 'reference' or origin.startswith('AM_')
if reference or summary.get('full_APL_history_recorded') is True:
require(len(traces) == 4, 'Declared reference APL history is incomplete')
hashes = _jsonl(directory / 'tick-state-hashes.jsonl') if (directory / 'tick-state-hashes.jsonl').is_file() else None
queues = _jsonl(directory / 'queue.jsonl') if (directory / 'queue.jsonl').is_file() else None
if reference or summary.get('full_tick_state_hashes_recorded') is True:
require(hashes is not None, 'Declared state hashes are missing')
if reference or summary.get('full_queue_hashes_recorded') is True:
require(queues is not None, 'Declared queue hashes are missing')
result = {'source': str(directory), 'state': state, 'terminal': terminal, 'requests': _requests(directory / 'requests.csv'),
'steps': steps, 'global_tick_offset': offset, 'summary': summary, 'traces': traces,
'state_hashes': hashes, 'queues': queues, 'terminal_origin': origin}
validate_run(result)
return result
def close_run(run):
"""Release read-only mappings opened by load_run; no files are modified."""
arrays = [*run.get('traces', {}).values(), *run.get('terminal', {}).values()]
closed = set()
for array in arrays:
current = array
while current is not None:
mapping = getattr(current, '_mmap', None)
if mapping is not None and id(mapping) not in closed:
mapping.close(); closed.add(id(mapping))
current = getattr(current, 'base', None)
def validate_run(run):
"""Array-level contract, also usable by synthetic tests without files."""
require(isinstance(run, dict), 'Run must be a dictionary')
steps, offset = run['steps'], run['global_tick_offset']
require(type(steps) is int and steps > 0 and type(offset) is int and offset >= 0, 'Invalid segment clock')
state, terminal = run['state'], run['terminal']
require(set(state) == set(STATE_KEYS), 'Expected exactly the six state keys')
n = len(state['v'])
require(n > 0, 'Empty neuron population')
for name, dtype in (('v', np.float64), ('g', np.float64), ('ref', np.int32), ('counts', np.int32)):
value = state[name]
require(value.dtype == dtype and value.shape == (n,) and np.isfinite(value).all(), 'Invalid state ' + name)
require(np.all((state['ref'] >= 0) & (state['ref'] <= 22)) and np.all(state['counts'] >= 0), 'Invalid ref/count values')
tick, node = state['step'], state['neuron_idx']
require(tick.dtype == node.dtype == np.int32 and tick.ndim == node.ndim == 1 and tick.shape == node.shape and
np.all((tick >= 0) & (tick < steps)) and np.all((node >= 0) & (node < n)), 'Invalid events')
keys = tick.astype(np.int64) * n + node
require(len(keys) < 2 or np.all(keys[1:] > keys[:-1]), 'Events must be sorted unique')
require(np.array_equal(np.bincount(node, minlength=n), state['counts']), 'Counts disagree with segment events')
request = run['requests']
require(isinstance(request, np.ndarray) and request.dtype == np.int64 and request.ndim == 2 and request.shape[1] == 5,
'Requests must be int64 rows in the five AJ fields')
require(np.all((request[:, 0] >= 0) & (request[:, 0] < steps)) and np.all((request[:, 1] >= 0) & (request[:, 1] < n)) and
np.all(request[:, 2] == 1) and np.all((request[:, 3] == 0) | (request[:, 3] == 1)) and
np.all(request[:, 4] == 1 - request[:, 3]), 'Invalid request values')
request_keys = request[:, 0] * n + request[:, 1]
require(len(request_keys) < 2 or np.all(request_keys[1:] > request_keys[:-1]), 'Requests must be sorted unique')
require(set(terminal) == {'spike_ring', 'apl_state', 'apl_pending', 'next_tick'}, 'Invalid terminal keys')
ring = terminal['spike_ring']
require(ring.dtype == np.uint8 and ring.shape == (19, n) and np.all(ring <= 1), 'Invalid spike ring')
phase = terminal['next_tick']
require(isinstance(phase, np.ndarray) and phase.dtype == np.int64 and phase.shape == () and int(phase) == steps,
'Terminal phase must be local segment length')
pending, apl_state = terminal['apl_pending'], terminal['apl_state']
require(pending.dtype == np.float32 and pending.ndim == 2 and pending.shape[0] == 18 and pending.shape[1] > 0 and
apl_state.dtype == np.float32 and apl_state.shape == (2,) and np.isfinite(pending).all() and np.isfinite(apl_state).all(),
'Invalid APL terminal state')
for t in range(max(0, steps - 19), steps):
expected = np.zeros(n, np.uint8)
first, last = np.searchsorted(tick, (t, t + 1)); expected[node[first:last]] = 1
require(bit_equal(ring[t % 19], expected), 'Written ring slot differs from sparse events')
if offset == 0 and steps < 19:
require(not np.any(ring[steps:]), 'Fresh uninitialized ring slots are not zero')
traces = run.get('traces', {})
require(not traces or set(traces) == set(TRACE_FILES), 'Partial APL trace set')
for key, trace in traces.items():
width = 2 if key in ('drive', 'state') else pending.shape[1]
require(trace.dtype == np.float32 and trace.shape == (steps, width) and np.isfinite(trace).all(), 'Invalid APL history: ' + key)
if traces:
require(bit_equal(traces['state'][-1], apl_state), 'Final APL history/state mismatch')
kept = min(steps, 18)
require(bit_equal(pending[-kept:], traces['generated'][-kept:]), 'Terminal APL queue does not retain generated suffix')
if steps > 18:
require(bit_equal(traces['applied'][18:], traces['generated'][:-18]), 'Within-segment APL delay differs from 18')
if offset == 0:
require(np.all(traces['applied'][:min(18, steps)].view(np.uint32) == 0), 'Fresh APL application padding is not positive zero')
hashes, queues = run.get('state_hashes'), run.get('queues')
if hashes is not None:
require(len(hashes) == steps, 'State hash coverage incomplete')
for t, row in enumerate(hashes):
require(set(row) == {'tick', *HASH_FIELDS} and type(row['tick']) is int and row['tick'] == t and
all(_sha(row[key]) for key in HASH_FIELDS), 'Invalid state hash row')
for name in ('v', 'g', 'ref'):
raw = np.ascontiguousarray(state[name], dtype=state[name].dtype.newbyteorder('<')).tobytes()
require(hashes[-1][name + '_sha256'] == hashlib.sha256(raw).hexdigest(), 'Last state hash differs from terminal ' + name)
if queues is not None:
require(len(queues) == steps, 'Queue coverage incomplete')
for t, row in enumerate(queues):
require(set(row) == {'tick', *QUEUE_FIELDS, 'joint_sha256'} and type(row['tick']) is int and row['tick'] == t and
type(row['count']) is int and type(row['accepted_count']) is int and 0 <= row['accepted_count'] <= row['count'] and
all(_sha(row[key]) for key in ('ordered_edge_sha256', 'accepted_mask_sha256', 'joint_sha256')), 'Invalid queue row')
return run
def _run(value, legacy=False):
return load_run(value, allow_legacy_am=legacy) if isinstance(value, (str, Path)) else validate_run(value)
def _activity(run):
terminal = run['terminal']
result = {'spikes': len(run['state']['step']), 'requested': len(run['requests']),
'accepted_requests': int(run['requests'][:, 3].sum(dtype=np.int64)),
'terminal_apl_state_nonzero_values': int(np.count_nonzero(terminal['apl_state'])),
'terminal_pending_nonzero_values': int(np.count_nonzero(terminal['apl_pending']))}
traces = run.get('traces', {})
result['generated_h_nonzero_values'] = int(np.count_nonzero(traces['generated'])) if traces else None
result['applied_h_nonzero_values'] = int(np.count_nonzero(traces['applied'])) if traces else None
result['apl_nonzero_observed'] = bool(result['terminal_apl_state_nonzero_values'] or result['terminal_pending_nonzero_values'] or
(result['generated_h_nonzero_values'] or 0) or (result['applied_h_nonzero_values'] or 0))
return result
def _pair_checks(left, right, prefix='pair'):
checks = {prefix + '.steps': left['steps'] == right['steps'], prefix + '.offset': left['global_tick_offset'] == right['global_tick_offset']}
for name in STATE_KEYS:
checks[prefix + '.state.' + name] = bit_equal(left['state'][name], right['state'][name])
checks[prefix + '.requests_five_fields'] = bit_equal(left['requests'], right['requests'])
for name in ('spike_ring', 'apl_state', 'apl_pending', 'next_tick'):
checks[prefix + '.terminal.' + name] = bit_equal(left['terminal'][name], right['terminal'][name])
for field in ('effective_weights_raw_sha256',):
a, b = left.get('summary', {}).get(field), right.get('summary', {}).get(field)
if a is not None or b is not None:
checks[prefix + '.' + field] = _sha(a) and a == b
availability = {'APL_traces': bool(left.get('traces')) and bool(right.get('traces')),
'state_hashes': left.get('state_hashes') is not None and right.get('state_hashes') is not None,
'queue_hashes': left.get('queues') is not None and right.get('queues') is not None}
if availability['APL_traces']:
for name in TRACE_FILES:
checks[prefix + '.trace.' + name] = bit_equal(left['traces'][name], right['traces'][name])
if availability['state_hashes']:
checks[prefix + '.state_hashes'] = left['state_hashes'] == right['state_hashes']
if availability['queue_hashes']:
checks[prefix + '.queues'] = left['queues'] == right['queues']
return checks, availability
def compare_fresh(left, right, legacy_am=None):
left, right = _run(left), _run(right)
require(left['global_tick_offset'] == right['global_tick_offset'] == 0, 'Fresh comparison requires fresh runs')
checks, available = _pair_checks(left, right)
origins = [left.get('terminal_origin', 'caller_arrays'), right.get('terminal_origin', 'caller_arrays')]
if legacy_am is not None:
legacy = _run(legacy_am, legacy=True)
require(legacy['global_tick_offset'] == 0, 'AM control must be fresh')
extra, legacy_available = _pair_checks(left, legacy, 'AM')
checks.update(extra); available['AM'] = legacy_available
# The left run may be light. Do not thereby skip the independent full
# diagnostic comparison between the right reference and sealed AM.
extra, reference_available = _pair_checks(right, legacy, 'reference_vs_AM')
checks.update(extra); available['reference_vs_AM'] = reference_available
origins.append(legacy.get('terminal_origin', 'caller_arrays'))
activity = _activity(left)
exact = bool(all(checks.values()))
nonvacuous = activity['spikes'] > 0 and activity['apl_nonzero_observed']
return {'schema': 'phase4an-fresh-engineering-comparison-v1', 'numerical_exact': exact,
'nonvacuous_activity': nonvacuous, 'pass_all': exact and nonvacuous,
'status': 'FAIL-NUMERICAL' if not exact else ('PASS-FRESH-SCOPE' if nonvacuous else 'INCOMPLETE-COVERAGE'),
'checks': checks, 'failed_checks': [key for key, value in checks.items() if not value], 'activity': activity,
'reference_comparisons_available': available, 'terminal_origins': origins,
'cross_segment_validation_performed': False, 'temporal_validation_complete': False,
'scope': 'Fresh event/state/request/terminal identity only; no continuation, learning, physiology or performance PASS',
'independent_CSR_queue_reconstruction_performed': False,
'accepted_nonzero_weight_edge_witness_verified': False,
'external_seals_and_input_authority_verified_here': False}
def compare_segments(monolithic, segments):
mono = _run(monolithic)
parts = [_run(value) for value in segments]
require(len(parts) >= 2, 'Need a monolithic run and at least two segments')
origin = mono['global_tick_offset']
if origin:
parent = mono.get('summary', {}).get('parent_checkpoint_manifest_sha256')
require(_sha(parent) and parts[0].get('summary', {}).get('parent_checkpoint_manifest_sha256') == parent,
'Nonzero-origin comparisons must bind the same starting parent checkpoint')
cursor = origin
for part in parts:
require(part['global_tick_offset'] == cursor, 'Segment clock gap/overlap/order error')
require(len(part['state']['v']) == len(mono['state']['v']), 'Segment population changed')
cursor += part['steps']
require(cursor == origin + mono['steps'], 'Segments do not cover the monolithic duration')
checks = {}
step = np.concatenate([part['state']['step'].astype(np.int64) + part['global_tick_offset'] for part in parts])
neuron = np.concatenate([part['state']['neuron_idx'] for part in parts])
checks['concatenated_global_events'] = np.array_equal(step, mono['state']['step'].astype(np.int64) + origin) and bit_equal(neuron, mono['state']['neuron_idx'])
counts = np.zeros_like(mono['state']['counts'], dtype=np.int64)
for part in parts:
counts += part['state']['counts'].astype(np.int64)
checks['sum_segment_counts'] = np.array_equal(counts, mono['state']['counts'].astype(np.int64))
requests = []
for part in parts:
rows = part['requests'].copy(); rows[:, 0] += part['global_tick_offset']; requests.append(rows)
mono_requests = mono['requests'].copy(); mono_requests[:, 0] += origin
checks['concatenated_requests_five_fields'] = bit_equal(np.concatenate(requests), mono_requests)
last = parts[-1]
for name in ('v', 'g', 'ref'):
checks['terminal.' + name] = bit_equal(last['state'][name], mono['state'][name])
checks['terminal.normalized_spike_ring'] = bit_equal(normalized_ring(last['terminal']), normalized_ring(mono['terminal']))
for name in ('apl_state', 'apl_pending'):
checks['terminal.' + name] = bit_equal(last['terminal'][name], mono['terminal'][name])
expected_weight = mono.get('summary', {}).get('effective_weights_raw_sha256')
if expected_weight is not None:
checks['unchanged_effective_weights'] = _sha(expected_weight) and all(part.get('summary', {}).get('effective_weights_raw_sha256') == expected_weight for part in parts)
trace_available = bool(mono.get('traces')) and all(part.get('traces') for part in parts)
hash_available = mono.get('state_hashes') is not None and all(part.get('state_hashes') is not None for part in parts)
queue_available = mono.get('queues') is not None and all(part.get('queues') is not None for part in parts)
if trace_available:
for name in TRACE_FILES:
checks['concatenated_APL.' + name] = all(bit_equal(part['traces'][name], mono['traces'][name][part['global_tick_offset'] - origin:part['global_tick_offset'] - origin + part['steps']]) for part in parts)
if hash_available:
checks['concatenated_per_tick_state_hashes'] = all(all(row[name] == mono['state_hashes'][part['global_tick_offset'] - origin + tick][name] for name in HASH_FIELDS)
for part in parts for tick, row in enumerate(part['state_hashes']))
if queue_available:
checks['concatenated_queue_order_and_acceptance'] = all(all(row[name] == mono['queues'][part['global_tick_offset'] - origin + tick][name] for name in QUEUE_FIELDS)
for part in parts for tick, row in enumerate(part['queues']))
boundary_rows = []
events = mono['state']['step'].astype(np.int64) + origin
for before, part in zip(parts, parts[1:]):
cut, stop = part['global_tick_offset'], part['global_tick_offset'] + part['steps']
emitted_before = (events < cut) & (events + 18 >= cut)
arriving_this_segment = emitted_before & (events + 18 < stop)
pending = before['terminal']['apl_pending']
consume = min(part['steps'], 18)
spike_carry = normalized_ring(before['terminal'])
# Future local arrival tick j consumes normalized slot j+1. This also
# covers spikes inherited from before a nonzero monolithic origin,
# which are legitimately absent from that run's local event log.
pending_spikes = int(spike_carry[1:].sum(dtype=np.int64))
arriving_spikes = int(spike_carry[1:consume + 1].sum(dtype=np.int64))
if cut - origin >= 18:
checks['boundary.' + str(cut) + '.ring_pending_event_count'] = pending_spikes == int(emitted_before.sum())
# Slots not overwritten by this short segment must remain bit-identical.
if part['steps'] < 19:
checks['boundary.' + str(cut) + '.unwritten_spike_slots'] = bit_equal(part['terminal']['spike_ring'][part['steps']:], spike_carry[part['steps']:])
if part['steps'] < 18:
checks['boundary.' + str(cut) + '.unconsumed_APL'] = bit_equal(part['terminal']['apl_pending'][:18 - part['steps']], pending[part['steps']:])
if part.get('traces'):
checks['boundary.' + str(cut) + '.applied_parent_APL'] = bit_equal(part['traces']['applied'][:consume], pending[:consume])
queue_rows = (part['queues'][:consume] if part.get('queues') is not None else
mono['queues'][cut - origin:cut - origin + consume] if mono.get('queues') is not None else None)
boundary_rows.append({'global_tick': cut, 'next_segment_steps': part['steps'],
'pending_source_spike_events': pending_spikes, 'source_spikes_arriving_in_next_segment': arriving_spikes,
'visible_local_log_source_spikes_arriving_in_next_segment': int(arriving_this_segment.sum()),
'pending_source_spike_origin': 'recorded normalized ring slots; includes pre-origin carry',
'observed_carried_arriving_edges': sum(row['count'] for row in queue_rows) if queue_rows is not None else None,
'observed_carried_accepted_edges': sum(row['accepted_count'] for row in queue_rows) if queue_rows is not None else None,
'carried_APL_nonzero_pending_values': int(np.count_nonzero(pending)),
'carried_APL_nonzero_values_applied_in_next_segment': int(np.count_nonzero(pending[:consume])),
'carried_APL_nonzero_rows_applied_in_next_segment': int(np.count_nonzero(np.any(pending[:consume] != 0, axis=1)))})
source_arrivals = sum(row['source_spikes_arriving_in_next_segment'] for row in boundary_rows)
edge_counts = [row['observed_carried_arriving_edges'] for row in boundary_rows]
observed_edges = sum(value for value in edge_counts if value is not None) if any(value is not None for value in edge_counts) else None
applied_values = sum(row['carried_APL_nonzero_values_applied_in_next_segment'] for row in boundary_rows)
activity = _activity(mono)
coverage = {'boundaries': boundary_rows, 'source_spikes_crossing_boundaries_and_due_in_receiver': source_arrivals,
'observed_carried_arriving_edges': observed_edges, 'carried_APL_nonzero_applied_values': applied_values,
'boundary_pending_event_counts_may_overlap_across_short_segments': True,
'actual_edge_arrival_coverage_known': observed_edges is not None}
nonvacuous = bool(activity['spikes'] > 0 and activity['apl_nonzero_observed'] and source_arrivals > 0 and
observed_edges is not None and observed_edges > 0 and applied_values > 0)
exact = bool(all(checks.values()))
return {'schema': 'phase4an-segment-engineering-comparison-v1', 'numerical_exact': exact,
'nonvacuous_temporal_coverage': nonvacuous, 'temporal_validation_complete': exact and nonvacuous,
'pass_all': exact and nonvacuous,
'status': 'FAIL-NUMERICAL' if not exact else ('PASS-SEGMENT-SCOPE' if nonvacuous else 'INCOMPLETE-COVERAGE'),
'checks': checks, 'failed_checks': [key for key, value in checks.items() if not value],
'activity': activity, 'coverage': coverage, 'segments': len(parts), 'steps': mono['steps'], 'global_tick_offset': origin,
'reference_comparisons_available': {'APL_traces': trace_available, 'state_hashes': hash_available, 'queue_hashes': queue_available},
'queue_joint_hash_compared': False, 'queue_joint_hash_exclusion_reason': 'local tick header differs; ordered-edge/mask hashes and counts compared when available',
'scope': 'Explicit finite engineering trajectory/terminal/carry checks only; no learning, physiology, or performance PASS',
'independent_CSR_queue_reconstruction_performed': False,
'accepted_nonzero_weight_edge_witness_verified': False,
'external_seals_and_input_authority_verified_here': False}