"""Pure, pre-registration conditioning gates; never an execution authority. The numeric rules come from PROTOCOL_DRAFT sections 6-8 and the fixed EVALUATION_POLICY_DRAFT. Two explicit pre-outcome operationalizations require the caller's policy descriptor: reversal/retention downstream means the exact nonMBONDownstream set, with legacyDownstream also reported; the old H mean predicate is evaluated twice per (mode, original cue), using each DAN branch's own complete control vectors, and both results must pass that separate audit. Neither choice is described as the original H data layout. All evaluation functions are CPU/pure: descriptors and raw arrays are checked, but disk receipts, anatomical identities, seed derivation, actual execution, registration authority and full numerical/integrity audits remain EXTERNAL. A supplied SHA or Boolean is not proof of any of those facts. Consequently no return value claims scientific learning, execution approval or a candidate. The only file read is the pinned Python dependency at module import time. """ from __future__ import annotations import hashlib import json from collections.abc import Mapping from pathlib import Path import types import numpy as np METRICS_SHA256 = '47319e21db3c8b030b1bafbf0703cd86fb588d23bb29436accbacdba73d08c3c' _path = Path(__file__).resolve().parent.parent / 'olfactory-conditioning-lab-v1' / 'metrics.py' _source = _path.read_bytes() if hashlib.sha256(_source).hexdigest() != METRICS_SHA256: raise ValueError('Frozen metrics source SHA256 differs') M = types.ModuleType('conditioning_execution_frozen_metrics') M.__file__ = str(_path) exec(compile(_source, str(_path), 'exec'), M.__dict__) del _source SCHEMA = 'conditioning-learning-gates-v1' REGISTRY_SCHEMA = 'conditioning-gate-registry-descriptor-v1' AUTHORITY_SCHEMA = 'conditioning-data-authority-descriptor-v1' PAIR_SCHEMA = 'conditioning-probe-pair-descriptor-v1' DOWNSTREAM_POLICY = 'nonMBONDownstream-pre-outcome-operationalization-v1' H_MAPPING = 'each-DAN-control-source-separately-both-pass-v1' ASSAYS = ('normal', 'delayed', 'reversal', 'retention') DAN_COMPARTMENTS = {'PAM15': "y5B'2a", 'PPL103': "y2a'1"} CARRY = ('v', 'g', 'ref', 'spike_ring', 'apl_state', 'apl_pending', 'absolute_tick', 'delta', 'relevant_rng_state') EXTERNAL = ('registration/source authority', 'anatomical membership', 'full seed derivation and alias inventory', 'actual input/receipt files and completed trajectories', 'continuous state/queue/RNG restoration', 'full finite/integrity/resource audits') def require(ok, message): if not ok: raise ValueError(message) def _keys(value, fields, label): require(isinstance(value, Mapping) and set(value) == set(fields), 'Wrong ' + label + ' fields') def _sha(value, label): require(M._sha(value), 'Invalid SHA256: ' + label) return value def _token(value, label): return M._token(value, label) def descriptor_sha256(value): """Canonical descriptor hash; this does NOT establish external authority.""" return hashlib.sha256(json.dumps(value, sort_keys=True, separators=(',', ':'), ensure_ascii=False, allow_nan=False).encode('utf-8')).hexdigest() def _scope(): return dict(external_authority_verified=False, scientific_learning_pass_claimed=False, candidate_generated=False, execution_authorized=False, data_backed_claimed=False, external_requirements=list(EXTERNAL), frozen_metrics_source_sha256=METRICS_SHA256) def validate_registry(registry, *, expected_sha256): """Check all 40 declared blocks and actual 63-bit seeds, never just labels. training_sources lists independent training/design source streams, excluding counterfactual aliases. The external registrar must prove that this list is complete and agrees with the frozen full trial/seed inventory. Evaluation is one original A/B input pair per block, reused within that block across assays. """ _keys(registry, ('schema', 'protocol_sha256', 'population_binding_sha256', 'nodes_raw_sha256', 'population_membership_sha256', 'blocks'), 'registry') require(registry['schema'] == REGISTRY_SCHEMA, 'Wrong registry schema') require(descriptor_sha256(registry) == _sha(expected_sha256, 'external registry'), 'Registry descriptor changed') for field in ('protocol_sha256', 'population_binding_sha256', 'nodes_raw_sha256', 'population_membership_sha256'): _sha(registry[field], field) require(isinstance(registry['blocks'], Mapping) and len(registry['blocks']) == 40, 'Exactly 40 registered blocks required') identities, streams, seeds = set(), set(), set() for block_id, block in registry['blocks'].items(): _token(block_id, 'block_id') _keys(block, ('mode', 'dan_type', 'compartment_verbatim', 'conditioned_cue', 'replicate', 'training_sources', 'evaluation_sources', 'evaluation_input_sha256'), 'block') require(block['mode'] in M.MODES and block['dan_type'] in DAN_COMPARTMENTS and block['compartment_verbatim'] == DAN_COMPARTMENTS[block['dan_type']] and block['conditioned_cue'] in M.CUES and type(block['replicate']) is int and 1 <= block['replicate'] <= 5, 'Unknown cell/compartment/replicate') identity = (block['mode'], block['dan_type'], block['conditioned_cue'], block['replicate']) require(identity not in identities, 'Duplicate cell/replicate') identities.add(identity) require(type(block['training_sources']) is list and block['training_sources'], 'Missing independent training/design sources') _keys(block['evaluation_sources'], M.CUES, 'evaluation sources') _keys(block['evaluation_input_sha256'], M.CUES, 'evaluation input hashes') for cue in M.CUES: _sha(block['evaluation_input_sha256'][cue], 'evaluation input') entries = [(x, ('training', 'design')) for x in block['training_sources']] entries += [(block['evaluation_sources'][cue], ('evaluation',)) for cue in M.CUES] for source, allowed in entries: _keys(source, ('stream_id', 'seed', 'split'), 'independent source') _token(source['stream_id'], 'stream_id') require(source['split'] in allowed and type(source['seed']) is int and 0 <= source['seed'] < 2**63, 'Wrong source split or full63bit seed') require(source['stream_id'] not in streams and source['seed'] not in seeds, 'Independent source ID/seed collision, including training/evaluation overlap') streams.add(source['stream_id']); seeds.add(source['seed']) require(len(identities) == 40, 'Incomplete eight-cell/five-replicate inventory') return dict(schema=SCHEMA, registry_sha256=expected_sha256, blocks=40, independent_declared_streams=len(streams), **_scope()) def _context(registry, authority, nodes=None, populations=None): _keys(authority, ('schema', 'registry_sha256', 'verification_receipt_sha256', 'execution_inventory_sha256', 'population_binding_sha256'), 'external data authority descriptor') require(authority['schema'] == AUTHORITY_SCHEMA, 'Wrong data authority schema') for field in ('registry_sha256', 'verification_receipt_sha256', 'execution_inventory_sha256', 'population_binding_sha256'): _sha(authority[field], field) validate_registry(registry, expected_sha256=authority['registry_sha256']) require(authority['population_binding_sha256'] == registry['population_binding_sha256'], 'Population authority binding differs') if nodes is not None: membership = M.validate_populations(nodes, populations) require(M._hash(nodes) == registry['nodes_raw_sha256'] and membership['membership_sha256'] == registry['population_membership_sha256'], 'Raw population binding differs') def _cell_rows(rows, registry, mode, dan_type, conditioned_cue): require(mode in M.MODES and dan_type in DAN_COMPARTMENTS and conditioned_cue in M.CUES, 'Unknown cell') require(type(rows) is list and len(rows) == 5, 'Exactly five independent training rows required') expected = {key for key, value in registry['blocks'].items() if (value['mode'], value['dan_type'], value['conditioned_cue']) == (mode, dan_type, conditioned_cue)} require(len(expected) == 5 and {row['replicate_id'] for row in rows} == expected, 'Missing/duplicate/wrong-cell training rows') for row in rows: block = registry['blocks'][row['replicate_id']] require(row['replicate_unit'] == 'independent_training', 'Evaluation draws are not training replicates') require(row['training_stream_ids'] == [x['stream_id'] for x in block['training_sources']], 'Training source lineage differs') require(row['evaluation_stream_ids'] == [block['evaluation_sources'][cue]['stream_id'] for cue in M.CUES], 'Both registered evaluation inputs required; no extra evaluation replication') return expected def _pair(pair, block_id, registry, nodes, populations, used, *, policy, delta=None, checkpoint=None): fields = ('schema', 'block_id', 'snapshot_id', 'receipt_sha256', 'probe_receipt_sha256', 'evaluation_input_sha256', 'state_raw_sha256', 'states', 'state_policy', 'source_checkpoint_sha256', 'delta_sha256', 'probe_steps', 'cs_start_tick', 'cs_stop_tick_exclusive', 'US_requested', 'weight_updates_enabled', 'feedback_to_training_or_idle') _keys(pair, fields, 'probe pair') require(pair['schema'] == PAIR_SCHEMA and pair['block_id'] == block_id and pair['state_policy'] == policy, 'Probe identity/state policy differs') _token(pair['snapshot_id'], 'snapshot_id') for field in ('receipt_sha256', 'source_checkpoint_sha256', 'delta_sha256'): _sha(pair[field], field) require(type(pair['probe_steps']) is int and pair['probe_steps'] == 1200 and type(pair['cs_start_tick']) is int and pair['cs_start_tick'] == 0 and type(pair['cs_stop_tick_exclusive']) is int and pair['cs_stop_tick_exclusive'] == 1000 and pair['US_requested'] is False and pair['weight_updates_enabled'] is False and pair['feedback_to_training_or_idle'] is False, 'Probe timing/US/update/feedback differs') require(delta is None or pair['delta_sha256'] == delta, 'Probe delta source differs') require(checkpoint is None or pair['source_checkpoint_sha256'] == checkpoint, 'Probe checkpoint source differs') for field in ('probe_receipt_sha256', 'evaluation_input_sha256', 'state_raw_sha256', 'states'): _keys(pair[field], M.CUES, field) require(pair['evaluation_input_sha256'] == registry['blocks'][block_id]['evaluation_input_sha256'], 'Probe must use the exact registered evaluation inputs') for cue in M.CUES: _sha(pair['probe_receipt_sha256'][cue], 'probe receipt') checked = M.validate_state(pair['states'][cue], nodes=nodes, steps=1200) require(pair['state_raw_sha256'][cue] == checked['hashes'], 'Probe raw arrays differ from descriptor hashes') # Re-referencing one baseline is permitted, but a new snapshot cannot claim # that it executed a probe by reusing another snapshot's receipt. fingerprint = descriptor_sha256({key: value for key, value in pair.items() if key != 'states'}) identity = pair['snapshot_id'] require(identity not in used['snapshots'] or used['snapshots'][identity] == fingerprint, 'Snapshot identity reused with changed data') for receipt in (pair['receipt_sha256'], *pair['probe_receipt_sha256'].values()): require(receipt not in used['receipts'] or used['receipts'][receipt] == identity, 'Probe execution receipt reused across snapshots') used['receipts'][receipt] = identity require(len({pair['receipt_sha256'], *pair['probe_receipt_sha256'].values()}) == 3, 'A/B probes require distinct actual receipts') used['snapshots'][identity] = fingerprint return pair['states'] def _arm_execution(value, *, assay, arm, used): _keys(value, ('receipt_sha256', 'recording_verified', 'complete', 'completed_epochs', 'reinforcement_opportunities', 'terminal_pairings', 'epoch_duration_ms', 'cs_duration_ms', 'us_tick', 'initial_delta_sha256', 'terminal_delta_sha256', 'terminal_checkpoint_sha256', 'neural_state_policy', 'weight_rule', 'reinforced_cue'), 'training execution descriptor') for key in ('receipt_sha256', 'initial_delta_sha256', 'terminal_delta_sha256', 'terminal_checkpoint_sha256'): _sha(value[key], key) require(value['receipt_sha256'] not in used, 'Training receipt reused across arms/replicates') used.add(value['receipt_sha256']) require(value['complete'] is True and value['recording_verified'] is True, 'Caller must supply a completed, externally verified execution descriptor') for field, expected in (('completed_epochs', 150 if arm == 'unpaired' else 100), ('reinforcement_opportunities', 0 if arm == 'CS-only' else 50), ('terminal_pairings', 50), ('us_tick', 1500 if assay == 'delayed' else 900)): require(type(value[field]) is int and value[field] == expected, 'Wrong terminal inventory: ' + field) require(value['epoch_duration_ms'] == (180. if assay == 'delayed' else 120.) and value['cs_duration_ms'] == 100. and value['neural_state_policy'] == 'fresh_epoch_delta_only' and value['weight_rule'] == 'frozen_temporal_eligibility_v2', 'Frozen training timing/state/update policy differs') def _report(assay, rows, registry, authority, mode, dan_type, conditioned_cue): rows = sorted(rows, key=lambda row: row['replicate_id']) count = sum(row['conjunction_pass'] for row in rows) return dict(schema=SCHEMA, status='CONDITIONAL-PREDICATES-PASS' if count >= 3 else 'CONDITIONAL-PREDICATES-FAIL', assay=assay, mode=mode, dan_type=dan_type, conditioned_cue=conditioned_cue, predicate_pass=count >= 3, successful_same_replicate_conjunctions=count, required_majority=3, training_replicates=5, replicates=rows, registry_sha256=authority['registry_sha256'], external_data_authority_descriptor_sha256=descriptor_sha256(authority), downstream_policy=DOWNSTREAM_POLICY, policy_scope='pre-outcome additional operationalization', **_scope()) def evaluate_acquisition(replicates, *, assay, mode, dan_type, conditioned_cue, registry, authority): """Reuse the pinned normal/delayed gate, preserving every six-control rule. replicates has the original frozen metrics schema. recording_verified is the external caller's descriptor assertion, NOT a verification done by this call. """ _context(registry, authority) _cell_rows(replicates, registry, mode, dan_type, conditioned_cue) registered = {row['replicate_id']: row['training_stream_ids'] for row in replicates} for row in replicates: for arm in row['arms'].values(): for cue in M.CUES: summary = arm['metrics']['cues'][cue] require(summary['nodes_raw_sha256'] == registry['nodes_raw_sha256'] and summary['membership']['membership_sha256'] == registry['population_membership_sha256'], 'Population metric binding differs') frozen = M.evaluate_acquisition(replicates, assay=assay, mode=mode, dan_type=dan_type, conditioned_cue=conditioned_cue, registered_training_streams=registered) result = _report(assay, frozen['replicates'], registry, authority, mode, dan_type, conditioned_cue) result.update(frozen_acquisition_result=frozen, acquisition_controls=list(M.CONTROLS), downstream_policy='unchanged acquisition requires both legacyDownstream and nonMBONDownstream positive gains', acquisition_metric_inputs=json.loads(json.dumps(replicates, allow_nan=False)), legacy_control_MBON_gains={name: {row['replicate_id']: row['arms'][name]['metrics']['separation']['MBON']['gain'] for row in replicates} for name in ('D=0', 'random reward', 'frozen')}) return result def evaluate_reversal(replicates, *, mode, dan_type, conditioned_cue, registry, authority, nodes, populations, downstream_policy): """Original pre/orientation, strict nonzero sign crossing, fixed 50 count.""" require(downstream_policy == DOWNSTREAM_POLICY, 'Explicit preregistered downstream operationalization required') _context(registry, authority, nodes, populations) _cell_rows(replicates, registry, mode, dan_type, conditioned_cue) reports, execution_used = [], set() used = dict(snapshots={}, receipts={}) neutral = next(cue for cue in M.CUES if cue != conditioned_cue) for row in replicates: _keys(row, ('replicate_id', 'replicate_unit', 'training_stream_ids', 'evaluation_stream_ids', 'pre', 'acquisition', 'reversal', 'no_reversal', 'execution'), 'reversal row') block_id = row['replicate_id'] _keys(row['execution'], ('acquisition', 'reversal', 'no_reversal'), 'reversal executions') for arm, execution in row['execution'].items(): _arm_execution(execution, assay='normal', arm=arm, used=execution_used) require(execution['reinforced_cue'] == (neutral if arm == 'reversal' else conditioned_cue), 'Reversal cue assignment differs') acq = row['execution']['acquisition'] for arm in ('reversal', 'no_reversal'): require(row['execution'][arm]['initial_delta_sha256'] == acq['terminal_delta_sha256'], 'Reversal must fork exact acquisition delta') pre = _pair(row['pre'], block_id, registry, nodes, populations, used, policy='common_frozen_reset', delta=acq['initial_delta_sha256']) metrics, states = {}, {} for arm in ('acquisition', 'reversal', 'no_reversal'): execution = row['execution'][arm] states[arm] = _pair(row[arm], block_id, registry, nodes, populations, used, policy='common_frozen_reset', delta=execution['terminal_delta_sha256'], checkpoint=execution['terminal_checkpoint_sha256']) metrics[arm] = M.arm_metrics(pre, states[arm], conditioned_cue=conditioned_cue, nodes=nodes, populations=populations) changes = {cue: M.functional_summary(states['acquisition'][cue], states['reversal'][cue], nodes=nodes, populations=populations, steps=1200) for cue in M.CUES} s = {arm: metric['rawS'] for arm, metric in metrics.items()} expected = (s['acquisition'] > 0 and s['no_reversal'] > 0 and s['reversal'] < 0) if dan_type == 'PAM15' else ( s['acquisition'] < 0 and s['no_reversal'] < 0 and s['reversal'] > 0) mbon, down = (changes[neutral]['populations'][name] for name in ('MBON', 'nonMBONDownstream')) predicates = dict(strict_three_signed_relations=bool(expected), former_neutral_MBON_count_or_defined_first_latency=bool(mbon['spike_count_l1'] > 0 or mbon['defined_first_latency_changed']), former_neutral_nonMBONDownstream_event_or_count=bool(down['events_changed'] or down['spike_count_l1'] > 0)) reports.append(dict(replicate_id=block_id, rawS=s, predicates=predicates, conjunction_pass=all(predicates.values()), metrics=metrics, acquisition_to_reversal_changes_by_cue=changes, legacy_style_sign_inequality_on_registered_S=bool(np.sign(s['acquisition']) != np.sign(s['reversal'])), exact_historical_H_readout_equivalence_claimed=False)) return _report('reversal', reports, registry, authority, mode, dan_type, conditioned_cue) def _idle(branch, used, *, arm, conditioned_cue): _keys(branch, ('source_checkpoint_sha256', 'delta_sha256', 'idle_lineage_id', 'idle_receipt_sha256', 'total_idle_ticks', 'no_input', 'updates_disabled', 'reset_state', 'analytic_time_advance', 'one_second_is_prefix_of_ten_second', 'checkpoints', 'source_execution'), 'idle branch') _arm_execution(branch['source_execution'], assay='normal', arm=arm, used=used) source = branch['source_execution'] require(source['terminal_checkpoint_sha256'] == branch['source_checkpoint_sha256'] and source['terminal_delta_sha256'] == branch['delta_sha256'] and source['reinforced_cue'] == conditioned_cue, 'Idle source must bind the complete terminal normal paired/frozen execution') require(arm != 'frozen' or source['initial_delta_sha256'] == source['terminal_delta_sha256'], 'Frozen training cannot change delta') for field in ('source_checkpoint_sha256', 'delta_sha256', 'idle_receipt_sha256'): _sha(branch[field], field) _token(branch['idle_lineage_id'], 'idle lineage') require(branch['idle_receipt_sha256'] not in used and branch['idle_lineage_id'] not in used, 'Idle branch/receipt reused') used.update((branch['idle_receipt_sha256'], branch['idle_lineage_id'])) require(type(branch['total_idle_ticks']) is int and branch['total_idle_ticks'] == 100000 and branch['no_input'] is True and branch['updates_disabled'] is True and branch['reset_state'] is False and branch['analytic_time_advance'] is False and branch['one_second_is_prefix_of_ten_second'] is True, 'Retention must be actual continuous 10-second idle with a 1-second prefix') _keys(branch['checkpoints'], ('0', '1', '10'), 'idle checkpoints') previous, start = None, None for second in (0, 1, 10): checkpoint = branch['checkpoints'][str(second)] _keys(checkpoint, ('checkpoint_sha256', 'parent_checkpoint_sha256', 'elapsed_ticks', 'absolute_tick', 'delta_sha256', 'carry_sha256'), 'idle checkpoint') for field in ('checkpoint_sha256', 'parent_checkpoint_sha256', 'delta_sha256'): _sha(checkpoint[field], field) require(type(checkpoint['elapsed_ticks']) is int and checkpoint['elapsed_ticks'] == second * 10000 and type(checkpoint['absolute_tick']) is int and checkpoint['absolute_tick'] >= 0, 'Retention clock differs') start = checkpoint['absolute_tick'] if second == 0 else start require(checkpoint['absolute_tick'] == start + second * 10000 and checkpoint['delta_sha256'] == branch['delta_sha256'], 'Absolute clock or idle delta changed') require(checkpoint['parent_checkpoint_sha256'] == (branch['source_checkpoint_sha256'] if previous is None else previous), 'Idle checkpoint chain does not preserve the same 1-to-10-second trajectory') _keys(checkpoint['carry_sha256'], CARRY, 'complete carried-state hashes') for field, value in checkpoint['carry_sha256'].items(): _sha(value, field) previous = checkpoint['checkpoint_sha256'] def evaluate_retention(replicates, *, mode, dan_type, conditioned_cue, registry, authority, nodes, populations, downstream_policy): """One conjunction per training replicate at BOTH 1 and 10 real seconds.""" require(downstream_policy == DOWNSTREAM_POLICY, 'Explicit preregistered downstream operationalization required') _context(registry, authority, nodes, populations) _cell_rows(replicates, registry, mode, dan_type, conditioned_cue) reports, idle_used = [], set() used = dict(snapshots={}, receipts={}) for row in replicates: _keys(row, ('replicate_id', 'replicate_unit', 'training_stream_ids', 'evaluation_stream_ids', 'pre', 'checkpoints', 'execution'), 'retention row') _keys(row['pre'], ('trained', 'frozen'), 'retention pre') _keys(row['execution'], ('trained', 'frozen'), 'retention branches') _keys(row['checkpoints'], ('0', '1', '10'), 'retention time inventory') block_id = row['replicate_id'] pre = {} for branch in ('trained', 'frozen'): execution = row['execution'][branch] _idle(execution, idle_used, arm='paired' if branch == 'trained' else 'frozen', conditioned_cue=conditioned_cue) pre[branch] = _pair(row['pre'][branch], block_id, registry, nodes, populations, used, policy='common_frozen_reset', delta=execution['source_execution']['initial_delta_sha256']) times, complete = {}, [] for second in (0, 1, 10): pairs = row['checkpoints'][str(second)] _keys(pairs, ('trained', 'frozen'), 'time-matched trained/frozen probes') states, metrics = {}, {} for branch in ('trained', 'frozen'): execution = row['execution'][branch] checkpoint = execution['checkpoints'][str(second)] states[branch] = _pair(pairs[branch], block_id, registry, nodes, populations, used, policy='continuous_checkpoint', delta=execution['delta_sha256'], checkpoint=checkpoint['checkpoint_sha256']) metrics[branch] = M.arm_metrics(pre[branch], states[branch], conditioned_cue=conditioned_cue, nodes=nodes, populations=populations) differences = {cue: M.functional_summary(states['frozen'][cue], states['trained'][cue], nodes=nodes, populations=populations, steps=1200) for cue in M.CUES} trained, frozen = (metrics[branch]['rawS'] for branch in ('trained', 'frozen')) mbon, down = (differences[conditioned_cue]['populations'][name] for name in ('MBON', 'nonMBONDownstream')) predicates = dict(raw_signed_direction=bool(trained > 0 if dan_type == 'PAM15' else trained < 0), beyond_time_matched_frozen=bool(trained > frozen if dan_type == 'PAM15' else trained < frozen), conditioned_MBON_count_or_defined_first_latency=bool(mbon['spike_count_l1'] > 0 or mbon['defined_first_latency_changed']), conditioned_nonMBONDownstream_event_or_count=bool(down['events_changed'] or down['spike_count_l1'] > 0)) times[str(second)] = dict(rawS_trained=trained, rawS_frozen=frozen, rawS_trained_minus_frozen=trained - frozen, metrics=metrics, frozen_to_trained_differences_by_cue=differences, predicates=predicates, contributes_to_gate=second in (1, 10), conjunction_pass=all(predicates.values())) if second in (1, 10): complete.append(all(predicates.values())) reports.append(dict(replicate_id=block_id, times=times, conjunction_pass=all(complete), legacy_style_last_MBON_separation_exceeds_pre=bool(times['10']['metrics']['trained']['separation']['MBON']['gain'] > 0), legacy_reset_retention_equivalence_claimed=False)) return _report('retention', reports, registry, authority, mode, dan_type, conditioned_cue) def _checked_difference(summary, before, after, cue): """Rebind reported differences to raw vectors in their two source metrics. The event-change bit comes from raw-event comparison in evaluate_*; a summary does not contain the event files. It remains externally bound evidence, never an independent disk/event verification performed by this cohort function. """ left, right = before['cues'][cue], after['cues'][cue] require(summary['membership'] == left['membership'] == right['membership'] and summary['nodes_raw_sha256'] == left['nodes_raw_sha256'] == right['nodes_raw_sha256'] and summary['pre_state_raw_sha256'] == left['post_state_raw_sha256'] and summary['post_state_raw_sha256'] == right['post_state_raw_sha256'], 'Difference source binding changed') for name in M.POPULATIONS: value, a, b = summary['populations'][name], left['populations'][name], right['populations'][name] for field in ('counts', 'first_latency_ms_per_neuron', 'final_v', 'final_g', 'final_ref'): require(value['pre_' + field] == a['post_' + field] and value['post_' + field] == b['post_' + field], 'Difference population vectors changed') count = sum(abs(x - y) for x, y in zip(value['pre_counts'], value['post_counts'])) first = [] for phase in ('pre', 'post'): defined = [x for x in value[phase + '_first_latency_ms_per_neuron'] if x is not None] first.append(min(defined) if defined else None) changed = first[0] is not None and first[1] is not None and first[0] != first[1] require(type(value['spike_count_l1']) is int and value['spike_count_l1'] == count and value['defined_first_latency_changed'] is changed and type(value['events_changed']) is bool, 'Difference predicate contradicts its raw count/defined-latency vectors') require(count == 0 or value['events_changed'], 'Changed counts require changed events') same_events = all(summary['pre_state_raw_sha256'][key] == summary['post_state_raw_sha256'][key] for key in ('step', 'neuron_idx')) require(not same_events or not value['events_changed'], 'Identical complete event arrays cannot change population events') return summary['populations'] def _validate_followup_report(row, assay, dan, cue): neutral = next(x for x in M.CUES if x != cue) if assay == 'reversal': _keys(row['metrics'], ('acquisition', 'reversal', 'no_reversal'), 'reversal report metrics') metrics = {name: M._bound_metric(value, cue) for name, value in row['metrics'].items()} for odor in M.CUES: require(len({tuple(sorted(metric['cues'][odor]['pre_state_raw_sha256'].items())) for metric in metrics.values()}) == 1, 'Reversal reports changed original pre baseline') s = {name: value['rawS'] for name, value in metrics.items()} require(row['rawS'] == s, 'Reversal raw signed result differs from source metrics') _keys(row['acquisition_to_reversal_changes_by_cue'], M.CUES, 'reversal cue changes') groups = {odor: _checked_difference(row['acquisition_to_reversal_changes_by_cue'][odor], metrics['acquisition'], metrics['reversal'], odor) for odor in M.CUES} mbon, down = (groups[neutral][name] for name in ('MBON', 'nonMBONDownstream')) signed = (s['acquisition'] > 0 and s['no_reversal'] > 0 and s['reversal'] < 0) if dan == 'PAM15' else ( s['acquisition'] < 0 and s['no_reversal'] < 0 and s['reversal'] > 0) predicates = dict(strict_three_signed_relations=bool(signed), former_neutral_MBON_count_or_defined_first_latency=bool(mbon['spike_count_l1'] > 0 or mbon['defined_first_latency_changed']), former_neutral_nonMBONDownstream_event_or_count=bool(down['events_changed'] or down['spike_count_l1'] > 0)) require(row['predicates'] == predicates and all(type(x) is bool for x in row['predicates'].values()), 'Reversal predicates differ from source metrics') return all(predicates.values()) _keys(row['times'], ('0', '1', '10'), 'retention report times') baselines, conjunctions = {}, [] for second in ('0', '1', '10'): value = row['times'][second] _keys(value['metrics'], ('trained', 'frozen'), 'retention report metrics') metrics = {name: M._bound_metric(metric, cue) for name, metric in value['metrics'].items()} for branch, metric in metrics.items(): baseline = {odor: metric['cues'][odor]['pre_state_raw_sha256'] for odor in M.CUES} require(branch not in baselines or baselines[branch] == baseline, 'Retention changed original pre baseline across time') baselines[branch] = baseline trained, frozen = (metrics[branch]['rawS'] for branch in ('trained', 'frozen')) require(value['rawS_trained'] == trained and value['rawS_frozen'] == frozen and value['rawS_trained_minus_frozen'] == trained - frozen, 'Retention signed contrast differs from source metrics') _keys(value['frozen_to_trained_differences_by_cue'], M.CUES, 'retention cue differences') groups = {odor: _checked_difference(value['frozen_to_trained_differences_by_cue'][odor], metrics['frozen'], metrics['trained'], odor) for odor in M.CUES} mbon, down = (groups[cue][name] for name in ('MBON', 'nonMBONDownstream')) predicates = dict(raw_signed_direction=bool(trained > 0 if dan == 'PAM15' else trained < 0), beyond_time_matched_frozen=bool(trained > frozen if dan == 'PAM15' else trained < frozen), conditioned_MBON_count_or_defined_first_latency=bool(mbon['spike_count_l1'] > 0 or mbon['defined_first_latency_changed']), conditioned_nonMBONDownstream_event_or_count=bool(down['events_changed'] or down['spike_count_l1'] > 0)) require(value['predicates'] == predicates and all(type(x) is bool for x in value['predicates'].values()) and value['conjunction_pass'] is all(predicates.values()) and value['contributes_to_gate'] is (second != '0'), 'Retention predicates differ from source metrics') if second != '0': conjunctions.append(all(predicates.values())) return all(conjunctions) def summarize_cohort(reports, *, registry, authority, required_assays): """Exact eight-cell inventory; each assay keeps its own same-replicate 3/5. Use ('normal',) for the staged acquisition decision or ASSAYS for the full functional table. The function does not silently intersect successful seeds across assays, pool cells, or incorporate legacy H/integrity gates. Those are separately registered coordinator decisions. Missing assays remain NOT-RUN. """ _context(registry, authority) require(tuple(required_assays) in (('normal',), ASSAYS), 'Only staged normal or full fixed assay scope supported') expected = {(m, d, c, a) for m in M.MODES for d in M.DAN_TYPES for c in M.CUES for a in required_assays} actual, table = set(), [] for report in reports: require(report.get('schema') == SCHEMA and report.get('registry_sha256') == authority['registry_sha256'] and report.get('external_data_authority_descriptor_sha256') == descriptor_sha256(authority), 'Report authority binding differs') identity = (report['mode'], report['dan_type'], report['conditioned_cue'], report['assay']) require(identity in expected and identity not in actual, 'Duplicate/unexpected cohort cell/assay') expected_ids = {key for key, value in registry['blocks'].items() if (value['mode'], value['dan_type'], value['conditioned_cue']) == identity[:3]} rows = report['replicates'] require(len(rows) == 5 and {row['replicate_id'] for row in rows} == expected_ids and all(type(row['conjunction_pass']) is bool for row in rows), 'Cohort replicate coverage differs') if report['assay'] in ('normal', 'delayed'): inputs = report.get('acquisition_metric_inputs') require(isinstance(inputs, list), 'Missing original normal/delayed metric inputs') rebuilt = evaluate_acquisition(inputs, assay=identity[3], mode=identity[0], dan_type=identity[1], conditioned_cue=identity[2], registry=registry, authority=authority) require(rebuilt == report, 'Normal/delayed report differs from frozen gate reconstruction') else: for row in rows: require(report['downstream_policy'] == DOWNSTREAM_POLICY, 'Follow-up downstream policy changed') conjunction = _validate_followup_report(row, report['assay'], report['dan_type'], report['conditioned_cue']) require(row['conjunction_pass'] is conjunction, 'Replicate conjunction differs from its predicates') count = sum(row['conjunction_pass'] for row in rows) require(report['successful_same_replicate_conjunctions'] == count and report['predicate_pass'] is (count >= 3), 'Cohort summary disagrees with replicate conjunctions') require(all(report.get(key) is False for key in ('external_authority_verified', 'scientific_learning_pass_claimed', 'candidate_generated', 'execution_authorized', 'data_backed_claimed')), 'Conditional report contains an unsupported authority claim') actual.add(identity) table.append(dict(mode=identity[0], dan_type=identity[1], conditioned_cue=identity[2], assay=identity[3], status='CONDITIONAL-PASS' if count >= 3 else 'CONDITIONAL-FAIL', successful_replicates=count)) for identity in sorted(expected - actual): table.append(dict(mode=identity[0], dan_type=identity[1], conditioned_cue=identity[2], assay=identity[3], status='NOT-RUN', successful_replicates=None)) complete = actual == expected return dict(schema=SCHEMA, status='COMPLETE' if complete else 'NOT-RUN', required_assays=list(required_assays), complete_inventory=complete, all_functional_predicates_pass=(all(row['status'] == 'CONDITIONAL-PASS' for row in table) if complete else None), table=sorted(table, key=lambda row: (row['mode'], row['dan_type'], row['conditioned_cue'], row['assay'])), legacy_H_and_integrity_gates_included=False, **_scope()) def legacy_h_cohort_audit(normal_reports, *, registry, authority, declared_mapping): """Four groups, two frozen H calls each; no branch/control pooling. Both stricter control-source mapping and both_pass aggregate are new explicit pre-outcome operationalizations, NOT a reproduced complete original H gate. """ if declared_mapping is None: return dict(schema=SCHEMA, status='NOT-TESTABLE', both_pass=None, reason='Missing explicit pre-outcome control-source mapping', **_scope()) require(declared_mapping == H_MAPPING, 'Unknown declared H control-source mapping') inventory = summarize_cohort(normal_reports, registry=registry, authority=authority, required_assays=('normal',)) if not inventory['complete_inventory']: return dict(schema=SCHEMA, status='NOT-RUN', both_pass=None, reason='Complete eight normal cells required', **_scope()) lookup = {(r['mode'], r['dan_type'], r['conditioned_cue']): r for r in normal_reports} groups = [] for mode in M.MODES: for cue in M.CUES: reports = {dan: lookup[(mode, dan, cue)] for dan in M.DAN_TYPES} outcomes = {} for source in M.DAN_TYPES: # The normal report must retain all raw arm metrics; gains are # taken from their validated source payload, not a selected mean. gains = {} for dan, label in (('PAM15', 'appetitive-conditioning'), ('PPL103', 'aversive-conditioning')): gains[label] = [row['population_separation_gains']['MBON'] for row in reports[dan]['replicates']] controls = reports[source].get('legacy_control_MBON_gains') require(isinstance(controls, Mapping) and set(controls) == {'D=0', 'random reward', 'frozen'}, 'Normal report lacks complete branch-bound legacy control gains') for name, label in (('D=0', 'd-zero-control'), ('random reward', 'random-reward-control'), ('frozen', 'frozen-brain-control')): require(set(controls[name]) == {row['replicate_id'] for row in reports[source]['replicates']}, 'Legacy control replicate mapping differs') gains[label] = [controls[name][row['replicate_id']] for row in reports[source]['replicates']] outcomes[source] = M.legacy_h_mean_control_audit(gains) groups.append(dict(mode=mode, conditioned_cue=cue, control_sources=outcomes, both_pass=all(value['predicate_pass'] for value in outcomes.values()))) return dict(schema=SCHEMA, status='CONDITIONAL-AUDIT', declared_mapping=declared_mapping, groups=groups, both_pass=all(group['both_pass'] for group in groups), original_H_data_layout_reproduced=False, new_stricter_control_source_mapping=True, **_scope())