Seal Phase 4AM whole-brain plastic interface audit without learning claim

This commit is contained in:
Digital Drosophila Archive
2026-09-30 16:11:14 +08:00
parent 6d5f66bcc3
commit de61cf14b1
3051 changed files with 415090 additions and 13 deletions
@@ -0,0 +1,28 @@
# Pre-registration engineering checks
No new brain trajectory or conditioning result existed during these repairs.
Only the new, unregistered AM code was changed; all prior models remained
read-only. The new experiment root was provisioned empty and owned by the
existing project user before preparation.
The first server-only unit test run had 74 tests: 73 passed, one failed
(`test_static25_repeat_and_single_validation`, copied-input SHA mismatch).
The local machine had not reproduced that failure. A direct synthetic probe
established the cause, rather than changing a tolerance or expected result:
- A temporary NPZ was overwritten with different, same-size (556-byte) data.
- Its device, inode, length, mtime_ns and ctime_ns were identical before/after.
- The fresh SHA changed from
`38219e908f1b500423c9fe1a70b6070103f878903c5f005c79e387fca8b449c4` to
`fa45373dd04bf5f9d574a5329d42f8259c99c70aa69b077673aaef8c95bf0a02`.
- The timestamp-keyed digest cache returned the former SHA for the latter
bytes. Both timestamps were `1790749632756475909` in the observed probe.
The new comparator was corrected to read fresh bytes for SHA verification and
to include content hashes in static cache identity. A deliberate same-stat,
same-length rewrite test guards this issue. No waiting/sleep workaround, relaxed
hash equality, modified old data, or scientific rerun is used to hide it.
This note is a human-readable preparation record, not a saved raw unit-test
transcript. The subsequent complete server test transcript is recorded during
formal preparation and must pass without skipped Torch compatibility tests.
@@ -0,0 +1,85 @@
# Phase 4AM — D18 whole-brain plastic interface
This is a separate, non-trained branch. All Phase 1–4AL files remain read-only.
The user authorized independent new-model dynamics hypothesis tests. No base
CSR, transmitter sign, W_syn, neuron threshold, APL calibration, eligibility-v2,
or 14,232-edge mask is changed. No game, decoder, RL, or visual input is used.
## Fixed test order and scope
1. All 120 sealed AK inputs and their 24 predeclared repeats run with exactly
zero plastic_delta. Compare every recorded state bit, event, count, delayed
edge queue, request acceptance, and APL generated/applied/pending sample
against AK. All must pass before any nonzero overlay runs.
2. The same complete input inventory runs with one fixed diagnostic overlay:
the original float32 eligibility-v2 floor, `-.25 * base_candidate_mv`.
All 14,232 mask edges are included; all other weights remain identical.
Twenty-four technical repeats must be exact. This is not learned memory.
All presynaptic events are recomputed by the whole brain, unlike AL's
clamped-source MBON replay. No outcome selects an odor, compartment, dose,
parameter, or number of training pairings.
3. Pure-function compatibility tests validate the frozen eligibility trace and
original additive apply_v2 rule. No reinforcement or weight update occurs
in any of these GPU trials. Fixed delta is installed only before tick zero.
Report both cohorts, both modes, all odors and all seeds. Technical repeats do
not increase the statistical sample. Matched-energy retains its inherited
meaning: expected stochastic input, not exactly matched realized event counts.
Simulation remains 100 ms, including its unadvanced delay/APL tail.
## Explicit precision bridge — a new interface assumption
The existing D18 brain uses float64 SI voltage weights. Frozen eligibility-v2
uses float32 mV deltas and float32 candidate base amplitudes. The adapter keeps
the original D18 base bytes and adds `float64(delta32) * float64(.001)` using
separate non-fused operations, only on nonzero delta rows. Zero delta must not
reconstruct the base through float32. Positive original mask weights must
remain positive. This is not a claim of bitwise nonzero equivalence to the old
float32 brain, nor of precisely 25% of float64 D18 amplitudes. The base candidate
is reproduced from the pinned original Phase 4C NumPy expression, not converted
back from the float64 brain. The mask and all units are recorded.
Only the pre-loop weight-install hook is inserted in an AST-derived copy of
the SHA-pinned AJ function. Its timestep loop AST and original CUDA operators
remain identical. The old module is not patched and its original __file__ is
not fabricated. Inherited AJ source metadata describes the parent; additional
AM adapter provenance explicitly describes the new overlay. The original spike
delay queue stores spike identities and reads fixed weights at arrival. No
mid-trial update or implicit weight-snapshot delay rule is introduced.
## Interpretation and next experiment boundary
Record MBON, KC, DAN, actual MBON downstream, descending and motor output
changes separately, as well as first divergence and recruited/lost KC cells.
Static transfer is neither associative acquisition nor a maximal functional
effect bound. A weak static response does not prove all sparse overlays fail.
The full-brain response is not compared with AL as a strict arithmetic oracle:
AL clamps feedback and its float64 0.75 multiplication is a different fixed
precision intervention. Any side-by-side descriptive result states both.
Conditioning must be separately preregistered. Keep the original 4L static
ODOR_A (4-ethylphenol) and ODOR_B (3-hexanone), reciprocal cue assignments,
type/compartment-specific US and frozen eligibility-v2. PAM/PPL1 alone never
defines valence. The original D scalar is an artificial unconditioned-signal
interface, not measured dopamine or the number of actually emitted DAN spikes.
Log requests, acceptance, and actual DAN spikes separately. Multiplying D by
actual accepted spikes would be a different explicitly registered hypothesis,
not an unnoticed repair of eligibility-v2. No such change is made here.
Later functional learning requires independent evaluation seeds, actual paired
and control trajectories, MBON and downstream specificity, reversal and real
time retention. Neither file validity, delta change nor a static response
completes the learning goal. This stage creates no learned candidate.
## Integrity
Exclusive-create outputs, a pre-outcome source/input/config manifest, fixed
trial inventory, unit-test records, complete per-trial recording hashes,
pre/post frozen integrity, and the five unchanged deterministic-v2 reference
trials are required. Partial outputs are preserved and never overwritten.
No queued ComfyUI job is evicted. Only the declared RTX 4090 is used. The old
references are regression checks of the old runtime, not proof of D18 biology.
The biological limitations and primary-paper evidence are inherited unchanged
from sealed AL EVIDENCE.md; this precision/interface implementation introduces
no new single-cell physiological measurement or universal dopamine rule.
@@ -0,0 +1,248 @@
"""One pre-loop overlay hook in the SHA-pinned AJ function; no old global patch.
run_gpu_overlay(case_dir, out_dir, build_root, overlay_file, overlay_manifest)
retains AJ's output/summary schema. overlay-audit.json and adapter-provenance.json
are mandatory additional evidence. The inherited source-audit.json describes
the unchanged AJ source only, NOT the complete Phase 4AM adapter semantics.
Delta is fixed during the whole trial; this interface never trains or updates
eligibility. The original CUDA arrival operator still samples current weights
at arrival, and no emission-time weight snapshot is introduced.
"""
from __future__ import annotations
import ast
import copy
import hashlib
import importlib.util
import json
from pathlib import Path
import sys
import numpy as np
import overlay
AJ_SHA256 = 'af1975ba5e5e700208c0a598d3cbe648a3cf10885c6231239b6e4b28f76d173b'
PINS = {
'apl-timing-lab-v1/gpu_timing.py': AJ_SHA256,
'apl-timing-lab-v1/timing_queue.py': '54df6d4818e2a0c26e96fb0aaf5d9b71cd964981706da937562d48af79aca14e',
'author-apl-lab-v2/gpu_apl.py': '69f5d893f47dafff4ef7c3186c3df0b9014666b32c8f4e943b57016bec92b18a',
'author-apl-lab-v2/legacy_apl_worker.py': '21ceec65fe42581dc55872010e0025d660e80358905f1cf4df1dadf341a3b291',
'author-runtime-lab-v1/gpu_backend.py': '03758d07572f4b44d272059d9308fac534268ad201b57bdd77d69fee95e67278',
'author-runtime-lab-v1/author_ext.cpp': '208a937d17bbb041b9bf6b25b89264ee566830b60609e58491b44583d8541f15',
'author-runtime-lab-v1/author_ext.cu': '669f166e18ce9a3f63fc723db8b0a8b74f7fa4757194b1bd65b4cf6008a7787e',
'author-fullgraph-lab-v1/oracle_full.py': 'd72003d98f0f1624b12126eff50bd361c43d888f4a64d90ba9247a58976f1961',
}
HOOK_NAME = '_phase4am_install_overlay'
HOOK_CODE = HOOK_NAME + '(weights, graph, apl_out_mask, upload, out_dir, source_provenance)'
_LOADED = {}
def _save(path, value):
with Path(path).open('x', encoding='utf-8') as stream:
json.dump(value, stream, ensure_ascii=False, sort_keys=True, indent=2, allow_nan=False)
stream.write('\n')
def verify_sources(aj_model_dir):
directory = Path(aj_model_dir).absolute()
overlay.require(directory.name == 'apl-timing-lab-v1', 'AJ must be loaded from its actual original model directory')
paths = {key: directory.parent / key for key in PINS}
for key, path in paths.items():
overlay.require(overlay.file_hash(path) == PINS[key], 'Sealed source SHA mismatch: ' + str(path))
return {key: {'path': str(paths[key]), 'sha256': value} for key, value in PINS.items()}
def _load_checked(name, path, expected):
path = Path(path).absolute()
data = path.read_bytes()
overlay.require(hashlib.sha256(data).hexdigest() == expected, 'Source changed before loading: ' + str(path))
if name in sys.modules:
existing = sys.modules[name]
overlay.require(_LOADED.get(name) == (path, expected, existing), 'Refusing an existing unverified module binding: ' + name)
return existing
spec = importlib.util.spec_from_file_location(name, path)
overlay.require(spec is not None and spec.loader is not None, 'No source loader')
module = importlib.util.module_from_spec(spec)
sys.modules[name] = module
try:
# Execute precisely the checked source bytes; do not write frozen pyc.
exec(compile(data, str(path), 'exec'), module.__dict__)
except BaseException:
sys.modules.pop(name, None)
raise
_LOADED[name] = (path, expected, module)
return module
def _dump(node):
return ast.dump(node, annotate_fields=True, include_attributes=False)
def derive_ast(source_bytes):
"""Pure AST adapter: one inserted Expr, every other original node unchanged."""
overlay.require(hashlib.sha256(source_bytes).hexdigest() == AJ_SHA256, 'Cannot derive from unpinned AJ source')
module = ast.parse(source_bytes)
matches = [node for node in module.body if isinstance(node, ast.FunctionDef) and node.name == 'run_gpu']
overlay.require(len(matches) == 1, 'Expected exactly one sealed AJ run_gpu')
original = matches[0]
adapted = copy.deepcopy(original)
tries = [node for node in adapted.body if isinstance(node, ast.Try)]
overlay.require(len(tries) == 1, 'Unexpected run_gpu try structure')
statements = tries[0].body
anchor = ast.parse('effective_hash = hashlib.sha256()').body[0]
positions = [i for i, node in enumerate(statements) if _dump(node) == _dump(anchor)]
overlay.require(len(positions) == 1, 'Effective-weight hash insertion anchor is not unique')
position = positions[0]
previous = ast.parse('if bool(np.any(apl_out_mask)):\n weights[upload(apl_out_mask, torch.bool)] = 0.0').body[0]
overlay.require(position > 0 and _dump(statements[position - 1]) == _dump(previous),
'Overlay hook must immediately follow frozen fast-APL zeroing')
hook = ast.copy_location(ast.parse(HOOK_CODE).body[0], statements[position])
statements.insert(position, hook)
tick_loops = lambda tree: [node for node in ast.walk(tree) if isinstance(node, ast.For) and
isinstance(node.target, ast.Name) and node.target.id == 'tick']
old_loops, new_loops = tick_loops(original), tick_loops(adapted)
overlay.require(len(old_loops) == len(new_loops) == 1 and _dump(old_loops[0]) == _dump(new_loops[0]),
'Entire simulation loop AST must remain identical')
restored = copy.deepcopy(adapted)
restored_try = next(node for node in restored.body if isinstance(node, ast.Try))
restored_try.body.pop(position)
overlay.require(_dump(restored) == _dump(original), 'Adapter changed more than its single pre-loop hook')
ast.fix_missing_locations(adapted)
sha = lambda value: hashlib.sha256(value.encode('utf-8')).hexdigest()
audit = {'original_run_ast_sha256': sha(_dump(original)), 'adapted_run_ast_sha256': sha(_dump(adapted)),
'loop_ast_sha256': sha(_dump(old_loops[0])), 'entire_tick_loop_ast_identical': True,
'only_ast_change': HOOK_CODE, 'inserted_ast_statements': 1,
'hook_after_apl_zero_before_effective_hash': True}
return adapted, audit
def compile_derived(aj_module, install_hook):
"""Compile only the derived function into a NEW namespace, never old globals."""
source_path = Path(aj_module.__file__).absolute()
function_ast, audit = derive_ast(source_path.read_bytes())
namespace = dict(aj_module.__dict__)
# Real adapter location, not AJ's __file__ masquerading as a new module.
namespace.update(__name__=__name__ + '.derived_run', __file__=str(Path(__file__).absolute()))
overlay.require(HOOK_NAME not in namespace, 'Hook name collides with sealed globals')
namespace[HOOK_NAME] = install_hook
tree = ast.fix_missing_locations(ast.Module(body=[function_ast], type_ignores=[]))
exec(compile(tree, str(Path(__file__).absolute()) + '::AST-derived-AJ-run_gpu', 'exec'), namespace)
audit.update(derived_namespace_file=namespace['__file__'], original_module_file=str(source_path),
original_module_globals_patched=False, fake_original_file_used=False)
return namespace['run_gpu'], audit
def _copy_input(source, destination, expected):
with Path(source).open('rb') as incoming, Path(destination).open('xb') as outgoing:
for block in iter(lambda: incoming.read(8 << 20), b''):
outgoing.write(block)
overlay.require(overlay.file_hash(destination) == expected, 'Copied input hash mismatch')
def run_gpu_overlay(case_dir, out_dir, build_root, overlay_file, overlay_manifest):
"""Fresh D18 constant-weight interface run; no learning/update inside trial.
This is the ONLY GPU entry point; importing/testing the module is CPU-only.
Output is exclusive. The caller still owns preregistration, case/graph and
frozen-mask authority, resource checks, budgets, and scientific gate choice.
Success requires the added complete adapter-provenance.json, not merely an
inherited AJ summary that may precede a failed final wrapper verification.
"""
case_dir, out_dir = Path(case_dir).absolute(), Path(out_dir).absolute()
overlay.require(not out_dir.exists(), 'Refusing an existing output directory')
overlay.require(sys.dont_write_bytecode, 'Invoke with python -B so inherited loaders cannot write frozen __pycache__')
own_sources = {'adapter': overlay.file_hash(__file__), 'overlay': overlay.file_hash(overlay.__file__)}
plan = overlay.load_overlay(overlay_file, overlay_manifest)
spec = json.loads((case_dir / 'spec.json').read_text(encoding='utf-8'))
overlay.require(type(spec.get('apl_delay_steps')) is int and spec['apl_delay_steps'] == 18,
'Phase 4AM interface requires fixed D18')
overlay.require(spec.get('training', False) is False and spec.get('learning', False) is False,
'This interface does not authorize a learning run')
aj_dir = Path(plan['metadata']['aj_model_dir'])
sources = verify_sources(aj_dir)
_load_checked('timing_queue', aj_dir / 'timing_queue.py', PINS['apl-timing-lab-v1/timing_queue.py'])
aj = _load_checked('phase4am_sealed_aj_gpu', aj_dir / 'gpu_timing.py', AJ_SHA256)
base_file = Path(spec['graph_dir']) / 'weights.npy'
base_file_sha = overlay.file_hash(base_file)
calls = []
def install(weights, graph, apl_out_mask, upload, output, inherited_provenance):
overlay.require(not calls, 'Plastic overlay hook must run exactly once')
mapping = overlay.map_installation(graph['weights'], graph['edge_id'], apl_out_mask, plan)
if len(graph['nodes']) == 166700:
overlay.require(int(apl_out_mask.sum()) == 5845, 'Frozen fullgraph fast-APL mask changed')
torch = aj.torch
overlay.require(weights.dtype == torch.float64 and weights.ndim == 1 and weights.numel() == len(graph['edge_id']),
'Runtime weight tensor must retain float64 SI edge order')
rows = mapping['rows']
if len(rows):
local = upload(rows, torch.int64)
# Separate eager f64 multiply and addition, never base->f32 roundtrip.
delta32 = plan['plastic_delta_mv'][plan['plastic_delta_mv'] != np.float32(0)]
delta_si = upload(delta32, torch.float64) * 0.001
weights[local] = weights[local] + delta_si
actual = weights[local].cpu().numpy().copy()
overlay.require(overlay.bit_equal(actual, mapping['expected_si']), 'GPU installation differs from independent CPU SI arithmetic')
# With zero delta no indexing assignment or +0 arithmetic happens.
base_raw_sha, expected_sha = overlay.expected_hashes(graph['weights'], apl_out_mask, mapping)
actual_hash = hashlib.sha256()
for start in range(0, weights.numel(), 1 << 20):
actual_hash.update(weights[start:start + (1 << 20)].cpu().numpy().astype('<f8', copy=False).tobytes())
effective_sha = actual_hash.hexdigest()
overlay.require(effective_sha == expected_sha, 'Full effective weight bytes differ from base+APLzero+sparse overlay')
overlay.verify_inputs(plan)
overlay.require(overlay.file_hash(base_file) == base_file_sha, 'Original graph base file changed')
_copy_input(plan['input']['overlay_file'], output / 'overlay-input.npz', plan['input']['overlay_sha256'])
_copy_input(plan['input']['manifest_file'], output / 'overlay-manifest.json', plan['input']['manifest_sha256'])
audit = {'schema': 'phase4am-overlay-audit-v1', 'complete': True,
'overlay_name': plan['metadata']['overlay_name'], 'input': plan['input'],
'arrays': {key: overlay.array_metadata(plan[key]) for key in
('edge_id', 'plastic_delta_mv', 'base_candidate_mv') if plan[key] is not None},
'candidate_count': len(plan['edge_id']), 'nonzero_delta_count': int(np.count_nonzero(plan['plastic_delta_mv'])),
**{key: mapping[key] for key in ('mapped_candidate_count', 'missing_candidate_count', 'installed_nonzero_count', 'apl_overlap_count')},
'delta_dtype': 'float32', 'delta_units': 'mV', 'state_dtype': 'float64', 'bridge': overlay.BRIDGE,
'installation_schedule': 'before tick 0; after fast APL zeroing',
'weights_updated_during_run': False, 'learning': False, 'zero_delta_no_write': True,
'frozen_mask_exact': True, 'bounds_pass': True, 'apl_fast_edges_zeroed': int(apl_out_mask.sum()),
'base_graph_files_modified': False, 'untouched_weights_bitwise_preserved': True,
'base_weights_file_sha256': base_file_sha, 'base_weights_raw_sha256': base_raw_sha,
'effective_weights_raw_sha256': effective_sha, 'expected_effective_weights_raw_sha256': expected_sha,
'copied_overlay_file': 'overlay-input.npz', 'copied_manifest_file': 'overlay-manifest.json',
'inherited_source_audit_scope': 'AJ source provenance only; AM overlay semantics are recorded separately',
'inherited_aj_source_provenance': inherited_provenance,
'static25_is_exact_fraction_of_float64_base_claimed': False,
'arrival_weight_sampling': 'arrival time; delta fixed for entire trial'}
_save(output / 'overlay-audit.json', audit)
calls.append(audit)
derived, ast_audit = compile_derived(aj, install)
try:
summary = derived(case_dir, out_dir, Path(build_root))
overlay.require(len(calls) == 1, 'Exactly one overlay installation was required')
overlay.verify_inputs(plan)
overlay.require(verify_sources(aj_dir) == sources and overlay.file_hash(base_file) == base_file_sha,
'Frozen sources or base graph changed during the run')
overlay.require(own_sources == {'adapter': overlay.file_hash(__file__), 'overlay': overlay.file_hash(overlay.__file__)},
'Adapter source changed during invocation')
overlay.require(summary.get('complete') is True and summary.get('effective_weights_raw_sha256') ==
calls[0]['effective_weights_raw_sha256'], 'Inherited run summary does not bind installed weights')
receipt = {'schema': 'phase4am-adapter-provenance-v1', 'complete': True,
'scope': 'constant sparse overlay installation only; no within-trial plasticity or learning',
'adapter_file': str(Path(__file__).absolute()), 'adapter_sha256': own_sources['adapter'],
'overlay_module_file': str(Path(overlay.__file__).absolute()), 'overlay_module_sha256': own_sources['overlay'],
'sealed_sources': sources, 'ast': ast_audit, 'installation_calls': len(calls),
'weights_updated_during_run': False, 'learning': False, 'apl_delay_steps': 18,
'original_module_globals_patched': False, 'delta_constant_for_entire_trial': True,
'inherited_source_audit_describes_AM_semantics': False,
'overlay_audit_sha256': overlay.file_hash(out_dir / 'overlay-audit.json'),
'inherited_summary_sha256': overlay.file_hash(out_dir / 'summary.json'),
'effective_weights_raw_sha256': calls[0]['effective_weights_raw_sha256']}
_save(out_dir / 'adapter-provenance.json', receipt)
return summary
except Exception as error:
if out_dir.is_dir() and not (out_dir / 'adapter-error.json').exists():
_save(out_dir / 'adapter-error.json', {'complete': False, 'type': type(error).__name__,
'message': str(error), 'installation_calls': len(calls), 'no_complete_adapter_receipt': True})
raise
@@ -0,0 +1,19 @@
85a3253ceb4e4c5d7bcf17b8b3294dbbf72bd1139415a892f6a90e8037785c89 PREPARATION.md
e03273995f4d5f1fc18d0af481374b8688ae735d83ae718895ffb741f8ac9399 PROTOCOL.md
3daabe771d3eef6c6189827c0ee5159b266c3a058e07da5781bb863be428aef9 adapter.py
4d64020af05e7fc9e535ac8532dd0e7b614b200f695ed8c6d486c6151de57175 comparison.py
c19f00c81f12c4c3503d3d557bd73d0722d4d3fed7279449408c67a89a6ffcf9 config.json
0fa2e0892c973fe70ecbc0613e3cb508c256b7745042f8936edf23dedc31d166 context.py
174fb8d14619189e74b095e77a6db18b14c93046dc431c0b55710a5aa2dd2e61 eligibility_bridge.py
b8e4fb59d4efa261a8615f1456bc2ad1f1822e941af558b27074b8c41dba15a1 finalize.py
7f891d0ba79b393c96e75fd2dee2eddc51e57d8213eaac2779703bc2c18712b4 overlay.py
40976f0ed0b01fbf275c245de0f0a907592d23f5ca4733293b41e1d011c7ee62 prepare.py
6a6fcf4cc64d27234ab69ce5a9dcdb8bbd8b3b4965c9c08c2f9d20747025e9e7 run_suite.py
b4f3cacf3ab60f70d63713d5bbc3e03658f38e357a47ef219b1050003176df01 summarize.py
a6274f338307a6961e514f565ab3e731051846caf62901e6843037755adc6fd8 test_comparison.py
113435c0f3528e3901e47421570a5f906d192826df9fc4ee600429a87ab904c5 test_eligibility_bridge.py
1c0536e0d0c27de6ab152ebb5aa0015ee31325417b17d3cfedc5f43bafa2ee79 test_overlay_adapter.py
351a0c2887d657e1942b849d768d7efe8c52c0c3c67d0cf4d55658549c3bfe32 test_workflow.py
f1453a8814339ec7860ef4dee20549cc811d13cefd7aee2d308ebdfd51a839ca test_workflow_identity.py
5b121184ec3e666814dd440356604e96520aecdd8902d5b68c7d61caa7f224c5 verify_frozen.py
7edeb251ecbeac5a64805fefe171a0a0bf8bba2675919ef922cc1a329c203ea8 manifest.json
@@ -0,0 +1,603 @@
"""Exact, read-only Phase 4AM output comparison; never a learning gate.
The sealed AJ comparator is loaded from verified bytes without modifying its
globals. Full-graph queue identities and refractory acceptance are additionally
reconstructed from actual events, including zero-weight edges. Only declared
performance fields may differ. New AM provenance is checked separately, not
mistaken for the inherited AJ implementation provenance.
"""
from __future__ import annotations
import argparse
import ast
import copy
from functools import lru_cache
import hashlib
import importlib.util
import json
import math
from pathlib import Path
import numpy as np
N = 166700
E = 25582938
K = 4064
CANDIDATES = 14232
STEPS = 1000
AJ_SHA = 'af1975ba5e5e700208c0a598d3cbe648a3cf10885c6231239b6e4b28f76d173b'
HELPER_SHA = '9010f070fba9b7c9cf2d86187ee2abc57f3ac606ebc08a42baad4f3922b51734'
CPP_SHA = '208a937d17bbb041b9bf6b25b89264ee566830b60609e58491b44583d8541f15'
CUDA_SHA = '669f166e18ce9a3f63fc723db8b0a8b74f7fa4757194b1bd65b4cf6008a7787e'
SEALED = {
'ag_gpu': '69f5d893f47dafff4ef7c3186c3df0b9014666b32c8f4e943b57016bec92b18a',
'ag_worker': '21ceec65fe42581dc55872010e0025d660e80358905f1cf4df1dadf341a3b291',
'ae_backend': '03758d07572f4b44d272059d9308fac534268ad201b57bdd77d69fee95e67278',
'af_queue': 'd72003d98f0f1624b12126eff50bd361c43d888f4a64d90ba9247a58976f1961',
}
ADAPTER_PINS = {
'apl-timing-lab-v1/gpu_timing.py': AJ_SHA,
'apl-timing-lab-v1/timing_queue.py': '54df6d4818e2a0c26e96fb0aaf5d9b71cd964981706da937562d48af79aca14e',
'author-apl-lab-v2/gpu_apl.py': SEALED['ag_gpu'],
'author-apl-lab-v2/legacy_apl_worker.py': SEALED['ag_worker'],
'author-runtime-lab-v1/gpu_backend.py': SEALED['ae_backend'],
'author-runtime-lab-v1/author_ext.cpp': CPP_SHA,
'author-runtime-lab-v1/author_ext.cu': CUDA_SHA,
'author-fullgraph-lab-v1/oracle_full.py': SEALED['af_queue'],
}
HOOK_CODE = '_phase4am_install_overlay(weights, graph, apl_out_mask, upload, out_dir, source_provenance)'
PERFORMANCE = frozenset(('wall_seconds', 'diagnostic_simulation_seconds', 'build_or_cache_seconds',
'peak_allocated_vram_bytes', 'peak_reserved_vram_bytes'))
BRIDGE = 'baseSI64 + (delta32 widened to float64) * float64(0.001); nonzero rows only'
SCHEDULE = 'before tick 0; after fast APL zeroing'
GRAPH_FIELDS = ('nodes', 'edge_id', 'src', 'dst', 'ptr', 'signed_raw', 'weights')
_WEIGHT_CACHE = {}
_BASE_RAW_CACHE = {}
def require(condition, message):
if not condition:
raise ValueError(message)
def _fingerprint(path):
path = Path(path).resolve()
stat = path.stat()
require(path.is_file(), 'Not a regular evidence file: ' + str(path))
return str(path), stat.st_dev, stat.st_ino, stat.st_size, stat.st_mtime_ns, stat.st_ctime_ns
def _digest_fingerprint(identity):
# Do not cache byte hashes by stat metadata. Same-size writes can share
# inode, mtime_ns and ctime_ns even on the actual server filesystem.
value = hashlib.sha256()
with Path(identity[0]).open('rb') as source:
for block in iter(lambda: source.read(8 << 20), b''):
value.update(block)
require(_fingerprint(identity[0]) == identity, 'Evidence changed while hashing')
return value.hexdigest()
def file_hash(path):
return _digest_fingerprint(_fingerprint(path))
def raw_hash(array):
return hashlib.sha256(np.ascontiguousarray(array).tobytes()).hexdigest()
@lru_cache(maxsize=2)
def _helper_from_bytes(identity):
require(file_hash(identity[0]) == HELPER_SHA, 'Sealed AJ comparator hash changed')
spec = importlib.util.spec_from_file_location('phase4am_readonly_sealed_aj_compare', identity[0])
module = importlib.util.module_from_spec(spec)
exec(compile(Path(identity[0]).read_bytes(), identity[0], 'exec'), module.__dict__)
return module
def _helper(used):
path = Path(__file__).resolve().parent.parent / 'apl-timing-lab-v1/compare_timing.py'
used.add(path)
sha = file_hash(path)
require(sha == HELPER_SHA, 'Sealed AJ comparator hash changed')
return _helper_from_bytes(_fingerprint(path) + (sha,))
def _json(path, used):
path = Path(path)
used.add(path)
def unique(pairs):
result = {}
for key, value in pairs:
require(key not in result, 'Duplicate JSON key: ' + key)
result[key] = value
return result
return json.loads(path.read_text(encoding='utf-8'), object_pairs_hook=unique,
parse_constant=lambda value: (_ for _ in ()).throw(ValueError('Nonfinite JSON: ' + value)))
def _npz(path, used):
path = Path(path)
used.add(path)
with np.load(path, allow_pickle=False) as data:
require(len(data.files) == len(set(data.files)), 'Duplicate NPZ key')
return {key: data[key].copy() for key in data.files}
@lru_cache(maxsize=2)
def _static_arrays(identities):
arrays = {Path(identity[0]).name: np.load(identity[0], mmap_mode='r', allow_pickle=False)
for identity in identities}
require(all(_fingerprint(identity[0]) == identity[:-1] and file_hash(identity[0]) == identity[-1]
for identity in identities), 'Static inputs changed while loading')
return arrays
def _load_case(case_dir, used):
spec = _json(case_dir / 'spec.json', used)
require(type(spec['steps']) is int and spec['steps'] == STEPS and spec['dt_ms'] == .1 and
spec['duration_ms'] == 100. and spec['record_history'] is False and
type(spec['apl_delay_steps']) is int and spec['apl_delay_steps'] == 18,
'Phase 4AM comparison requires the unchanged full 100-ms D18 case')
model = spec['model']
for key, value in (('synaptic_delay_ms', 1.8), ('refractory_ms', 2.2),
('w_syn_mv_per_anatomical_synapse', .275), ('resting_potential_mv', -52.),
('reset_potential_mv', -52.), ('threshold_mv', -45.)):
require(type(model[key]) in (int, float) and model[key] == value, 'Frozen model field changed: ' + key)
graph_dir, bundle_dir = Path(spec['graph_dir']), Path(spec['apl_bundle_dir'])
require(graph_dir.is_absolute() and bundle_dir.is_absolute(), 'Static input paths must be absolute')
paths = [graph_dir / (key + '.npy') for key in GRAPH_FIELDS]
paths += [bundle_dir / key for key in ('input_matrix.npy', 'output_matrix.npy', 'kc_globals.npy', 'apl_globals.npy')]
used.update(paths)
# Caches for parsed/derived immutable graph data are keyed by FRESH content
# SHA, not merely a filesystem timestamp. Re-read hashes on every call.
token = tuple(_fingerprint(p) + (file_hash(p),) for p in paths)
arrays = _static_arrays(token)
graph = {key: arrays[key + '.npy'] for key in GRAPH_FIELDS}
bundle = {key: arrays[key] for key in ('input_matrix.npy', 'output_matrix.npy', 'kc_globals.npy', 'apl_globals.npy')}
_validate_static(graph, bundle, token)
requests = _npz(case_dir / 'requests.npz', used)
require(set(requests) == {'tick', 'neuron_idx'}, 'Unexpected request arrays')
ticks, nodes = requests['tick'], requests['neuron_idx']
require(ticks.dtype == nodes.dtype == np.int32 and ticks.ndim == 1 and ticks.shape == nodes.shape and
np.all((ticks >= 0) & (ticks < STEPS)) and np.all((nodes >= 0) & (nodes < N)), 'Invalid sparse requests')
keys = ticks.astype(np.int64) * N + nodes
require(np.all(keys[1:] > keys[:-1]), 'Requests must be sorted unique; no silently deduplicated requests')
coeff_path = Path(spec['coefficients_path'])
require(coeff_path.is_absolute(), 'Coefficient path must be absolute')
coeff = _json(coeff_path, used)
for key in ('gd', 'c0', 'cg', 'cv', 'threshold', 'reset', 'seed_volt'):
require(type(coeff[key]) in (int, float) and math.isfinite(coeff[key]), 'Invalid author coefficient: ' + key)
require(coeff['threshold'] == model['threshold_mv'] * .001 and
coeff['reset'] == model['reset_potential_mv'] * .001 and coeff['seed_volt'] > coeff['threshold'],
'Author coefficient units/threshold mismatch')
input_hashes = {'spec.json': file_hash(case_dir / 'spec.json'),
'requests.npz': file_hash(case_dir / 'requests.npz'), 'base_weights.npy': file_hash(graph_dir / 'weights.npy'),
'coefficients.json': file_hash(coeff_path)}
if (case_dir / 'arrays.npz').exists():
used.add(case_dir / 'arrays.npz')
input_hashes['arrays.npz'] = file_hash(case_dir / 'arrays.npz')
return dict(spec=spec, graph=graph, bundle=bundle, token=token, input_hashes=input_hashes,
requested=list(zip(map(int, ticks), map(int, nodes))), graph_dir=graph_dir, bundle_dir=bundle_dir)
_VALIDATED_STATIC = set()
def _validate_static(graph, bundle, token):
if token in _VALIDATED_STATIC:
return
for key, dtype, shape in (('nodes', np.int32, (N,)), ('ptr', np.int64, (N + 1,)),
('edge_id', np.int64, (E,)), ('src', np.int32, (E,)), ('dst', np.int32, (E,)),
('signed_raw', np.int64, (E,)), ('weights', np.float64, (E,))):
require(graph[key].dtype == dtype and graph[key].shape == shape, 'Canonical graph schema changed: ' + key)
require(np.array_equal(graph['nodes'], np.arange(N, dtype=np.int32)), 'Global neuron identity changed')
ptr = graph['ptr']
require(ptr[0] == 0 and ptr[-1] == E and np.all(np.diff(ptr) >= 0), 'Invalid canonical CSR')
for start in range(0, E, 1 << 20):
stop = min(E, start + (1 << 20))
expected_ids = np.arange(start, stop, dtype=np.int64)
require(np.array_equal(graph['edge_id'][start:stop], expected_ids), 'Original edge identity changed')
require(np.array_equal(graph['src'][start:stop], np.searchsorted(ptr[1:], expected_ids, side='right')),
'CSR source order changed')
require(np.all((graph['dst'][start:stop] >= 0) & (graph['dst'][start:stop] < N)), 'Invalid edge targets')
original = graph['weights'][start:stop]
expected = graph['signed_raw'][start:stop] * (.275 * .001)
require(np.isfinite(original).all() and raw_hash(original) == raw_hash(expected), 'Original signed SI weights changed')
for name, dtype, shape in (('kc_globals.npy', np.int32, (K,)), ('apl_globals.npy', np.int32, (2,)),
('input_matrix.npy', np.float32, (2, N)), ('output_matrix.npy', np.float32, (2, K))):
a = bundle[name]
require(a.dtype == dtype and a.shape == shape and np.isfinite(a).all(), 'Invalid APL bundle ' + name)
if dtype == np.int32:
require(np.all((a >= 0) & (a < N)) and np.all(a[1:] > a[:-1]), 'Invalid APL/KC IDs')
else:
require(np.all(a >= 0), 'Negative normalized APL matrix')
require(not np.intersect1d(bundle['kc_globals.npy'], bundle['apl_globals.npy']).size, 'APL/KC overlap')
_VALIDATED_STATIC.add(token)
def _effective_hash(case, ids=None, delta=None):
"""Independent static bridge, cached per immutable graph/delta identity."""
key = (case['token'], None if ids is None else raw_hash(ids), None if delta is None else raw_hash(delta))
if key in _WEIGHT_CACHE:
return _WEIGHT_CACHE[key]
graph, apl = case['graph'], case['bundle']['apl_globals.npy']
baseline, effective = hashlib.sha256(), hashlib.sha256()
masked = 0
for start in range(0, len(graph['edge_id']), 1 << 20):
stop = min(len(graph['edge_id']), start + (1 << 20))
value = graph['weights'][start:stop].copy()
fast = np.isin(graph['src'][start:stop], apl)
masked += int(fast.sum())
value[fast] = np.float64(0)
baseline.update(value.astype('<f8', copy=False).tobytes())
if ids is not None:
lo, hi = np.searchsorted(ids, (start, stop))
ix, change = ids[lo:hi] - start, delta[lo:hi]
require(not fast[ix].any(), 'Plastic mask overlaps fast APL outputs')
nz = change != 0
value[ix[nz]] = np.add(value[ix[nz]], np.multiply(change[nz].astype(np.float64), np.float64(.001)))
require(np.isfinite(value[ix[nz]]).all() and np.all(value[ix[nz]] > 0), 'Static overlay changes candidate sign')
effective.update(value.astype('<f8', copy=False).tobytes())
result = (baseline.hexdigest(), effective.hexdigest(), masked)
_WEIGHT_CACHE[key] = result
return result
def _base_raw_hash(case):
key = case['token']
if key not in _BASE_RAW_CACHE:
h = hashlib.sha256()
values = case['graph']['weights']
for start in range(0, len(values), 1 << 20):
h.update(values[start:start + (1 << 20)].astype('<f8', copy=False).tobytes())
_BASE_RAW_CACHE[key] = h.hexdigest()
return _BASE_RAW_CACHE[key]
def _self_consistency(run, graph, requested, steps, helper, role, checks, differences):
"""Reconstruct every queue hash, request gate, and ref hash from events.
No edge weight, claimed queue digest, or stored PASS determines the result.
Expansion touches only the current delayed spike sources, not all edges.
"""
state, ptr, nodes = run['state'], graph['ptr'], graph['nodes']
n = len(nodes)
local = np.searchsorted(nodes, state['neuron_idx'])
require(np.all(local < n) and np.array_equal(nodes[local], state['neuron_idx']), 'Spike outside graph')
keys = state['step'].astype(np.int64) * N + state['neuron_idx']
require(np.all(keys[1:] > keys[:-1]), 'Duplicate or unordered actual events')
require(np.array_equal(np.bincount(local, minlength=n), state['counts']), 'Event counts do not match per-neuron counts')
require([(r['tick'], r['neuron_idx']) for r in run['requests']] == requested, 'Request input identity differs')
bounds = np.searchsorted(state['step'], np.arange(steps + 1))
rq_bounds = np.searchsorted([r['tick'] for r in run['requests']], np.arange(steps + 1))
last = np.full(n, -1_000_000_000, np.int64)
failures = {}
expected_due_total = expected_accepted_total = 0
for tick in range(steps):
fired = local[bounds[tick]:bounds[tick + 1]]
if np.any(tick - last[fired] < 22):
failures.setdefault('refractory_spike_violation', tick)
for row in run['requests'][rq_bounds[tick]:rq_bounds[tick + 1]]:
target = int(np.searchsorted(nodes, row['neuron_idx']))
require(target < n and nodes[target] == row['neuron_idx'], 'Request outside canonical graph')
accepted = tick - last[target] >= 22
if row['accepted'] != int(accepted) or row['rejected'] != int(not accepted):
failures.setdefault('request_refractory_gate', tick)
if bool(np.any(fired == target)) != bool(accepted):
failures.setdefault('request_actual_spike', tick)
last[fired] = tick
ref = np.maximum(22 - (tick - last), 0).astype(np.int32)
if helper.raw_hash(ref, '<i4') != run['hashes'][tick]['ref_sha256']:
failures.setdefault('all_tick_ref_hash', tick)
sources = local[bounds[tick - 18]:bounds[tick - 17]] if tick >= 18 else np.empty(0, np.int64)
pieces = [np.arange(ptr[source], ptr[source + 1], dtype=np.int64) for source in sources]
rows = np.concatenate(pieces) if pieces else np.empty(0, np.int64)
accepted = (ref[graph['dst'][rows]] == 0).astype(np.uint8)
expected = helper._queue_digest(tick, graph['edge_id'][rows], accepted)
expected_due_total += len(rows)
expected_accepted_total += int(accepted.sum())
if expected != run['queues'][tick]:
failures.setdefault('full_queue_edge_order_and_acceptance', tick)
if not np.array_equal(ref, state['ref']):
failures['final_ref_from_events'] = steps - 1
summary = run['summary']
if summary.get('arriving_edges') != expected_due_total or summary.get('accepted_arriving_edges') != expected_accepted_total:
failures['queue_summary_counts'] = 'mismatch'
checks[role + '.full_event_queue_request_accounting'] = not failures
if failures:
differences[role + '.independent_accounting'] = failures
def _overlay(run, case, used, zero_required=False):
folder = run['directory']
audit = _json(folder / 'overlay-audit.json', used)
require(audit['schema'] == 'phase4am-overlay-audit-v1' and audit['complete'] is True, 'Incomplete overlay audit')
source = audit['input']
inputs = {}
for label in ('overlay', 'manifest', 'mask', 'base_candidate'):
filename, sha = source[label + '_file'], source[label + '_sha256']
if filename is None:
require(label == 'base_candidate' and sha is None, 'Required overlay input absent')
inputs[label] = None
continue
path = Path(filename)
require(path.is_absolute(), 'Overlay provenance input must be absolute')
used.add(path)
require(file_hash(path) == sha, 'Overlay input hash mismatch: ' + label)
inputs[label] = path
manifest = _json(inputs['manifest'], used)
require(manifest['schema'] == 'phase4am-overlay-v1' and manifest['overlay_sha256'] == source['overlay_sha256'] and
manifest['mask_sha256'] == source['mask_sha256'] and Path(manifest['mask_path']).resolve() == inputs['mask'].resolve(),
'Overlay manifest linkage mismatch')
require(manifest['base_candidate_sha256'] == source['base_candidate_sha256'] and
(manifest['base_candidate_path'] is None if inputs['base_candidate'] is None else
Path(manifest['base_candidate_path']).resolve() == inputs['base_candidate'].resolve()), 'Candidate floor provenance mismatch')
require(Path(manifest['aj_model_dir']).resolve() == Path(__file__).resolve().parent.parent / 'apl-timing-lab-v1',
'Overlay is not bound to the sealed AJ model')
require(audit['copied_overlay_file'] == 'overlay-input.npz' and audit['copied_manifest_file'] == 'overlay-manifest.json',
'Unexpected copied overlay filenames')
for label, name in (('overlay', 'overlay-input.npz'), ('manifest', 'overlay-manifest.json')):
used.add(folder / name)
require(file_hash(folder / name) == source[label + '_sha256'], 'Copied input mismatch')
arrays = _npz(inputs['overlay'], used)
require(set(arrays) in ({'edge_id', 'plastic_delta_mv'}, {'edge_id', 'plastic_delta_mv', 'base_candidate_mv'}), 'Overlay NPZ schema changed')
ids, delta = arrays['edge_id'], arrays['plastic_delta_mv']
require(ids.dtype == np.int64 and ids.shape == (CANDIDATES,) and np.all(ids[1:] > ids[:-1]) and
np.all((ids >= 0) & (ids < len(case['graph']['edge_id']))), 'Invalid original plastic edge IDs')
mask = np.load(inputs['mask'], allow_pickle=False)
require(mask.dtype == np.int64 and mask.shape == ids.shape and np.array_equal(mask, ids), 'Frozen plastic mask identity mismatch')
require(delta.dtype == np.float32 and delta.shape == ids.shape and np.isfinite(delta).all() and np.all(delta <= 0), 'Invalid LTD delta')
audit_arrays = dict(arrays)
name = manifest['overlay_name']
require(name in ('zero', 'static25') and audit['overlay_name'] == name, 'Unknown overlay intervention')
if zero_required:
require(name == 'zero', 'Zero-regression cannot use a nonzero intervention')
if name == 'zero':
require(not np.any(delta != 0), 'Zero overlay contains nonzero delta')
else:
require(inputs['base_candidate'] is not None, 'Static25 requires its frozen float32 mV floor')
if inputs['base_candidate'] is not None:
base = np.load(inputs['base_candidate'], allow_pickle=False)
require(base.dtype == np.float32 and base.shape == ids.shape and np.isfinite(base).all() and np.all(base > 0), 'Invalid old float32 base')
floor = np.multiply(base, np.float32(-.25))
require(np.all(delta >= floor), 'Delta exceeds the existing depression bound')
if 'base_candidate_mv' in arrays:
require(arrays['base_candidate_mv'].dtype == np.float32 and raw_hash(arrays['base_candidate_mv']) == raw_hash(base), 'Embedded old base differs')
if name == 'static25':
require(raw_hash(delta) == raw_hash(floor), 'Static25 is not the declared old float32 floor')
audit_arrays['base_candidate_mv'] = base
else:
require('base_candidate_mv' not in arrays, 'Embedded unanchored old base is forbidden')
expected_arrays = {key: dict(dtype=str(value.dtype), shape=list(value.shape), raw_sha256=raw_hash(value))
for key, value in audit_arrays.items()}
require(audit['arrays'] == expected_arrays, 'Overlay array audit differs from actual bytes')
require(np.isin(case['graph']['src'][ids], case['bundle']['kc_globals.npy']).all() and
np.all(case['graph']['weights'][ids] > 0), 'Plastic edge source/sign changed')
baseline_sha, effective_sha, apl_count = _effective_hash(case, ids, delta)
graph = case['graph']
for key, value in {'candidate_count': CANDIDATES, 'nonzero_delta_count': int(np.count_nonzero(delta)),
'mapped_candidate_count': CANDIDATES, 'missing_candidate_count': 0,
'installed_nonzero_count': int(np.count_nonzero(delta)), 'delta_dtype': 'float32', 'delta_units': 'mV',
'state_dtype': 'float64', 'bridge': BRIDGE, 'installation_schedule': SCHEDULE,
'weights_updated_during_run': False, 'learning': False, 'zero_delta_no_write': True,
'frozen_mask_exact': True, 'bounds_pass': True, 'apl_overlap_count': 0,
'apl_fast_edges_zeroed': apl_count, 'base_graph_files_modified': False,
'untouched_weights_bitwise_preserved': True,
'base_weights_file_sha256': file_hash(case['graph_dir'] / 'weights.npy'),
'base_weights_raw_sha256': _base_raw_hash(case),
'effective_weights_raw_sha256': effective_sha, 'expected_effective_weights_raw_sha256': effective_sha}.items():
require(type(audit.get(key)) is type(value) and audit[key] == value, 'Overlay audit mismatch: ' + key)
require(run['summary']['effective_weights_raw_sha256'] == effective_sha, 'Installed effective-weight hash differs from independent bridge')
if zero_required:
require(effective_sha == baseline_sha, 'Zero overlay changed the baseline effective weights')
require(audit['inherited_aj_source_provenance'] == run['summary']['source_provenance'] and
audit['inherited_source_audit_scope'] == 'AJ source provenance only; AM overlay semantics are recorded separately' and
audit['static25_is_exact_fraction_of_float64_base_claimed'] is False and
audit['arrival_weight_sampling'] == 'arrival time; delta fixed for entire trial', 'Overlay semantic scope mismatch')
return audit
def _expected_ast(source_path, adapter_path):
"""Independently derive just the declared Expr insertion; no adapter import."""
tree = ast.parse(Path(source_path).read_bytes())
original = [node for node in tree.body if isinstance(node, ast.FunctionDef) and node.name == 'run_gpu']
require(len(original) == 1, 'Pinned AJ run_gpu not unique')
original = original[0]
adapted = copy.deepcopy(original)
tries = [node for node in adapted.body if isinstance(node, ast.Try)]
require(len(tries) == 1, 'Pinned run_gpu try not unique')
statements = tries[0].body
dump = lambda node: ast.dump(node, annotate_fields=True, include_attributes=False)
anchor = dump(ast.parse('effective_hash = hashlib.sha256()').body[0])
indices = [i for i, node in enumerate(statements) if dump(node) == anchor]
require(len(indices) == 1, 'Pinned hook anchor not unique')
index = indices[0]
previous = ast.parse('if bool(np.any(apl_out_mask)):\n weights[upload(apl_out_mask, torch.bool)] = 0.0').body[0]
require(index > 0 and dump(statements[index - 1]) == dump(previous), 'Hook is not immediately after APL zeroing')
statements.insert(index, ast.parse(HOOK_CODE).body[0])
loops = lambda node: [item for item in ast.walk(node) if isinstance(item, ast.For) and
isinstance(item.target, ast.Name) and item.target.id == 'tick']
before, after = loops(original), loops(adapted)
require(len(before) == len(after) == 1 and dump(before[0]) == dump(after[0]), 'Hook changed loop AST')
sha = lambda node: hashlib.sha256(dump(node).encode('utf-8')).hexdigest()
return dict(original_run_ast_sha256=sha(original), adapted_run_ast_sha256=sha(adapted),
loop_ast_sha256=sha(before[0]), entire_tick_loop_ast_identical=True, only_ast_change=HOOK_CODE,
inserted_ast_statements=1, hook_after_apl_zero_before_effective_hash=True,
derived_namespace_file=str(adapter_path.absolute()), original_module_file=str(Path(source_path).absolute()),
original_module_globals_patched=False, fake_original_file_used=False)
def _adapter_receipt(run, used):
folder = run['directory']
require(not (folder / 'adapter-error.json').exists(), 'Adapter recorded an error')
receipt = _json(folder / 'adapter-provenance.json', used)
require(receipt['schema'] == 'phase4am-adapter-provenance-v1' and receipt['complete'] is True,
'Completed inherited AJ summary is insufficient without completed AM receipt')
model = Path(__file__).resolve().parent
for label, filename in (('adapter', 'adapter.py'), ('overlay_module', 'overlay.py')):
path = Path(receipt[label + '_file'])
require(path.is_absolute() and path.resolve() == model / filename, 'Unexpected new wrapper source path')
used.add(path)
require(file_hash(path) == receipt[label + '_sha256'], 'Wrapper source hash changed')
source_rows = {}
for relative, sha in ADAPTER_PINS.items():
path = model.parent / relative
used.add(path)
require(file_hash(path) == sha, 'Frozen source changed: ' + relative)
source_rows[relative] = {'path': str(path.absolute()), 'sha256': sha}
require(receipt['sealed_sources'] == source_rows, 'Wrapper sealed-source inventory differs')
require(receipt['ast'] == _expected_ast(model.parent / 'apl-timing-lab-v1/gpu_timing.py', model / 'adapter.py'),
'Wrapper AST does not match independently reconstructed single pre-loop hook')
for key, value in dict(installation_calls=1, weights_updated_during_run=False, learning=False, apl_delay_steps=18,
original_module_globals_patched=False, delta_constant_for_entire_trial=True,
inherited_source_audit_describes_AM_semantics=False).items():
require(type(receipt.get(key)) is type(value) and receipt[key] == value, 'Wrapper receipt mismatch: ' + key)
require(receipt['scope'] == 'constant sparse overlay installation only; no within-trial plasticity or learning', 'Wrapper scope changed')
require(receipt['overlay_audit_sha256'] == file_hash(folder / 'overlay-audit.json') and
receipt['inherited_summary_sha256'] == file_hash(folder / 'summary.json') and
receipt['effective_weights_raw_sha256'] == run['summary']['effective_weights_raw_sha256'], 'Wrapper receipt not bound to output')
return {key: value for key, value in receipt.items() if key != 'inherited_summary_sha256'}
def _provenance(run, case, helper, used):
summary, component = run['summary'], run['component']
require(summary['input_sha256'] == case['input_hashes'], 'Actual case/weight/coefficient input hash differs')
require(summary['all_finite'] is True and summary['counts_match_sparse_events'] is True and
summary['learning'] is False and summary['state_units'] == 'SI volts', 'Invalid finite/state/learning declaration')
require(summary['sealed_ae_backend_sha256'] == SEALED['ae_backend'], 'Frozen backend changed')
build = summary['build']
require(build['sources'] == {'author_ext.cpp': CPP_SHA, 'author_ext.cu': CUDA_SHA} and
build['cuda_flags'] == ['-O2', '--fmad=false', '--ftz=false', '--prec-div=true', '--prec-sqrt=true'] and
build['arch_list'] == '8.9', 'Build arithmetic/source contract changed')
source = _json(run['directory'] / 'source-audit.json', used)
require(source == summary['source_provenance'] and source['sealed_source_sha256'] == SEALED and
source['candidate_sha256'] == AJ_SHA and source['module_globals_patched'] is False, 'Inherited AJ source audit changed')
diff = run['directory'] / 'sealed-gpu-source.diff'
used.add(diff)
require(file_hash(diff) == source['source_diff_sha256'], 'Inherited source diff hash mismatch')
bundle = case['bundle']
require(component['files_sha256'] == {name: file_hash(case['bundle_dir'] / name) for name in bundle} and
component['array_sha256'] == {name: raw_hash(value) for name, value in bundle.items()}, 'Actual APL bundle bytes changed')
require(component['ok'] is True and component['protocol'] == 'phase4ag-apl-v1' and
component['n_neurons'] == N and component['n_apl'] == 2 and component['n_kc'] == K and
component['dt_ms'] == .1, 'APL component dimensions/clock changed')
for key, value in (('decay_f32_bits', np.float32(math.exp(-.1 / 20.))), ('gain_f32_bits', np.float32(.01))):
require(component[key] == f'{int(value.view(np.uint32)):08x}', 'APL constant changed: ' + key)
env = component['environment']
require(env['cuda_matmul_allow_tf32'] is False and env['float32_matmul_precision'] == 'highest' and
env['precision_configuration_changed_by_component'] is False and '4090' in env['device_name'],
'GPU precision environment changed')
require(summary['apl_schedule'] == 'end, after threshold/reset and guarded arrivals, unconditional all KC' and
summary['apl_si_conversion'] == 'applied h32 -> float64 -> multiply float64 0.001 -> separate float64 subtraction',
'APL scheduling or SI conversion changed')
for key in PERFORMANCE:
require(type(summary[key]) in (int, float) and math.isfinite(summary[key]) and summary[key] >= 0, 'Invalid performance field: ' + key)
def _summary_pair(left, right, checks, differences):
a = {k: v for k, v in left.items() if k not in PERFORMANCE}
b = {k: v for k, v in right.items() if k not in PERFORMANCE}
checks['summary.nonperformance_exact'] = a == b
if a != b:
differences['summary'] = {key: {'left': a.get(key), 'right': b.get(key)}
for key in sorted(set(a) | set(b)) if a.get(key) != b.get(key) or (key in a) != (key in b)}
def compare_runs(case_dir, left, right, output_path=None, mode='zero'):
"""Zero-vs-sealed-AK or AM repeat equality; failures return a failed report.
``output_path=None`` is read-only. A provided report is created exclusively,
outside both run directories and the input case. Parent protocol must bind
the case and old manifests; this comparator reports exactly the bytes read.
"""
case_dir, left, right = (Path(p).resolve() for p in (case_dir, left, right))
if output_path is not None:
output_path = Path(output_path).resolve()
require(not output_path.exists(), 'Refusing existing comparison output')
require(not any(output_path.is_relative_to(p) for p in (case_dir, left, right)), 'Comparison must not write into input evidence')
checks, differences, used = {}, {}, {Path(__file__).resolve()}
report = dict(schema='phase4am-comparison-v1', mode=mode, case_dir=str(case_dir), left=str(left), right=str(right),
pass_all=False, learning_achieved=False, candidate_generated=False, tolerance=None,
scope='Exact declared trajectory and static overlay integrity; no physiological or learning PASS',
explicit_exclusions=sorted(PERFORMANCE), independent_cpu_wholebrain_oracle_claim=False)
try:
require(mode in ('zero', 'repeat', 'self'), 'Unknown comparison mode')
require((left == right) == (mode == 'self'), 'Only explicit single-run validation may use one directory')
helper = _helper(used)
case = _load_case(case_dir, used)
spec, graph = case['spec'], case['graph']
n, edges, steps = len(graph['nodes']), len(graph['edge_id']), spec['steps']
sides = ((left, 'left_gpu'),) if mode == 'self' else ((left, 'left_gpu'), (right, 'right_gpu'))
runs = [helper._load_run(path, role, n, edges, steps, False, spec['name'], 18, used, checks)
for path, role in sides]
for role, run in zip(('left_gpu', 'right_gpu'), runs):
_provenance(run, case, helper, used)
require(all(np.isfinite(a).all() for a in run['state'].values()), 'Nonfinite final state/events')
_self_consistency(run, graph, case['requested'], steps, helper, role, checks, differences)
helper._timing_sequence_checks(run['apl']['inhibition'], run['apl']['applied'], run['pending'], 18, role, checks, differences)
helper._timing_metadata_checks(run, role, 18, steps, checks)
require(not (run['directory'] / 'first-failure-state.npz').exists(), 'Recorded first numerical failure exists')
if mode != 'self':
helper._pair_outputs(*runs, checks, differences, n, steps, False)
require(runs[0]['timing'] == runs[1]['timing'], 'APL timing metadata differs')
_summary_pair(runs[0]['summary'], runs[1]['summary'], checks, differences)
baseline_sha, _, apl_count = _effective_hash(case)
for run in runs:
require(run['summary']['apl_fast_edges_zeroed'] == apl_count and run['summary']['kc_targets_present'] == K,
'Fast APL or KC coverage changed')
if mode == 'zero':
require(not (left / 'overlay-audit.json').exists(), 'Zero reference must be the unwrapped sealed AK run')
require(runs[0]['summary']['effective_weights_raw_sha256'] == baseline_sha, 'Sealed reference effective weights changed')
audit = _overlay(runs[1], case, used, zero_required=True)
_adapter_receipt(runs[1], used)
report['overlay_name'] = audit['overlay_name']
elif mode == 'repeat':
a, b = [_overlay(run, case, used) for run in runs]
require(a == b, 'Repeated overlay provenance/identity differs')
receipts = [_adapter_receipt(run, used) for run in runs]
require(receipts[0] == receipts[1], 'Repeated wrapper provenance differs beyond bound walltime-bearing summary')
report['overlay_name'] = a['overlay_name']
else:
report['overlay_name'] = _overlay(runs[0], case, used)['overlay_name']
_adapter_receipt(runs[0], used)
report['scope'] = 'Single-run event/queue/input/static-overlay self-consistency; no repeat, equivalence, physiology or learning PASS'
checks['input_overlay_and_source_provenance'] = True
report.update(nodes=n, edges=edges, steps=steps, apl_delay_steps=18,
full_queue_reconstructed=True, total_spikes=len(runs[0]['state']['step']))
except Exception as error:
report['error'] = {'type': type(error).__name__, 'message': str(error)}
manifest = []
try:
for path in sorted(used):
manifest.append(dict(path=str(path.resolve()), bytes=path.stat().st_size, sha256=file_hash(path)))
except Exception as error:
report['read_manifest_error'] = {'type': type(error).__name__, 'message': str(error)}
report.update(checks={key: bool(value) for key, value in checks.items()}, differences=differences,
read_manifest=manifest, failed_checks=sorted(key for key, value in checks.items() if not value))
report['pass_all'] = bool(checks) and all(checks.values()) and 'error' not in report and 'read_manifest_error' not in report
if output_path is not None:
output_path.parent.mkdir(parents=True, exist_ok=True)
with output_path.open('x', encoding='utf-8') as target:
json.dump(report, target, indent=2, sort_keys=True, allow_nan=False)
target.write('\n')
return report
def validate_run(case_dir, output_dir, output_path=None):
"""Single-run static-overlay integrity only; not numerical equivalence."""
return compare_runs(case_dir, output_dir, output_dir, output_path, mode='self')
if __name__ == '__main__':
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--case', required=True)
parser.add_argument('--left', required=True)
parser.add_argument('--right', required=True)
parser.add_argument('--output', required=True)
parser.add_argument('--mode', choices=('zero', 'repeat', 'self'), required=True)
args = parser.parse_args()
result = compare_runs(args.case, args.left, args.right, args.output, args.mode)
print(json.dumps({'pass_all': result['pass_all'], 'failed_checks': result['failed_checks'], 'error': result.get('error')}, allow_nan=False))
raise SystemExit(0 if result['pass_all'] else 1)
@@ -0,0 +1,22 @@
{
"phase": "4AM",
"purpose": "Exact D18 trial-boundary plastic-overlay interface and closed-loop transfer gate",
"neurons": 166700,
"edges": 25582938,
"candidate_edges": 14232,
"primary_trials": 120,
"technical_repeats": 24,
"steps": 1000,
"dt_ms": 0.1,
"apl_delay_steps": 18,
"stages": ["zero", "static25"],
"max_fractional_depression": 0.25,
"virtual_gate_tick": 900,
"gpu_uuid": "GPU-79f3a85d-adce-7833-7003-6488140ca596",
"output_budget_bytes": 17179869184,
"training": false,
"candidate_generation": false,
"static_test_is_learning": false,
"precision_bridge": "base float64 SI plus separate float64(delta float32 mV) times 0.001; zero rows untouched",
"future_learning": "Original frozen eligibility-v2 and additive trial-boundary update; artificial scalar D remains separate from actual DAN events"
}
@@ -0,0 +1,115 @@
"""New branch only. Old files are hash-anchored read-only inputs."""
import hashlib
import importlib.util
import json
import sys
from pathlib import Path
sys.dont_write_bytecode = True
ROOT = Path('/data/digital-drosophila')
MODEL = Path(__file__).resolve().parent
EXP = ROOT / 'experiments/phase4am-wholebrain-plastic-interface'
AK = ROOT / 'experiments/phase4ak-apl-timing-validation'
AL = ROOT / 'experiments/phase4al-mb-credit-transfer'
AL_MODEL = ROOT / 'models/male-cns-lif/mb-credit-transfer-audit-v1'
AJ_MODEL = ROOT / 'models/male-cns-lif/apl-timing-lab-v1'
AG = ROOT / 'experiments/phase4ag-author-apl-r2'
H = ROOT / 'experiments/phase4h-dopamine-plasticity'
META = ROOT / 'datasets/male-cns-v1.0/processed/neuron-only/neuron-index/unified-metadata.parquet'
CFG = json.loads((MODEL / 'config.json').read_text(encoding='utf-8'))
PINS = {
'models/male-cns-lif/mb-credit-transfer-audit-v1/context.py': '1626873baa224fab5d427a1fab1d6f840f14814152914ac4c2d6aa7a4f0bb1f6',
'models/male-cns-lif/mb-credit-transfer-audit-v1/manifest.json': '72e4b4e2c53c258939ca355f31eeba2cd6381e126a61efeea651d8bac8df5328',
'experiments/phase4al-mb-credit-transfer/manifest.json': 'a22de7d85cbfe760070ff55f5666e74475a3335c63bbd37b41241a94be7e3eea',
'experiments/phase4al-mb-credit-transfer/audit/final-status.json': 'ec846137531d3bea357f57364857b5de5ca2381a01aac3ebb1b7ade79059209e',
'models/male-cns-lif/apl-timing-lab-v1/gpu_timing.py': 'af1975ba5e5e700208c0a598d3cbe648a3cf10885c6231239b6e4b28f76d173b',
'models/male-cns-lif/apl-timing-lab-v1/compare_timing.py': '9010f070fba9b7c9cf2d86187ee2abc57f3ac606ebc08a42baad4f3922b51734',
'models/male-cns-lif/phase4c.py': '5ec83a132deb8ba20e62dab485537c2414016fe2fece546198d61c0668d75b6b',
'models/male-cns-lif/mb-physiology-v1/phase4j.py': 'abb4574da85f00bd9ef61024c65993ef81d42651ff8d8d63c15dd69c6222471e',
'experiments/phase4h-dopamine-plasticity/plastic-mask/plastic-edge-candidates.parquet': 'e5075ee3e5a0edf3a4d197453847163cc295b254f21c67203159bba204b12a76',
'experiments/phase4h-dopamine-plasticity/plastic-mask/plastic-edge-ids.int64.npy': '8b0fb6eb2e6c31da4d17dc20d890aa3f367e514f05642de5bad6b42a1611c05b',
'experiments/phase4h-dopamine-plasticity/plastic-mask/plastic-edge-mask.bool.npy': 'e8b7a439f07eae6e36729d6577a2c5e4a4c7aa4b15e97fc5266d7278db9e150e',
'datasets/male-cns-v1.0/processed/neuron-only/neuron-index/unified-metadata.parquet': '922af16846a065c3dbfca7c11146b83ca217fcbd7392edc745f444a04eae8c63'
}
def digest(path):
h = hashlib.sha256()
with Path(path).open('rb') as f:
for block in iter(lambda: f.read(8 << 20), b''):
h.update(block)
return h.hexdigest()
def read(path):
return json.loads(Path(path).read_text(encoding='utf-8'))
def save(path, value):
path = Path(path); path.parent.mkdir(parents=True, exist_ok=True)
with path.open('x', encoding='utf-8') as f:
json.dump(value, f, indent=2, ensure_ascii=False, allow_nan=False)
f.write('\n')
def write_npz(path, **values):
import numpy as np
with Path(path).open('xb') as f:
np.savez_compressed(f, **values)
def load_module(name, path, expected_hash):
data = Path(path).read_bytes()
assert hashlib.sha256(data).hexdigest() == expected_hash, str(path)
spec = importlib.util.spec_from_file_location(name, path)
module = importlib.util.module_from_spec(spec)
sys.modules[name] = module
exec(compile(data, str(path), 'exec'), module.__dict__)
return module
def sources():
return {p.relative_to(MODEL).as_posix(): digest(p) for p in sorted(MODEL.rglob('*'))
if p.is_file() and '__pycache__' not in p.parts and p.name not in ('manifest.json', 'checksums.sha256')}
def integrity():
old = load_module('sealed_al_context_am', AL_MODEL / 'context.py',
PINS['models/male-cns-lif/mb-credit-transfer-audit-v1/context.py'])
result = old.integrity()
sys.path.insert(0, str(ROOT / 'models/male-cns-lif/terminal-scope-diagnostic-v1'))
from diagnostic import manifest_check
for path in (AL_MODEL, AL):
result[path.relative_to(ROOT).as_posix()] = manifest_check(path, digest)
assert all(row['pass'] for row in result.values())
return result
def check(full=False):
reg = read(EXP / 'protocol/preregistered.json')
assert reg['sources'] == sources() and reg['config'] == CFG
for row in reg['inputs'] if full else []:
assert digest(ROOT / row['path']) == row['sha256'], row['path']
for row in read(EXP / 'protocol/prepared-hashes.json'):
assert digest(EXP / row['path']) == row['sha256'], row['path']
return reg
def bit_equal(a, b):
return a.dtype == b.dtype and a.shape == b.shape and a.tobytes() == b.tobytes()
def budget():
size = sum(p.stat().st_size for p in EXP.rglob('*') if p.is_file())
assert size < CFG['output_budget_bytes'], 'Output budget exceeded; stop and preserve all partials'
return size
def seal(root):
rows = [dict(path=p.relative_to(root).as_posix(), bytes=p.stat().st_size, sha256=digest(p))
for p in sorted(root.rglob('*')) if p.is_file() and '__pycache__' not in p.parts]
save(root / 'manifest.json', dict(root=str(root), files=rows))
with (root / 'checksums.sha256').open('x', encoding='utf-8') as f:
for row in rows:
f.write(row['sha256'] + ' ' + row['path'] + '\n')
f.write(digest(root / 'manifest.json') + ' manifest.json\n')
@@ -0,0 +1,285 @@
"""Pure Phase 4J eligibility adapter; no brain run, training, or artifact writes.
D is the original artificial command scalar. Actual DAN request acceptance and
spikes are separate evidence and MUST NOT silently replace D here. All input
arrays remain unchanged. Returned arrays own their storage and are read-only.
The NumPy trace backend is a candidate compatibility implementation; only an
explicit comparison with the Torch backend establishes Torch bitwise agreement.
"""
from __future__ import annotations
import ast
from dataclasses import dataclass
import hashlib
import math
from pathlib import Path
from types import MappingProxyType, SimpleNamespace
from typing import Any
import numpy as np
PHASE4J_SHA256 = "abb4574da85f00bd9ef61024c65993ef81d42651ff8d8d63c15dd69c6222471e"
DT_MS = 0.1
TAU_MS = 100.0
TRACE_CAP = 1.0
ETA_MV = 0.00275
FLOOR_FRACTION = 0.25
POLARITY = -1
COMPARTMENTS = ("B2B'2a", "a1", "y2a'1", "y5B'2a")
FIXED_GATES = MappingProxyType({"negative_us_before_cs_delta_exact_zero": True,
"plus_1000_to_zero_ratio_strict_upper": 0.01,
"off_compartment_delta_exact_unchanged": True,
"zero_d_and_frozen_delta_exact_unchanged": True})
_TRACE_EXPRESSION = (
"kc_trace.mul_(trace_decay).add_(spikes[self.kc_gpu].to(torch.float32))"
".clamp_max_(1.0)"
)
def _require(condition: bool, message: str) -> None:
if not condition:
raise ValueError(message)
def _readonly(array: np.ndarray) -> np.ndarray:
result = np.array(array, copy=True, order="C")
result.setflags(write=False)
return result
def bit_equal(left: np.ndarray, right: np.ndarray) -> bool:
a, b = np.asarray(left), np.asarray(right)
return a.dtype == b.dtype and a.shape == b.shape and a.tobytes() == b.tobytes()
def _integer(value: Any, name: str, minimum: int) -> int:
_require(isinstance(value, (int, np.integer)) and not isinstance(value, (bool, np.bool_)),
f"{name} must be an integer")
_require(int(value) >= minimum, f"{name} is below {minimum}")
return int(value)
def _array(value: Any, dtype: Any, name: str) -> np.ndarray:
result = np.asarray(value)
_require(result.ndim == 1 and result.dtype == np.dtype(dtype),
f"{name} must be a one-dimensional {np.dtype(dtype)} array")
return result
def _kc_array(kc: np.ndarray, n_neurons: int) -> np.ndarray:
kc = _array(kc, np.int32, "kc")
_require(len(kc) > 0 and np.all((kc >= 0) & (kc < n_neurons)), "KC IDs out of range or empty")
_require(np.all(kc[1:] > kc[:-1]), "KC IDs must be canonical sorted unique global IDs")
return kc
def _load_original(source: str | Path) -> tuple[Any, Any, dict[str, str]]:
"""Verify the entire frozen source, then execute ONLY one function AST.
Old imports, globals, class initialization and main are never executed.
The trace expression is also checked against the exact frozen expression.
"""
raw = Path(source).read_bytes()
actual_sha = hashlib.sha256(raw).hexdigest()
_require(actual_sha == PHASE4J_SHA256, "frozen Phase 4J source SHA256 mismatch")
tree = ast.parse(raw.decode("utf-8"), filename=str(source))
functions = [node for node in tree.body if isinstance(node, ast.FunctionDef) and node.name == "apply_v2"]
_require(len(functions) == 1, "frozen apply_v2 AST is missing or ambiguous")
function = functions[0]
classes = [node for node in tree.body if isinstance(node, ast.ClassDef) and node.name == "APLSimulator"]
runs = [node for cls in classes for node in cls.body
if isinstance(node, ast.FunctionDef) and node.name == "run"]
expected = ast.parse(_TRACE_EXPRESSION).body[0]
expected_dump = ast.dump(expected, include_attributes=False)
expressions = [node for run in runs for node in ast.walk(run)
if isinstance(node, ast.Expr) and ast.dump(node, include_attributes=False) == expected_dump]
_require(len(expressions) == 1, "frozen Torch trace expression is missing or ambiguous")
module = ast.Module(body=[function], type_ignores=[])
namespace = {"np": np, "Validator": object, "Any": Any}
exec(compile(module, str(source) + "::apply_v2-only", "exec"), namespace)
trace_code = compile(ast.Module(body=[expressions[0]], type_ignores=[]),
str(source) + "::trace-expression-only", "exec")
evidence = dict(source_sha256=actual_sha,
apply_v2_ast_sha256=hashlib.sha256(ast.dump(function, include_attributes=False).encode()).hexdigest(),
trace_expression_ast_sha256=hashlib.sha256(expected_dump.encode()).hexdigest())
return namespace["apply_v2"], trace_code, evidence
@dataclass(frozen=True)
class TraceResult:
command_steps: np.ndarray
snapshots: np.ndarray
final: np.ndarray
audit: dict[str, Any]
@property
def last_command_trace(self) -> np.ndarray:
"""Original runtime's last scheduled-US snapshot, or zero without US."""
return _readonly(self.snapshots[-1] if len(self.snapshots) else np.zeros_like(self.final))
def trace_from_events(step: np.ndarray, neuron_idx: np.ndarray, kc: np.ndarray,
steps: int, command_steps: Any, *, phase4j_source: str | Path,
backend: str = "numpy", n_neurons: int = 166700) -> TraceResult:
"""Replay actual sparse spikes; snapshot AFTER the current tick's spike.
One Boolean spike per global neuron/tick, including refractory ticks as
recorded by the caller. This function does not reconstruct brain dynamics,
infer missing events, or apply any refractory guard to eligibility.
"""
_, trace_code, evidence = _load_original(phase4j_source)
steps = _integer(steps, "steps", 1)
n_neurons = _integer(n_neurons, "n_neurons", 1)
kc = _kc_array(kc, n_neurons)
step = _array(step, np.int32, "step")
neuron_idx = _array(neuron_idx, np.int32, "neuron_idx")
_require(len(step) == len(neuron_idx), "event columns have different lengths")
_require(np.all((step >= 0) & (step < steps)), "event tick outside trial")
_require(np.all((neuron_idx >= 0) & (neuron_idx < n_neurons)), "event neuron outside graph")
_require(np.all((step[1:] > step[:-1]) |
((step[1:] == step[:-1]) & (neuron_idx[1:] > neuron_idx[:-1]))),
"events must be sorted by tick/global ID and unique")
commands = np.asarray(command_steps)
_require(commands.ndim == 1, "command_steps must be one-dimensional")
if commands.size == 0:
commands = np.empty(0, np.int64)
_require(commands.ndim == 1 and commands.dtype.kind in "iu", "command_steps must be integers")
_require(np.all((commands >= 0) & (commands < steps)), "command tick outside trial")
_require(np.all(commands[1:] > commands[:-1]), "command_steps must be sorted unique")
commands = commands.astype(np.int64, copy=True)
_require(backend in ("numpy", "torch"), "backend must be numpy or torch")
lookup = np.full(n_neurons, -1, np.int32)
lookup[kc] = np.arange(len(kc), dtype=np.int32)
local = lookup[neuron_idx]
keep = local >= 0
ticks, local = step[keep], local[keep]
snapshots = np.empty((len(commands), len(kc)), np.float32)
decay = math.exp(-DT_MS / TAU_MS)
command_lookup = {int(t): i for i, t in enumerate(commands)}
cursor = 0
torch_version = None
if backend == "numpy":
trace = np.zeros(len(kc), np.float32)
spike_values = np.zeros(len(kc), np.float32)
else:
try:
import torch
except ImportError as exc:
raise RuntimeError("Torch CPU reference unavailable; compatibility is not established") from exc
torch_version = str(torch.__version__)
trace = torch.zeros(len(kc), dtype=torch.float32, device="cpu")
spike_values = torch.zeros(len(kc), dtype=torch.bool, device="cpu")
environment = dict(torch=torch, kc_trace=trace, trace_decay=decay,
spikes=spike_values,
self=SimpleNamespace(kc_gpu=torch.arange(len(kc), dtype=torch.int64)))
for tick in range(steps):
end = cursor
while end < len(ticks) and ticks[end] == tick:
end += 1
if backend == "numpy":
spike_values.fill(0)
spike_values[local[cursor:end]] = 1
# Separate float32 operations; never power-jump across empty ticks.
np.multiply(trace, np.float32(decay), out=trace)
np.add(trace, spike_values, out=trace)
np.minimum(trace, np.float32(TRACE_CAP), out=trace)
if tick in command_lookup:
snapshots[command_lookup[tick]] = trace
else:
spike_values.zero_()
if end > cursor:
spike_values[torch.from_numpy(local[cursor:end].astype(np.int64, copy=True))] = True
exec(trace_code, environment)
if tick in command_lookup:
snapshots[command_lookup[tick]] = trace.numpy()
cursor = end
final = trace if backend == "numpy" else trace.numpy()
audit = dict(evidence, backend=backend, torch_version=torch_version, numpy_version=str(np.__version__),
steps=steps, kc_count=len(kc), actual_kc_events=int(keep.sum()),
command_count=len(commands), dt_ms=DT_MS, trace_tau_ms=TAU_MS,
trace_cap=TRACE_CAP, decay_python_float=decay,
decay_float32_bits=int(np.asarray(np.float32(decay)).view(np.uint32)),
sampling="after_current_tick_spike", interval_skip_optimization=False,
torch_numpy_bitwise_comparison_performed=False,
d_semantics="artificial scheduled command; not measured DAN activity",
actual_dan_activity_used_to_gate=False, brain_dynamics_executed=False,
training_executed=False, learning_pass_claimed=False)
return TraceResult(_readonly(commands), _readonly(snapshots), _readonly(final), audit)
class _Column:
"""Small immutable-array interface consumed by the frozen function."""
def __init__(self, values: np.ndarray):
self.values = values
def to_numpy(self, dtype: Any = None) -> np.ndarray:
return self.values.astype(dtype, copy=True) if dtype is not None else self.values.copy()
def astype(self, dtype: Any) -> "_Column":
return _Column(self.values.astype(dtype))
def apply_eligibility(trace: np.ndarray, kc: np.ndarray, candidate_sources: np.ndarray,
candidate_compartments: np.ndarray, compartment: str,
delta: np.ndarray, base_candidate: np.ndarray, *, d: float,
frozen: bool = False, phase4j_source: str | Path,
n_neurons: int = 166700) -> tuple[np.ndarray, dict[str, Any]]:
"""Apply the SHA-pinned original apply_v2 AST to candidate-aligned arrays.
delta/base_candidate are ORIGINAL float32 mV values, not SI or reconstructed
float64 D18 weights. Candidate row identity and the complete 14,232-edge mask
are verified by the coordinator; a small synthetic subset is allowed here.
Existing overlays must already obey the original floor and canonical +0.
No input is clipped, repaired, reordered, or mutated.
"""
original, _, evidence = _load_original(phase4j_source)
n_neurons = _integer(n_neurons, "n_neurons", 1)
kc = _kc_array(kc, n_neurons)
trace = _array(trace, np.float32, "trace")
sources = _array(candidate_sources, np.int32, "candidate_sources")
delta = _array(delta, np.float32, "delta")
base = _array(base_candidate, np.float32, "base_candidate")
compartments = np.asarray(candidate_compartments)
_require(compartments.ndim == 1 and compartments.dtype.kind == "U", "candidate_compartments must be Unicode strings")
_require(len(trace) == len(kc) and np.all(np.isfinite(trace)) and np.all((trace >= 0) & (trace <= TRACE_CAP)),
"trace must match KC IDs and lie in [0,1]")
_require(len(delta) == len(base) == len(sources) == len(compartments), "candidate columns have different lengths")
_require(np.all(np.isin(sources, kc)), "all candidate sources must be canonical KCs")
_require(compartment in COMPARTMENTS and np.all(np.isin(compartments, COMPARTMENTS)),
"unrecognized exact frozen compartment")
_require(isinstance(d, (float, int, np.floating, np.integer)) and not isinstance(d, (bool, np.bool_))
and np.isfinite(d) and float(d) in (0.0, 1.0), "D must be the fixed artificial scalar 0 or 1")
_require(isinstance(frozen, (bool, np.bool_)), "frozen must be Boolean")
_require(np.all(np.isfinite(base)) and np.all(base > 0), "original candidate base must be finite positive float32 mV")
lower = -FLOOR_FRACTION * base
_require(np.all(np.isfinite(delta)) and np.all((delta >= lower) & (delta <= 0)), "delta violates original frozen floor")
_require(not np.any((delta == 0) & np.signbit(delta)), "delta zero must be canonical +0 for exact identity")
validator = SimpleNamespace(n=n_neurons, kc=kc.copy(), base_candidate=base.copy(),
cand={"source_neuron_idx": _Column(sources.copy()),
"target_compartment_verbatim": _Column(compartments.copy())})
config = {"eligibility_v2": {"eta_effective_mv": ETA_MV,
"max_fractional_depression": FLOOR_FRACTION}}
if frozen:
result = delta.copy()
original_report = None
else:
result, original_report = original(validator, trace.copy(), compartment, float(d), delta.copy(), config)
selected = compartments == compartment
_require(result.dtype == np.float32 and np.all(np.isfinite(result)), "original update returned invalid values")
_require(bit_equal(result[~selected], delta[~selected]), "off-compartment delta changed")
if frozen or float(d) == 0:
_require(bit_equal(result, delta), "zero-D/frozen identity failed")
_require(np.all((result >= lower) & (result <= 0)), "original result violates frozen floor")
report = dict(evidence, original_apply_v2_executed=not bool(frozen), original_report=original_report,
candidate_count=len(delta), selected_compartment=compartment,
selected_candidate_count=int(selected.sum()), d_command=float(d), frozen=bool(frozen),
actual_changed_edges=int(np.count_nonzero(result != delta)),
off_compartment_exact_unchanged=True, numpy_version=str(np.__version__),
eta_effective_mv=ETA_MV, polarity=POLARITY, floor_fraction=FLOOR_FRACTION,
delta_units="mV", delta_dtype="float32", original_base_units="mV",
complete_mask_identity_verified_by_this_function=False,
actual_dan_activity_used_to_gate=False,
d_semantics="artificial scheduled command; not measured DAN activity",
brain_dynamics_executed=False, training_executed=False, learning_pass_claimed=False)
return _readonly(result), report
@@ -0,0 +1,36 @@
"""Seal interface evidence; never promote static transfer to learned memory."""
import yaml
from context import ROOT, MODEL, EXP, read, save, digest, check, integrity, budget, seal
def main():
check(full=True)
from summarize import run
result = run(verify_only=True)
refs = read(EXP / 'regression/frozen-five.json')
names = [r['name'] for r in yaml.safe_load((ROOT / 'models/male-cns-lif/deterministic-runtime-v2/phase4p.yaml').read_text())['reference_trials']]
assert len(names) == len(set(names)) == 5
assert refs['pass_all'] is True and [r['trial'] for r in refs['trials']] == names
assert all(set(r['exact']) == {'step', 'neuron_idx', 'counts', 'v', 'g'} and
all(v is True for v in r['exact'].values()) for r in refs['trials'])
old = integrity(); save(EXP / 'regression/old-integrity-after.json', old)
final = dict(status=result['status'], zero_overlay_exact=True, static25_repeat_exact=True,
primary_trials_per_stage=120, repeats_per_stage=24, old_integrity_pass=all(r['pass'] for r in old.values()),
frozen_five_reference_pass=True, frozen_eligibility_and_mask_unchanged=True,
base_weights_unchanged=True, training=False, learned_candidate=False,
scientific_summary_sha256=digest(EXP / 'audit/scientific-summary.json'),
payload_bytes_before_manifest=budget(), next_required='Separately preregister finite olfactory paired/control conditioning; no automatic learning PASS')
save(EXP / 'audit/final-status.json', final)
with (EXP / 'REPORT.md').open('x', encoding='utf-8') as f:
f.write('# Phase 4AM — whole-brain plastic interface\n\nStatus: `' + result['status'] + '`.\n\n')
f.write('All 144 zero-overlay runs reproduce sealed AK D18 exactly. All 120 fixed-overlay primary runs and 24 repeats are retained.\n')
f.write('The fixed overlay is the original float32 25% floor, added through the declared float64 SI bridge. No training occurred.\n\n')
for name, block in result['blocks'].items():
f.write('- ' + name + ': ' + '; '.join(pop + ' event changes ' + str(v['trials_event_change']) + '/30' for pop, v in block['populations'].items()) + '.\n')
f.write('\nOld artifacts and five deterministic-v2 references pass integrity/regression. This does not complete the learning goal.\n')
check(full=True); seal(MODEL); seal(EXP)
print(final['status'], flush=True)
if __name__ == '__main__':
main()
@@ -0,0 +1,95 @@
{
"root": "/data/digital-drosophila/models/male-cns-lif/wholebrain-plastic-interface-v1",
"files": [
{
"path": "PREPARATION.md",
"bytes": 1625,
"sha256": "85a3253ceb4e4c5d7bcf17b8b3294dbbf72bd1139415a892f6a90e8037785c89"
},
{
"path": "PROTOCOL.md",
"bytes": 5223,
"sha256": "e03273995f4d5f1fc18d0af481374b8688ae735d83ae718895ffb741f8ac9399"
},
{
"path": "adapter.py",
"bytes": 15690,
"sha256": "3daabe771d3eef6c6189827c0ee5159b266c3a058e07da5781bb863be428aef9"
},
{
"path": "comparison.py",
"bytes": 37000,
"sha256": "4d64020af05e7fc9e535ac8532dd0e7b614b200f695ed8c6d486c6151de57175"
},
{
"path": "config.json",
"bytes": 848,
"sha256": "c19f00c81f12c4c3503d3d557bd73d0722d4d3fed7279449408c67a89a6ffcf9"
},
{
"path": "context.py",
"bytes": 5444,
"sha256": "0fa2e0892c973fe70ecbc0613e3cb508c256b7745042f8936edf23dedc31d166"
},
{
"path": "eligibility_bridge.py",
"bytes": 15196,
"sha256": "174fb8d14619189e74b095e77a6db18b14c93046dc431c0b55710a5aa2dd2e61"
},
{
"path": "finalize.py",
"bytes": 2472,
"sha256": "b8e4fb59d4efa261a8615f1456bc2ad1f1822e941af558b27074b8c41dba15a1"
},
{
"path": "overlay.py",
"bytes": 11355,
"sha256": "7f891d0ba79b393c96e75fd2dee2eddc51e57d8213eaac2779703bc2c18712b4"
},
{
"path": "prepare.py",
"bytes": 9824,
"sha256": "40976f0ed0b01fbf275c245de0f0a907592d23f5ca4733293b41e1d011c7ee62"
},
{
"path": "run_suite.py",
"bytes": 6857,
"sha256": "6a6fcf4cc64d27234ab69ce5a9dcdb8bbd8b3b4965c9c08c2f9d20747025e9e7"
},
{
"path": "summarize.py",
"bytes": 6359,
"sha256": "b4f3cacf3ab60f70d63713d5bbc3e03658f38e357a47ef219b1050003176df01"
},
{
"path": "test_comparison.py",
"bytes": 22896,
"sha256": "a6274f338307a6961e514f565ab3e731051846caf62901e6843037755adc6fd8"
},
{
"path": "test_eligibility_bridge.py",
"bytes": 12900,
"sha256": "113435c0f3528e3901e47421570a5f906d192826df9fc4ee600429a87ab904c5"
},
{
"path": "test_overlay_adapter.py",
"bytes": 14389,
"sha256": "1c0536e0d0c27de6ab152ebb5aa0015ee31325417b17d3cfedc5f43bafa2ee79"
},
{
"path": "test_workflow.py",
"bytes": 2485,
"sha256": "351a0c2887d657e1942b849d768d7efe8c52c0c3c67d0cf4d55658549c3bfe32"
},
{
"path": "test_workflow_identity.py",
"bytes": 11771,
"sha256": "f1453a8814339ec7860ef4dee20549cc811d13cefd7aee2d308ebdfd51a839ca"
},
{
"path": "verify_frozen.py",
"bytes": 2383,
"sha256": "5b121184ec3e666814dd440356604e96520aecdd8902d5b68c7d61caa7f224c5"
}
]
}
@@ -0,0 +1,222 @@
"""Read-only sparse plastic-overlay validation and independent SI arithmetic.
This module does not calculate eligibility, generate learning updates, simulate
neurons, or alter a graph. File loading enforces the complete frozen 14,232-row
candidate identity; the array helpers also accept small synthetic identities.
The externally anchored manifest is a provenance input, not its own authority.
"""
from __future__ import annotations
import hashlib
import json
from pathlib import Path
import re
import numpy as np
CANDIDATE_COUNT = 14232
EDGE_COUNT = 25582938
SCHEMA = 'phase4am-overlay-v1'
BRIDGE = 'baseSI64 + (delta32 widened to float64) * float64(0.001); nonzero rows only'
def require(ok, message):
if not ok:
raise ValueError(message)
def file_hash(path):
digest = hashlib.sha256()
with Path(path).open('rb') as source:
for block in iter(lambda: source.read(8 << 20), b''):
digest.update(block)
return digest.hexdigest()
def raw_hash(value):
require(isinstance(value, np.ndarray), 'Raw hash requires an ndarray')
dtype = value.dtype.newbyteorder('<')
return hashlib.sha256(np.ascontiguousarray(value, dtype=dtype).tobytes()).hexdigest()
def bit_equal(first, second):
return (isinstance(first, np.ndarray) and isinstance(second, np.ndarray) and
first.dtype == second.dtype and first.shape == second.shape and
first.tobytes(order='C') == second.tobytes(order='C'))
def _vector(value, dtype, name, size=None):
require(isinstance(value, np.ndarray) and value.dtype == np.dtype(dtype) and value.ndim == 1,
name + ' requires exact ' + dtype + ' vector; no implicit conversion')
require(size is None or value.shape == (size,), name + ' length differs')
return value
def _ids(value, name):
_vector(value, 'int64', name)
require(np.all((value >= 0) & (value < EDGE_COUNT)) and np.all(value[1:] > value[:-1]),
name + ' must be sorted unique frozen-range global edge IDs')
return value
def _owned(value):
result = np.array(value, copy=True, order='C')
result.flags.writeable = False
return result
def validate_arrays(edge_id, plastic_delta_mv, mask_edge_id, base_candidate_mv=None):
"""Validate/copy arrays; small masks are permitted only for pure unit helpers.
The production file loader separately insists on CANDIDATE_COUNT. Every
nonzero delta needs the original, positive float32 base in legacy mV.
Its bound is the frozen float32 expression -0.25 * base_candidate, NOT
a fraction recomputed from the author's float64 SI runtime weights.
"""
ids, mask = _ids(edge_id, 'edge_id'), _ids(mask_edge_id, 'mask_edge_id')
delta = _vector(plastic_delta_mv, 'float32', 'plastic_delta_mv', len(ids))
require(len(ids) > 0 and bit_equal(ids, mask), 'Candidate IDs must equal the complete anchored mask in order')
require(np.isfinite(delta).all() and np.all(delta <= np.float32(0)), 'Delta must be finite, nonpositive float32 mV')
base = None
if base_candidate_mv is not None:
base = _vector(base_candidate_mv, 'float32', 'base_candidate_mv', len(ids))
require(np.isfinite(base).all() and np.all(base > np.float32(0)), 'Original candidate base must be finite, positive float32 mV')
lower = np.multiply(np.float32(-.25), base)
require(np.all(delta >= lower), 'Delta exceeds the frozen original-float32 -25% bound')
else:
require(not np.any(delta != np.float32(0)), 'Nonzero delta requires the authoritative original float32 base')
return {'edge_id': _owned(ids), 'plastic_delta_mv': _owned(delta),
'base_candidate_mv': None if base is None else _owned(base)}
def _checked_file(manifest, path_key, hash_key):
path = Path(manifest[path_key])
expected = manifest[hash_key]
require(path.is_absolute() and path.is_file(), 'Missing absolute input: ' + path_key)
require(isinstance(expected, str) and re.fullmatch('[0-9a-f]{64}', expected) is not None,
'Malformed SHA256: ' + hash_key)
require(file_hash(path) == expected, 'Input SHA256 mismatch: ' + path_key)
return path
def load_overlay(overlay_file, overlay_manifest):
"""Load immutable, hash-bound production inputs without importing Torch.
Manifest keys: schema, overlay_name (zero/static25), overlay_sha256,
mask_path/mask_sha256, base_candidate_path/base_candidate_sha256 (both
null only for zero), aj_model_dir. Extra provenance fields are retained
in the copied original manifest, not treated as executable instructions.
NPZ keys: edge_id, plastic_delta_mv; optional base_candidate_mv must be
bit-identical to the authoritative external .npy, never a replacement.
"""
overlay_file, manifest_file = Path(overlay_file).absolute(), Path(overlay_manifest).absolute()
require(overlay_file.is_file() and manifest_file.is_file(), 'Missing overlay or manifest')
manifest_bytes = manifest_file.read_bytes()
manifest_sha = hashlib.sha256(manifest_bytes).hexdigest()
metadata = json.loads(manifest_bytes.decode('utf-8'))
required = {'schema', 'overlay_name', 'overlay_sha256', 'mask_path', 'mask_sha256',
'base_candidate_path', 'base_candidate_sha256', 'aj_model_dir'}
require(isinstance(metadata, dict) and required <= metadata.keys(), 'Incomplete overlay manifest')
require(metadata['schema'] == SCHEMA and metadata['overlay_name'] in ('zero', 'static25'), 'Unregistered interface overlay kind')
require(file_hash(overlay_file) == metadata['overlay_sha256'], 'Overlay file SHA256 mismatch')
aj_dir = Path(metadata['aj_model_dir'])
require(aj_dir.is_absolute() and aj_dir.is_dir(), 'aj_model_dir must name the real sealed AJ directory')
mask_path = _checked_file(metadata, 'mask_path', 'mask_sha256')
mask = np.load(mask_path, allow_pickle=False)
_ids(mask, 'authoritative mask')
require(mask.shape == (CANDIDATE_COUNT,), 'Frozen mask must contain exactly 14,232 candidates')
base_path, base = None, None
if metadata['base_candidate_path'] is None:
require(metadata['base_candidate_sha256'] is None, 'Absent base needs a null base hash')
else:
base_path = _checked_file(metadata, 'base_candidate_path', 'base_candidate_sha256')
base = np.load(base_path, allow_pickle=False)
with np.load(overlay_file, allow_pickle=False) as archive:
require({'edge_id', 'plastic_delta_mv'} <= set(archive.files) <=
{'edge_id', 'plastic_delta_mv', 'base_candidate_mv'}, 'Unexpected overlay NPZ schema')
values = validate_arrays(archive['edge_id'], archive['plastic_delta_mv'], mask, base)
if 'base_candidate_mv' in archive.files:
require(base is not None and bit_equal(archive['base_candidate_mv'], base),
'Embedded base is not the authoritative external original float32 base')
delta = values['plastic_delta_mv']
if metadata['overlay_name'] == 'zero':
require(not np.any(delta != 0), 'Named zero overlay is not zero')
else:
require(base is not None and bit_equal(delta, np.multiply(np.float32(-.25), base)),
'static25 must exactly equal the original float32 floor, not 25% of float64 runtime base')
values.update(metadata=metadata, input={
'overlay_file': str(overlay_file), 'overlay_sha256': metadata['overlay_sha256'],
'manifest_file': str(manifest_file), 'manifest_sha256': manifest_sha,
'mask_file': str(mask_path), 'mask_sha256': metadata['mask_sha256'],
'base_candidate_file': None if base_path is None else str(base_path),
'base_candidate_sha256': metadata['base_candidate_sha256']})
verify_inputs(values)
return values
def verify_inputs(plan):
for name in ('overlay', 'manifest', 'mask', 'base_candidate'):
path, expected = plan['input'][name + '_file'], plan['input'][name + '_sha256']
require((path is None and expected is None) or (path is not None and file_hash(path) == expected),
'Overlay input changed: ' + name)
def map_installation(base_si, graph_edge_id, apl_out_mask, plan):
"""Return sparse nonzero installation rows and independently computed values.
Missing zero-delta mask members are permitted in a small fixture. Missing
nonzero members fail closed. APL/candidate overlap is always rejected.
Neither base nor any caller array is changed. Zero delta has no write row.
"""
ids = _ids(graph_edge_id, 'graph_edge_id')
base = _vector(base_si, 'float64', 'base_si', len(ids))
apl = _vector(apl_out_mask, 'bool', 'apl_out_mask', len(ids))
require(np.isfinite(base).all(), 'Nonfinite graph SI base')
candidates = plan['edge_id']
delta = plan['plastic_delta_mv']
rows = np.searchsorted(ids, candidates)
present = rows < len(ids)
present[present] &= ids[rows[present]] == candidates[present]
nonzero = delta != np.float32(0)
require(not np.any(nonzero & ~present), 'A nonzero plastic candidate is absent from this graph')
mapped = rows[present]
require(not np.any(apl[mapped]), 'Plastic candidate overlaps the frozen fast-APL output mask')
require(np.all(base[mapped] > np.float64(0)), 'Candidate graph SI base must remain positive')
selected = rows[nonzero].astype(np.int64)
delta_si = np.multiply(delta[nonzero].astype(np.float64), np.float64(.001))
expected = np.add(base[selected], delta_si)
require(np.isfinite(expected).all() and np.all(expected > 0), 'Overlay would change a candidate sign or create nonfinite weights')
return {'rows': _owned(selected), 'delta_si': _owned(delta_si), 'expected_si': _owned(expected),
'mapped_candidate_count': int(present.sum()), 'missing_candidate_count': int((~present).sum()),
'installed_nonzero_count': int(nonzero.sum()), 'apl_overlap_count': 0}
def materialize_numpy(base_si, graph_edge_id, apl_out_mask, plan):
"""Independent pure CPU reference; used by unit tests, not a brain run."""
mapping = map_installation(base_si, graph_edge_id, apl_out_mask, plan)
result = np.array(base_si, copy=True, order='C')
result[apl_out_mask] = np.float64(0)
result[mapping['rows']] = mapping['expected_si']
return result, mapping
def expected_hashes(base_si, apl_out_mask, mapping, chunk_elements=1 << 20):
"""Bounded-memory base/effective raw hashes, preserving untouched signed bits."""
require(type(chunk_elements) is int and chunk_elements > 0, 'Invalid hash chunk size')
base_hash, effective_hash = hashlib.sha256(), hashlib.sha256()
rows = mapping['rows']
for start in range(0, len(base_si), chunk_elements):
stop = min(start + chunk_elements, len(base_si))
original = np.ascontiguousarray(base_si[start:stop], dtype='<f8')
base_hash.update(original.tobytes())
effective = original.copy()
effective[apl_out_mask[start:stop]] = np.float64(0)
lo, hi = np.searchsorted(rows, (start, stop))
effective[rows[lo:hi] - start] = mapping['expected_si'][lo:hi]
effective_hash.update(effective.tobytes())
return base_hash.hexdigest(), effective_hash.hexdigest()
def array_metadata(value):
return {'dtype': value.dtype.name, 'shape': list(value.shape), 'raw_sha256': raw_hash(value)}
@@ -0,0 +1,145 @@
"""Register the exact zero/static interface tests; create no brain trajectory."""
import ast
from datetime import datetime, timezone
import hashlib
import platform
import shutil
import subprocess
import sys
import numpy as np
import pandas as pd
from context import (ROOT, MODEL, EXP, AK, AL, H, AG, META, AJ_MODEL, CFG, PINS,
read, save, digest, sources, integrity, write_npz)
def old_base_candidate(raw, source_path):
"""Evaluate exactly the pinned old assignment RHS; all candidate KC signs +1."""
assert raw.dtype == np.int64 and raw.ndim == 1 and np.all(raw > 0)
tree = ast.parse(source_path.read_text())
runtime = next(n for n in tree.body if isinstance(n, ast.ClassDef) and n.name == 'Runtime')
init = next(n for n in runtime.body if isinstance(n, ast.FunctionDef) and n.name == '__init__')
selected = [n for n in ast.walk(init) if isinstance(n, ast.Assign) and any(
isinstance(t, ast.Subscript) and isinstance(t.value, ast.Name) and t.value.id == 'effective'
for t in n.targets)]
assert len(selected) == 1
value = selected[0].value
assert ast.unparse(value) == "raw_np[a:b].astype(np.float32) * signs[src] * float(cfg['model']['w_syn_mv_per_anatomical_synapse'])"
env = dict(raw_np=raw, a=0, b=len(raw), np=np, signs=np.array([1], np.int8), src=0,
cfg={'model': {'w_syn_mv_per_anatomical_synapse': .275}}, float=float)
out = eval(compile(ast.Expression(value), str(source_path), 'eval'), {'__builtins__': {}}, env)
assert out.dtype == np.float32 and np.isfinite(out).all() and np.all(out > 0)
return out, hashlib.sha256(ast.dump(value, include_attributes=False).encode()).hexdigest()
def main():
assert not EXP.exists() or (EXP.is_dir() and not any(EXP.iterdir())), 'Never reuse a populated experiment'
assert shutil.disk_usage(EXP.parent).free > CFG['output_budget_bytes'] + 10 * 1024**3
for relative, sha in PINS.items():
assert digest(ROOT / relative) == sha, relative
assert read(AL / 'audit/final-status.json')['status'] == 'PASS-CONDITIONAL-CREDIT-TRANSFER-AUDIT-NOT-LEARNING'
assert CFG['stages'] == ['zero', 'static25'] and not CFG['training'] and not CFG['candidate_generation']
records = read(AK / 'protocol/validation-cases.json')
assert len(records) == 120 and len({r['name'] for r in records}) == 120
first_seed = min(r['seed'] for r in records)
planned = [dict(row, repeat=repeat) for row in records
for repeat in ((0, 1) if row['seed'] == first_seed else (0,))]
assert len(planned) == 144
inputs = dict(PINS)
static = [AK / 'protocol/validation-cases.json',
H / 'mappings/mbon-to-downstream-actual-edges.parquet',
ROOT / 'experiments/phase4l-olfactory-grounding/odor-encoder/selection.json',
ROOT / 'experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json']
static += list((AG / 'graphs/full').glob('*.npy')) + list((AG / 'apl-bundle').glob('*.npy'))
raw_path = ROOT / 'datasets/male-cns-v1.0/processed/neuron-only/gpu/csr-weights.int64.npy'
static.append(raw_path)
for row in planned:
case = AK / 'cases' / row['cohort'] / row['name']
spec = read(case / 'spec.json')
assert spec['steps'] == 1000 and spec['dt_ms'] == .1 and spec['apl_delay_steps'] == 18
assert spec['model']['w_syn_mv_per_anatomical_synapse'] == .275
static += [case / 'spec.json', case / 'requests.npz']
for p in static:
inputs[p.relative_to(ROOT).as_posix()] = digest(p)
for name in ('protocol', 'overlays', 'gpu', 'audit', 'regression', 'logs', 'extension-build', 'summaries'):
(EXP / name).mkdir(parents=True, exist_ok=False)
test = subprocess.run([sys.executable, '-B', '-m', 'unittest', 'discover', '-v', '-s', str(MODEL)],
cwd=MODEL, text=True, capture_output=True)
with (EXP / 'regression/unit-tests.log').open('x', encoding='utf-8') as f:
f.write(test.stdout + test.stderr)
save(EXP / 'regression/unit-tests.json', dict(pass_all=test.returncode == 0,
exit_code=test.returncode, log_sha256=digest(EXP / 'regression/unit-tests.log')))
assert test.returncode == 0, 'Unit tests failed; preserve partial experiment'
assert 'skipped=' not in test.stderr, 'All server compatibility tests must execute'
save(EXP / 'protocol/preregistered.json', dict(timestamp_utc=datetime.now(timezone.utc).isoformat(),
sources=sources(), config=CFG, planned=planned,
inputs=[dict(path=k, sha256=v) for k, v in sorted(inputs.items())],
parent_commit=subprocess.check_output(['git', '-C', str(ROOT), 'rev-parse', 'HEAD'], text=True).strip(),
before_new_brain_trajectories=True, prior_AK_AL_results_known=True,
no_dynamic_pair_selection=True, training=False, candidate_generated=False,
python=sys.version, numpy=np.__version__, platform=platform.platform()))
save(EXP / 'regression/old-integrity-before.json', integrity())
candidate = pd.read_parquet(H / 'plastic-mask/plastic-edge-candidates.parquet')
mask_path = H / 'plastic-mask/plastic-edge-ids.int64.npy'
ids = np.load(mask_path, allow_pickle=False)
mask = np.load(H / 'plastic-mask/plastic-edge-mask.bool.npy', allow_pickle=False)
assert ids.dtype == np.int64 and ids.shape == (14232,)
assert np.array_equal(candidate.edge_id, ids) and np.array_equal(np.flatnonzero(mask), ids)
graph = {k: np.load(AG / 'graphs/full' / (k + '.npy'), mmap_mode='r')
for k in ('src', 'dst', 'edge_id', 'weights', 'signed_raw', 'nodes')}
assert np.array_equal(graph['nodes'], np.arange(166700, dtype=np.int32))
assert np.array_equal(graph['edge_id'], np.arange(25582938, dtype=np.int64))
assert np.array_equal(graph['src'][ids], candidate.source_neuron_idx)
assert np.array_equal(graph['dst'][ids], candidate.target_neuron_idx)
raw = np.load(raw_path, mmap_mode='r')
assert np.array_equal(raw[ids], candidate.raw_synapse_count)
assert np.array_equal(graph['signed_raw'][ids], raw[ids]), 'Original candidate sign must be +1'
assert np.all(graph['weights'][ids] > 0) and (candidate.plasticity_polarity == -1).all()
base, rhs_sha = old_base_candidate(raw[ids], ROOT / 'models/male-cns-lif/phase4c.py')
base_path = EXP / 'protocol/base-candidate.float32-mV.npy'
with base_path.open('xb') as f:
np.save(f, base, allow_pickle=False)
for stage in CFG['stages']:
delta = np.zeros(len(ids), np.float32) if stage == 'zero' else (-float(.25) * base).astype(np.float32)
path = EXP / 'overlays' / (stage + '.npz')
write_npz(path, edge_id=ids, plastic_delta_mv=delta)
save(EXP / 'overlays' / (stage + '.json'), dict(schema='phase4am-overlay-v1', overlay_name=stage,
overlay_sha256=digest(path), mask_path=str(mask_path), mask_sha256=digest(mask_path),
base_candidate_path=str(base_path), base_candidate_sha256=digest(base_path),
aj_model_dir=str(AJ_MODEL), base_rhs_ast_sha256=rhs_sha,
old_f32_expression_source_sha256=digest(ROOT / 'models/male-cns-lif/phase4c.py'),
training=False, fixed_for_whole_trial=True))
meta = pd.read_parquet(META).sort_values('neuron_idx').reset_index(drop=True)
assert np.array_equal(meta.neuron_idx.to_numpy(), graph['nodes'])
kc = np.flatnonzero(meta.annotation_class.eq('Kenyon_Cell')).astype(np.int32)
mbon = np.flatnonzero(meta.annotation_class.eq('MBON')).astype(np.int32)
assert len(kc) == 4064 and len(mbon) == 97
assert np.isin(candidate.source_neuron_idx, kc).all() and np.isin(candidate.target_neuron_idx, mbon).all()
down = pd.read_parquet(H / 'mappings/mbon-to-downstream-actual-edges.parquet')
assert np.array_equal(graph['src'][down.edge_id.to_numpy()], down.source_neuron_idx.to_numpy())
assert np.array_equal(graph['dst'][down.edge_id.to_numpy()], down.target_neuron_idx.to_numpy())
populations = dict(KC=kc, MBON=mbon,
mask_recipient_MBON=np.unique(candidate.target_neuron_idx.to_numpy(dtype=np.int32)),
DAN=np.flatnonzero(meta.annotation_class.eq('DAN')).astype(np.int32),
MBON_downstream=np.unique(down.target_neuron_idx.to_numpy(dtype=np.int32)))
# Exact observed superclass strings are checked; no inferred body identity.
role_labels = {'descending': ['descending_neuron', 'descending_neuron_tbc'],
'motor': ['vnc_motor', 'cb_motor']}
for name, labels in role_labels.items():
assert set(labels).issubset(set(meta.annotation_superclass.dropna().astype(str))), labels
populations[name] = np.flatnonzero(meta.annotation_superclass.isin(labels)).astype(np.int32)
write_npz(EXP / 'protocol/populations.npz', **populations)
save(EXP / 'protocol/static-audit.json', dict(candidate_edges=len(ids), mask_fixed=True,
old_base_rhs_ast_sha256=rhs_sha, populations={k: len(v) for k, v in populations.items()},
exact_descending_motor_superclass_labels=role_labels,
compartments={str(k): len(g) for k, g in candidate.groupby('target_compartment_verbatim')},
old_selected_odors=read(ROOT / 'experiments/phase4l-olfactory-grounding/odor-encoder/selection.json'),
source_mapping='Exact annotation_class/superclass and frozen actual-edge table; no inferred type/body IDs',
old_base_signed_positive=True, training=False))
save(EXP / 'protocol/prepared-hashes.json', [dict(path=p.relative_to(EXP).as_posix(), sha256=digest(p))
for folder in ('protocol', 'overlays') for p in sorted((EXP / folder).rglob('*'))
if p.is_file() and p.name != 'prepared-hashes.json'])
print('PREREGISTERED zero 144 then static25 144; no brain trajectories or training', flush=True)
if __name__ == '__main__':
main()
@@ -0,0 +1,132 @@
"""Finite fixed inventory; no overwrites, no automatic scientific retries."""
import argparse
import json
import os
import time
import traceback
import urllib.request
from context import ROOT, MODEL, EXP, AK, CFG, read, save, digest, check, budget
def preflight():
os.environ['CUDA_VISIBLE_DEVICES'] = CFG['gpu_uuid']
os.environ['CUDA_HOME'] = '/usr/local/cuda'
os.environ['PATH'] = str(ROOT / 'models/male-cns-lif/.venv/bin') + ':/usr/local/cuda/bin:' + os.environ['PATH']
os.environ['MAX_JOBS'] = '2'
os.environ['TORCH_CUDA_ARCH_LIST'] = '8.9'
for port in (8188, 8189, 8190):
with urllib.request.urlopen(f'http://192.168.10.51:{port}/queue', timeout=5) as response:
q = json.load(response)
assert not q['queue_running'] and not q['queue_pending'], 'ComfyUI busy: defer, never evict'
def output_inventory(folder):
return [dict(path=p.relative_to(folder).as_posix(), bytes=p.stat().st_size, sha256=digest(p))
for p in sorted(folder.rglob('*')) if p.is_file() and p.name != 'output-hashes.json']
def compare_expected(stage, row, folder):
from comparison import compare_runs, validate_run
case = AK / 'cases' / row['cohort'] / row['name']
if stage == 'zero':
reference = AK / 'gpu' / row['cohort'] / (row['name'] + '-r' + str(row['repeat']))
return compare_runs(case, reference, folder, mode='zero')
if row['repeat'] == 1:
reference = EXP / 'gpu' / stage / (row['name'] + '-r0')
return compare_runs(case, reference, folder, mode='repeat')
return validate_run(case, folder)
def verify_identity(folder, stage, row):
assert stage in CFG['stages'] and row['repeat'] in (0, 1)
assert folder == EXP / 'gpu' / stage / (row['name'] + '-r' + str(row['repeat']))
case = AK / 'cases' / row['cohort'] / row['name']
summary = read(folder / 'summary.json')
assert summary['case'] == row['name'] and summary['complete'] and summary['pass_all']
assert summary['input_sha256']['spec.json'] == digest(case / 'spec.json')
assert summary['input_sha256']['requests.npz'] == digest(case / 'requests.npz')
overlay = read(folder / 'overlay-audit.json')
assert overlay['complete'] and overlay['overlay_name'] == stage
assert overlay['input']['overlay_sha256'] == digest(EXP / 'overlays' / (stage + '.npz'))
assert overlay['input']['manifest_sha256'] == digest(EXP / 'overlays' / (stage + '.json'))
report = read(folder / 'comparison.json')
assert report['pass_all'] and report['overlay_name'] == stage
assert report['case_dir'] == str(case) and report['right'] == str(folder)
if stage == 'zero':
assert report['mode'] == 'zero'
assert report['left'] == str(AK / 'gpu' / row['cohort'] / (row['name'] + '-r' + str(row['repeat'])))
elif row['repeat'] == 1:
assert report['mode'] == 'repeat' and report['left'] == str(EXP / 'gpu' / stage / (row['name'] + '-r0'))
else:
assert report['mode'] == 'self' and report['left'] == str(folder)
def verify_completed(folder, stage=None, row=None, recompute=False):
rows = read(folder / 'output-hashes.json')
assert rows == output_inventory(folder), 'Completed output bytes changed: ' + str(folder)
assert read(folder / 'comparison.json')['pass_all']
assert read(folder / 'summary.json')['complete']
if stage is not None:
verify_identity(folder, stage, row)
if recompute:
report = compare_expected(stage, row, folder)
assert report['pass_all'] and report == read(folder / 'comparison.json'), 'Recomputed comparison differs'
def run(stage):
assert stage in CFG['stages']
reg = check(full=True); budget()
assert not list((EXP / 'audit').glob('stopped-*.json')), 'Previous failure: preserve and inspect, never silently retry'
receipt = EXP / 'audit' / (stage + '-complete.json')
assert not receipt.exists(), 'Stage already completed'
if stage == 'static25':
prior = read(EXP / 'audit/zero-complete.json')
assert prior['pass_all'] and prior['trials'] == 144
for row in reg['planned']:
verify_completed(EXP / 'gpu/zero' / (row['name'] + '-r' + str(row['repeat'])), 'zero', row)
preflight()
from adapter import run_gpu_overlay
began = time.perf_counter()
completed = []
try:
for ordinal, row in enumerate(reg['planned'], 1):
key = row['name'] + '-r' + str(row['repeat'])
folder = EXP / 'gpu' / stage / key
case = AK / 'cases' / row['cohort'] / row['name']
if folder.exists():
verify_completed(folder, stage, row, recompute=True)
print('VERIFIED-COMPLETED', stage, ordinal, key, flush=True)
else:
preflight(); check(); budget()
print('START', stage, ordinal, key, flush=True)
summary = run_gpu_overlay(case, folder, EXP / 'extension-build',
EXP / 'overlays' / (stage + '.npz'), EXP / 'overlays' / (stage + '.json'))
assert summary['pass_all'] and summary['complete']
report = compare_expected(stage, row, folder)
save(folder / 'comparison.json', report)
assert report['pass_all'], 'Independent recording/equivalence gate failed: ' + key
save(folder / 'output-hashes.json', output_inventory(folder))
verify_completed(folder, stage, row)
print('COMPLETE', stage, ordinal, key, 'simulation_seconds', summary['diagnostic_simulation_seconds'], flush=True)
completed.append(dict(name=row['name'], repeat=row['repeat'],
output_hashes_sha256=digest(folder / 'output-hashes.json'),
comparison_sha256=digest(folder / 'comparison.json')))
assert len(completed) == 144
check(full=True)
result = dict(stage=stage, pass_all=True, trials=144, primary_trials=120, technical_repeats=24,
completed=completed, wall_seconds=time.perf_counter() - began, training=False,
scope='All zero-delta runs exactly match sealed AK' if stage == 'zero' else
'Full closed-loop fixed overlay, internal event/queue accounting and 24 exact technical repeats; not learning')
save(receipt, result); budget()
return result
except Exception as error:
save(EXP / 'audit' / ('stopped-' + stage + '.json'), dict(stage=stage,
completed_before_error=completed, type=type(error).__name__, message=str(error),
traceback=traceback.format_exc(), partial_outputs_preserved=True, no_parameter_rescue=True))
raise
if __name__ == '__main__':
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('stage', choices=CFG['stages'])
run(parser.parse_args().stage)
@@ -0,0 +1,106 @@
"""Complete paired static-overlay effects; no learned-memory inference."""
import numpy as np
import pandas as pd
from context import EXP, CFG, read, save, digest, bit_equal
from run_suite import verify_completed
def load(path):
with np.load(path, allow_pickle=False) as data:
return {k: data[k].copy() for k in data.files}
def first_ticks(state, n=166700):
out = np.full(n, np.iinfo(np.int32).max, np.int32)
np.minimum.at(out, state['neuron_idx'], state['step'])
out[out == np.iinfo(np.int32).max] = -1
return out
def metrics(base, changed, population):
a, b = base['counts'][population], changed['counts'][population]
af, bf = first_ticks(base)[population], first_ticks(changed)[population]
ae = np.isin(base['neuron_idx'], population); be = np.isin(changed['neuron_idx'], population)
same = bit_equal(base['step'][ae], changed['step'][be]) and bit_equal(base['neuron_idx'][ae], changed['neuron_idx'][be])
ax = base['step'][ae].astype(np.int64) * 166700 + base['neuron_idx'][ae]
bx = changed['step'][be].astype(np.int64) * 166700 + changed['neuron_idx'][be]
different = np.setxor1d(ax, bx, assume_unique=True)
return dict(cells=len(population), base_active=int(np.count_nonzero(a)), changed_active=int(np.count_nonzero(b)),
base_spikes=int(a.sum()), changed_spikes=int(b.sum()),
recruited_cells=int(np.count_nonzero((a == 0) & (b > 0))), lost_cells=int(np.count_nonzero((a > 0) & (b == 0))),
count_changed_cells=int(np.count_nonzero(a != b)), first_spike_changed_cells=int(np.count_nonzero(af != bf)),
count_l1=int(np.abs(a.astype(np.int64) - b.astype(np.int64)).sum()), event_sequence_changed=not same,
first_event_divergence_ms=None if not len(different) else float(different.min() // 166700 * .1),
final_v_max_abs_SI=float(np.max(np.abs(base['v'][population] - changed['v'][population]))) if len(population) else None,
final_g_max_abs_SI=float(np.max(np.abs(base['g'][population] - changed['g'][population]))) if len(population) else None)
def run(verify_only=False):
def emit(path, value):
if verify_only:
assert read(path) == value, str(path)
else:
save(path, value)
reg = read(EXP / 'protocol/preregistered.json')
for stage in CFG['stages']:
receipt = read(EXP / 'audit' / (stage + '-complete.json'))
assert receipt['pass_all'] and receipt['trials'] == 144
assert len(receipt['completed']) == 144
for row, entry in zip(reg['planned'], receipt['completed']):
assert entry['name'] == row['name'] and entry['repeat'] == row['repeat']
folder = EXP / 'gpu' / stage / (row['name'] + '-r' + str(row['repeat']))
verify_completed(folder, stage, row, recompute=True)
assert digest(folder / 'output-hashes.json') == entry['output_hashes_sha256']
assert digest(folder / 'comparison.json') == entry['comparison_sha256']
pops = load(EXP / 'protocol/populations.npz')
rows, cellrows, times, peaks = [], [], [], []
for row in reg['planned']:
if row['repeat']:
continue
key = row['name'] + '-r0'
base, changed = [load(EXP / 'gpu' / stage / key / 'state.npz') for stage in CFG['stages']]
effects = {name: metrics(base, changed, nodes) for name, nodes in pops.items()}
result = dict(**row, effects=effects, whole_brain=metrics(base, changed, np.arange(166700, dtype=np.int32)))
emit(EXP / 'summaries' / (row['name'] + '.json'), result); rows.append(result)
af, bf = first_ticks(base), first_ticks(changed)
for neuron in pops['MBON']:
n = int(neuron)
cellrows.append(dict(case=row['name'], cohort=row['cohort'], mode=row['mode'], seed=row['seed'],
neuron_idx=n, base_count=int(base['counts'][n]), static25_count=int(changed['counts'][n]),
base_first_tick=int(af[n]), static25_first_tick=int(bf[n]),
base_final_v_SI=float(base['v'][n]), static25_final_v_SI=float(changed['v'][n]),
base_final_g_SI=float(base['g'][n]), static25_final_g_SI=float(changed['g'][n])))
for stage in CFG['stages']:
s = read(EXP / 'gpu' / stage / key / 'summary.json')
times.append(dict(stage=stage, case=row['name'], wall_seconds=s['wall_seconds'],
simulation_seconds=s['diagnostic_simulation_seconds']))
peaks.append(s['peak_allocated_vram_bytes'])
table = pd.DataFrame(cellrows)
table_path = EXP / 'summaries/per-MBON-static-effects.parquet'
if verify_only:
pd.testing.assert_frame_equal(table, pd.read_parquet(table_path), check_exact=True)
else:
assert not table_path.exists(); table.to_parquet(table_path, index=False)
blocks = {}
for cohort in sorted({r['cohort'] for r in rows}):
for mode in sorted({r['mode'] for r in rows}):
block = [r for r in rows if r['cohort'] == cohort and r['mode'] == mode]
assert len(block) == 30
blocks[cohort + '/' + mode] = dict(trials=30, populations={name: dict(
trials_event_change=sum(r['effects'][name]['event_sequence_changed'] for r in block),
trials_count_change=sum(r['effects'][name]['count_changed_cells'] > 0 for r in block),
mean_count_l1=float(np.mean([r['effects'][name]['count_l1'] for r in block])),
mean_recruited_cells=float(np.mean([r['effects'][name]['recruited_cells'] for r in block])),
mean_lost_cells=float(np.mean([r['effects'][name]['lost_cells'] for r in block]))) for name in pops})
summary = dict(status='PASS-EXACT-WHOLEBRAIN-PLASTIC-INTERFACE-NOT-LEARNING',
primary_trials_per_stage=120, technical_repeats_per_stage=24, zero_overlay_exact=True,
static25_repeat_exact=True, blocks=blocks, peak_allocated_vram_bytes=max(peaks),
timing=times, per_MBON_sha256=digest(table_path), training=False, learned_candidate=False,
conditional_AL_not_a_nonzero_arithmetic_oracle=True,
scope='Valid interface and recording; reported static response is not an associative learning PASS')
emit(EXP / 'audit/scientific-summary.json', summary)
return summary
if __name__ == '__main__':
print(run()['status'], flush=True)
@@ -0,0 +1,363 @@
"""Pure temporary-file synthetic tests; never a brain run or old-file write.
Public integration tests mock only the full-case loader to use a tiny graph.
The sealed output parser, timing/queue reconstructor, overlay bridge, source AST
and receipt checks remain real. Production rejects these tiny cases unchanged.
"""
import copy
import hashlib
import json
from pathlib import Path
import shutil
import tempfile
import unittest
from unittest.mock import patch
import numpy as np
import comparison as c
def write_json(path, data):
Path(path).write_text(json.dumps(data, sort_keys=True, allow_nan=False), encoding='utf-8')
class ComparisonTests(unittest.TestCase):
def setUp(self):
self.temp = tempfile.TemporaryDirectory(prefix='phase4am-comparison-synthetic-')
self.addCleanup(self.temp.cleanup)
self.root = Path(self.temp.name).resolve()
self.case_dir = self.root / 'case'
self.graph_dir = self.root / 'graph'
self.bundle_dir = self.root / 'bundle'
for p in (self.case_dir, self.graph_dir, self.bundle_dir):
p.mkdir()
self.helper = c._helper(set())
self.steps = 30
self.graph = dict(nodes=np.arange(4, dtype=np.int32), edge_id=np.arange(6, dtype=np.int64),
ptr=np.array([0, 2, 3, 5, 6], np.int64), src=np.array([0, 0, 1, 2, 2, 3], np.int32),
dst=np.array([3, 2, 2, 0, 3, 1], np.int32), signed_raw=np.array([1, 0, 2, -2, 3, 1], np.int64))
self.graph['weights'] = self.graph['signed_raw'] * (.275 * .001)
for key, value in self.graph.items():
np.save(self.graph_dir / (key + '.npy'), value)
self.bundle = {'kc_globals.npy': np.r_[np.array([0, 1], np.int32), np.arange(4, 4066, dtype=np.int32)],
'apl_globals.npy': np.array([2, 3], np.int32), 'input_matrix.npy': np.zeros((2, c.N), np.float32),
'output_matrix.npy': np.zeros((2, c.K), np.float32)}
for key, value in self.bundle.items():
np.save(self.bundle_dir / key, value)
self.requests = [(0, 0), (1, 1), (2, 0), (22, 0), (23, 3)]
np.savez(self.case_dir / 'requests.npz', tick=np.array([x[0] for x in self.requests], np.int32),
neuron_idx=np.array([x[1] for x in self.requests], np.int32))
write_json(self.case_dir / 'spec.json', {'name': 'synthetic', 'steps': self.steps,
'dt_ms': .1, 'duration_ms': 3., 'record_history': False, 'apl_delay_steps': 18})
write_json(self.root / 'coeff.json', {'synthetic': True})
self.case = dict(spec=json.loads((self.case_dir / 'spec.json').read_text()), graph=self.graph,
bundle=self.bundle, token=('synthetic', str(self.root)), graph_dir=self.graph_dir, bundle_dir=self.bundle_dir,
requested=self.requests, input_hashes={'spec.json': c.file_hash(self.case_dir / 'spec.json'),
'requests.npz': c.file_hash(self.case_dir / 'requests.npz'), 'base_weights.npy': c.file_hash(self.graph_dir / 'weights.npy'),
'coefficients.json': c.file_hash(self.root / 'coeff.json')})
self.ids = np.array([0, 2], np.int64)
self.base = np.array([.275, .55], np.float32)
np.save(self.root / 'mask.npy', self.ids)
np.save(self.root / 'base.npy', self.base)
self.delta = np.zeros(2, np.float32)
self.overlay_name = 'zero'
self._overlay_inputs()
def _overlay_inputs(self):
np.savez(self.root / 'overlay.npz', edge_id=self.ids, plastic_delta_mv=self.delta)
write_json(self.root / 'overlay-manifest.json', dict(schema='phase4am-overlay-v1', overlay_name=self.overlay_name,
overlay_sha256=c.file_hash(self.root / 'overlay.npz'), mask_path=str(self.root / 'mask.npy'),
mask_sha256=c.file_hash(self.root / 'mask.npy'), base_candidate_path=str(self.root / 'base.npy'),
base_candidate_sha256=c.file_hash(self.root / 'base.npy'),
aj_model_dir=str(Path(c.__file__).resolve().parent.parent / 'apl-timing-lab-v1')))
def run_files(self, name, wrapped):
directory = self.root / name
directory.mkdir()
ticks = np.array([0, 1, 18, 22, 23], np.int32)
nodes = np.array([0, 1, 2, 0, 3], np.int32)
state = dict(step=ticks, neuron_idx=nodes, counts=np.bincount(nodes, minlength=4).astype(np.int32),
v=np.full(4, -.052, np.float64), g=np.zeros(4, np.float64))
hashes, queues, requests = [], [], []
last = np.full(4, -1000000000, np.int64)
for tick in range(self.steps):
fired = nodes[ticks == tick]
for request_tick, target in self.requests:
if request_tick == tick:
ok = tick - last[target] >= 22
requests.append(dict(tick=tick, neuron_idx=target, attempted=1, accepted=int(ok), rejected=int(not ok)))
last[fired] = tick
ref = np.maximum(22 - (tick - last), 0).astype(np.int32)
hashes.append(dict(tick=tick, v_sha256=c.raw_hash(state['v']), g_sha256=c.raw_hash(state['g']), ref_sha256=c.raw_hash(ref)))
sources = nodes[ticks == tick - 18] if tick >= 18 else []
rows = np.array([eid for source in sources for eid in range(self.graph['ptr'][source], self.graph['ptr'][source + 1])], np.int64)
accepted = (ref[self.graph['dst'][rows]] == 0).astype(np.uint8)
queues.append(self.helper._queue_digest(tick, rows, accepted))
state['ref'] = ref
np.savez(directory / 'state.npz', **state)
for filename, rows in (('tick-state-hashes.jsonl', hashes), ('queue.jsonl', queues)):
(directory / filename).write_text(''.join(json.dumps(row) + '\n' for row in rows), encoding='utf-8')
(directory / 'requests.csv').write_text('tick,neuron_idx,attempted,accepted,rejected\n' +
''.join(','.join(str(row[key]) for key in c._helper(set()).REQUEST_FIELDS) + '\n' for row in requests), encoding='utf-8')
for field, width in (('drive', 2), ('state', 2), ('inhibition', c.K), ('applied', c.K)):
np.save(directory / ('apl-' + field + '.float32.npy'), np.zeros((self.steps, width), np.float32))
pending = np.zeros((18, c.K), np.float32)
np.save(directory / 'apl-pending-tail.float32.npy', pending)
timing = dict(apl_delay_steps=18, steps=self.steps, pending_generated_count=18, generated_rows=self.steps,
applied_generated_rows=self.steps - 18, pending_shape=[18, c.K], pending_initial_zero_prefix=0,
pending_application_tick_start=self.steps, pending_application_tick_stop_exclusive=self.steps + 18,
pending_generated_tick_start=self.steps - 18, pending_generated_tick_stop_exclusive=self.steps,
pending_raw_sha256=c.raw_hash(pending), final_apl_state_float32=[0., 0.], final_apl_state_u32_bits=[0, 0],
final_apl_state_nonzero=False, brain_tail_advanced=False, future_apl_decay_or_feedback_generated=False,
finite_generated_sequence_only=True, closed_loop_branch_integrals_claimed_equal=False,
biological_delay_measurement_claimed=False)
write_json(directory / 'apl-timing-audit.json', timing)
component = dict(ok=True, protocol='phase4ag-apl-v1', n_neurons=c.N, n_apl=2, n_kc=c.K, dt_ms=.1,
files_sha256={key: c.file_hash(self.bundle_dir / key) for key in self.bundle},
array_sha256={key: c.raw_hash(value) for key, value in self.bundle.items()},
decay_f32_bits=f'{int(np.float32(np.exp(-.1 / 20.)).view(np.uint32)):08x}',
gain_f32_bits=f'{int(np.float32(.01).view(np.uint32)):08x}',
environment=dict(device_name='NVIDIA GeForce RTX 4090', cuda_matmul_allow_tf32=False,
float32_matmul_precision='highest', precision_configuration_changed_by_component=False))
write_json(directory / 'apl-component.json', component)
(directory / 'sealed-gpu-source.diff').write_text('synthetic diff, not executed\n', encoding='utf-8')
provenance = dict(sealed_source_sha256=c.SEALED, candidate_sha256=c.AJ_SHA,
source_diff_sha256=c.file_hash(directory / 'sealed-gpu-source.diff'), module_globals_patched=False)
write_json(directory / 'source-audit.json', provenance)
_, effective_sha, apl_count = c._effective_hash(self.case, self.ids if wrapped else None, self.delta if wrapped else None)
summary = dict(case='synthetic', complete=True, pass_all=True, steps=self.steps, completed_ticks=self.steps,
nodes=4, edges=6, precision='float64', apl_precision='float32', state_units='SI volts', total_spikes=len(ticks),
requested=len(requests), accepted_requests=sum(row['accepted'] for row in requests),
rejected_requests=sum(row['rejected'] for row in requests), arriving_edges=sum(row['count'] for row in queues),
accepted_arriving_edges=sum(row['accepted_count'] for row in queues), counts_match_sparse_events=True,
all_finite=True, record_history=False, apl_fast_edges_zeroed=apl_count, kc_targets_present=c.K,
effective_weights_raw_sha256=effective_sha, apl_component=component,
apl_schedule='end, after threshold/reset and guarded arrivals, unconditional all KC',
apl_si_conversion='applied h32 -> float64 -> multiply float64 0.001 -> separate float64 subtraction',
apl_delay_steps=18, apl_timing=timing, source_provenance=provenance, pending_generated_count=18,
pending_initial_zero_prefix=0, pending_tail_shape=[18, c.K], future_generated_decay_tail_included=False,
build=dict(sources={'author_ext.cpp': c.CPP_SHA, 'author_ext.cu': c.CUDA_SHA}, arch_list='8.9',
cuda_flags=['-O2', '--fmad=false', '--ftz=false', '--prec-div=true', '--prec-sqrt=true']),
sealed_ae_backend_sha256=c.SEALED['ae_backend'], learning=False, input_sha256=self.case['input_hashes'],
**{key: 1.0 for key in c.PERFORMANCE})
write_json(directory / 'summary.json', summary)
if wrapped:
self._write_overlay(directory, summary)
return directory
def _write_overlay(self, directory, summary):
for source, target in (('overlay.npz', 'overlay-input.npz'), ('overlay-manifest.json', 'overlay-manifest.json')):
shutil.copyfile(self.root / source, directory / target)
input_rows = {}
for label, filename in (('overlay', 'overlay.npz'), ('manifest', 'overlay-manifest.json'), ('mask', 'mask.npy'), ('base_candidate', 'base.npy')):
input_rows[label + '_file'] = str(self.root / filename)
input_rows[label + '_sha256'] = c.file_hash(self.root / filename)
audit = dict(schema='phase4am-overlay-audit-v1', complete=True, overlay_name=self.overlay_name, input=input_rows,
arrays={key: dict(dtype=str(value.dtype), shape=list(value.shape), raw_sha256=c.raw_hash(value)) for key, value in
dict(edge_id=self.ids, plastic_delta_mv=self.delta, base_candidate_mv=self.base).items()},
candidate_count=2, nonzero_delta_count=int(np.count_nonzero(self.delta)), mapped_candidate_count=2,
missing_candidate_count=0, installed_nonzero_count=int(np.count_nonzero(self.delta)), delta_dtype='float32',
delta_units='mV', state_dtype='float64', bridge=c.BRIDGE, installation_schedule=c.SCHEDULE,
weights_updated_during_run=False, learning=False, zero_delta_no_write=True, frozen_mask_exact=True,
bounds_pass=True, apl_overlap_count=0, apl_fast_edges_zeroed=summary['apl_fast_edges_zeroed'],
base_graph_files_modified=False, untouched_weights_bitwise_preserved=True,
base_weights_file_sha256=c.file_hash(self.graph_dir / 'weights.npy'), base_weights_raw_sha256=c._base_raw_hash(self.case),
effective_weights_raw_sha256=summary['effective_weights_raw_sha256'],
expected_effective_weights_raw_sha256=summary['effective_weights_raw_sha256'],
copied_overlay_file='overlay-input.npz', copied_manifest_file='overlay-manifest.json',
inherited_aj_source_provenance=summary['source_provenance'],
inherited_source_audit_scope='AJ source provenance only; AM overlay semantics are recorded separately',
static25_is_exact_fraction_of_float64_base_claimed=False, arrival_weight_sampling='arrival time; delta fixed for entire trial')
write_json(directory / 'overlay-audit.json', audit)
model = Path(c.__file__).resolve().parent
receipt = dict(schema='phase4am-adapter-provenance-v1', complete=True,
scope='constant sparse overlay installation only; no within-trial plasticity or learning',
adapter_file=str(model / 'adapter.py'), adapter_sha256=c.file_hash(model / 'adapter.py'),
overlay_module_file=str(model / 'overlay.py'), overlay_module_sha256=c.file_hash(model / 'overlay.py'),
sealed_sources={relative: dict(path=str(model.parent / relative), sha256=sha) for relative, sha in c.ADAPTER_PINS.items()},
ast=c._expected_ast(model.parent / 'apl-timing-lab-v1/gpu_timing.py', model / 'adapter.py'),
installation_calls=1, weights_updated_during_run=False, learning=False, apl_delay_steps=18,
original_module_globals_patched=False, delta_constant_for_entire_trial=True,
inherited_source_audit_describes_AM_semantics=False, overlay_audit_sha256=c.file_hash(directory / 'overlay-audit.json'),
inherited_summary_sha256=c.file_hash(directory / 'summary.json'), effective_weights_raw_sha256=summary['effective_weights_raw_sha256'])
write_json(directory / 'adapter-provenance.json', receipt)
def compare(self, left, right, mode='zero', output=None):
with patch.object(c, '_load_case', return_value=self.case), patch.object(c, 'CANDIDATES', 2):
return c.compare_runs(self.case_dir, left, right, output, mode)
def assert_pass(self, report):
self.assertTrue(report['pass_all'], json.dumps({key: report.get(key) for key in ('error', 'failed_checks', 'differences')}))
self.assertFalse(report['learning_achieved'])
self.assertFalse(report['candidate_generated'])
self.assertTrue(report['read_manifest'])
def test_zero_complete_real_parsers(self):
left, right = self.run_files('left', False), self.run_files('right', True)
self.assert_pass(self.compare(left, right))
def test_static25_repeat_and_single_validation(self):
self.overlay_name = 'static25'
self.delta = np.multiply(self.base, np.float32(-.25))
self._overlay_inputs()
left, right = self.run_files('left', True), self.run_files('right', True)
self.assert_pass(self.compare(left, right, 'repeat'))
self.assert_pass(self.compare(left, left, 'self'))
def test_production_rejects_toy_dimensions(self):
with self.assertRaises(ValueError):
c._load_case(self.case_dir, set())
def test_missing_adapter_receipt_fails_despite_complete_summary(self):
left, right = self.run_files('left', False), self.run_files('right', True)
(right / 'adapter-provenance.json').unlink()
self.assertFalse(self.compare(left, right)['pass_all'])
def test_corrupt_adapter_receipt_ast_and_summary_binding_fail(self):
left, right = self.run_files('left', False), self.run_files('right', True)
path = right / 'adapter-provenance.json'
original = json.loads(path.read_text())
for change in ('ast', 'binding', 'complete'):
data = copy.deepcopy(original)
if change == 'ast':
data['ast']['entire_tick_loop_ast_identical'] = False
elif change == 'binding':
data['inherited_summary_sha256'] = '0' * 64
else:
data['complete'] = False
write_json(path, data)
self.assertFalse(self.compare(left, right)['pass_all'], change)
def test_per_neuron_count_corruption_not_hidden_by_equal_total(self):
left, right = self.run_files('left', False), self.run_files('right', True)
for folder in (left, right):
with np.load(folder / 'state.npz') as f:
state = {key: f[key].copy() for key in f.files}
state['counts'][0] -= 1
state['counts'][1] += 1
np.savez(folder / 'state.npz', **state)
self.assertFalse(self.compare(left, right)['pass_all'])
def test_both_equal_wrong_queues_fail_independent_reconstruction(self):
left, right = self.run_files('left', False), self.run_files('right', True)
for folder in (left, right):
path = folder / 'queue.jsonl'
rows = [json.loads(row) for row in path.read_text().splitlines()]
rows[18]['ordered_edge_sha256'] = '0' * 64
path.write_text(''.join(json.dumps(row) + '\n' for row in rows), encoding='utf-8')
report = self.compare(left, right)
self.assertFalse(report['pass_all'])
self.assertIn('left_gpu.full_event_queue_request_accounting', report['failed_checks'])
def test_both_equal_wrong_requests_fail(self):
left, right = self.run_files('left', False), self.run_files('right', True)
for folder in (left, right):
path = folder / 'requests.csv'
path.write_text(path.read_text().replace('2,0,1,0,1', '2,0,1,1,0'), encoding='utf-8')
self.assertFalse(self.compare(left, right)['pass_all'])
def test_both_equal_wrong_ref_hash_fails(self):
left, right = self.run_files('left', False), self.run_files('right', True)
for folder in (left, right):
path = folder / 'tick-state-hashes.jsonl'
rows = [json.loads(row) for row in path.read_text().splitlines()]
rows[1]['ref_sha256'] = '0' * 64
path.write_text(''.join(json.dumps(row) + '\n' for row in rows), encoding='utf-8')
self.assertFalse(self.compare(left, right)['pass_all'])
def test_state_signed_zero_detected(self):
left, right = self.run_files('left', False), self.run_files('right', True)
with np.load(right / 'state.npz') as f:
state = {key: f[key].copy() for key in f.files}
state['g'][0] = -0.
np.savez(right / 'state.npz', **state)
self.assertFalse(self.compare(left, right)['pass_all'])
def test_same_nonfinite_states_fail(self):
left, right = self.run_files('left', False), self.run_files('right', True)
for folder in (left, right):
with np.load(folder / 'state.npz') as f:
state = {key: f[key].copy() for key in f.files}
state['v'][0] = np.inf
np.savez(folder / 'state.npz', **state)
self.assertFalse(self.compare(left, right)['pass_all'])
def test_apl_pending_signed_zero_fails(self):
left, right = self.run_files('left', False), self.run_files('right', True)
path = right / 'apl-pending-tail.float32.npy'
value = np.load(path)
value[0, 0] = np.float32(-0.)
np.save(path, value)
self.assertFalse(self.compare(left, right)['pass_all'])
def test_missing_tick_or_extra_request_fails(self):
left, right = self.run_files('left', False), self.run_files('right', True)
path = right / 'queue.jsonl'
path.write_text('\n'.join(path.read_text().splitlines()[:-1]) + '\n', encoding='utf-8')
self.assertFalse(self.compare(left, right)['pass_all'])
def test_summary_only_whitelisted_performance_may_differ(self):
a = dict(dynamics='same', build={'source': 'same'}, wall_seconds=1)
b = dict(a, wall_seconds=5)
checks, differences = {}, {}
c._summary_pair(a, b, checks, differences)
self.assertTrue(all(checks.values()))
b['build'] = {'source': 'different'}
c._summary_pair(a, b, checks, differences)
self.assertFalse(all(checks.values()))
def test_overlay_bad_units_and_fake_complete_receipt_fail(self):
left, right = self.run_files('left', False), self.run_files('right', True)
path = right / 'overlay-audit.json'
data = json.loads(path.read_text()); data['delta_units'] = 'V'; write_json(path, data)
self.assertFalse(self.compare(left, right)['pass_all'])
def test_source_or_build_mutation_fails(self):
left, right = self.run_files('left', False), self.run_files('right', True)
path = right / 'summary.json'
data = json.loads(path.read_text()); data['build']['cuda_flags'].append('--use_fast_math'); write_json(path, data)
self.assertFalse(self.compare(left, right)['pass_all'])
def test_no_existing_output_overwrite_and_no_input_directory_write(self):
left, right = self.run_files('left', False), self.run_files('right', True)
output = self.root / 'report.json'
self.assert_pass(self.compare(left, right, output=output))
with self.assertRaises(ValueError):
self.compare(left, right, output=output)
with self.assertRaises(ValueError):
self.compare(left, right, output=right / 'report.json')
def test_fake_repeat_self_disallowed(self):
left = self.run_files('left', True)
self.assertFalse(self.compare(left, left, 'repeat')['pass_all'])
def test_static25_cannot_be_zero_reference(self):
self.overlay_name = 'static25'; self.delta = np.multiply(self.base, np.float32(-.25)); self._overlay_inputs()
left, right = self.run_files('left', False), self.run_files('right', True)
self.assertFalse(self.compare(left, right)['pass_all'])
def test_helper_source_pin_and_adapter_ast_contract(self):
model = Path(c.__file__).resolve().parent
self.assertEqual(c.file_hash(model.parent / 'apl-timing-lab-v1/compare_timing.py'), c.HELPER_SHA)
import adapter
_, owner = adapter.derive_ast((model.parent / 'apl-timing-lab-v1/gpu_timing.py').read_bytes())
independent = c._expected_ast(model.parent / 'apl-timing-lab-v1/gpu_timing.py', model / 'adapter.py')
for key, value in owner.items():
self.assertEqual(independent[key], value)
def test_fresh_sha_detects_same_size_write_even_with_identical_stat(self):
path = self.root / 'same-stat.bin'
path.write_bytes(b'first!')
identity = c._fingerprint(path)
with patch.object(c, '_fingerprint', return_value=identity):
before = c.file_hash(path)
path.write_bytes(b'other!')
after = c.file_hash(path)
self.assertEqual(before, hashlib.sha256(b'first!').hexdigest())
self.assertEqual(after, hashlib.sha256(b'other!').hexdigest())
self.assertNotEqual(before, after)
if __name__ == '__main__':
unittest.main()
@@ -0,0 +1,259 @@
"""Synthetic eligibility tests only; never load recorded brain trajectories."""
import ast
import importlib.util
import json
import math
import os
from pathlib import Path
from types import SimpleNamespace
import tempfile
import unittest
from typing import Any
import numpy as np
import eligibility_bridge as bridge
def source_path():
explicit = os.environ.get("PHASE4J_SOURCE")
if explicit:
return Path(explicit)
parent = Path(__file__).resolve().parents[1]
paths = (parent / "models/male-cns-lif/phase4j.py", parent / "mb-physiology-v1/phase4j.py")
for path in paths:
if path.is_file():
return path
raise FileNotFoundError("Set PHASE4J_SOURCE to the SHA-pinned original phase4j.py")
SOURCE = source_path()
KC = np.array([1, 3, 7], np.int32)
def run_trace(rows=(), steps=8, commands=(0, 3, 7), backend="numpy"):
events = np.asarray(rows, np.int32).reshape(-1, 2)
return bridge.trace_from_events(events[:, 0], events[:, 1], KC, steps, commands,
phase4j_source=SOURCE, backend=backend, n_neurons=10)
def update_args():
return dict(trace=np.array([1, .25, 0], np.float32), kc=KC.copy(),
candidate_sources=np.array([1, 1, 3, 7, 3], np.int32),
candidate_compartments=np.array(["y5B'2a", "a1", "y5B'2a", "y5B'2a", "y2a'1"]),
compartment="y5B'2a", delta=np.zeros(5, np.float32),
base_candidate=np.array([.275, .55, .0001, .275, 2.75], np.float32),
d=1., phase4j_source=SOURCE, n_neurons=10)
class FrozenTraceTests(unittest.TestCase):
def test_no_input_positive_zero_and_no_command(self):
result = run_trace(commands=())
self.assertEqual(result.snapshots.shape, (0, 3))
self.assertTrue(bridge.bit_equal(result.final, np.zeros(3, np.float32)))
self.assertTrue(bridge.bit_equal(result.last_command_trace, result.final))
self.assertFalse(result.audit["training_executed"])
self.assertFalse(result.audit["torch_numpy_bitwise_comparison_performed"])
json.dumps(result.audit, allow_nan=False)
def test_simultaneous_spike_is_seen_and_cap_is_one(self):
result = run_trace([(0, 1), (1, 1), (3, 3), (3, 7)])
self.assertEqual(result.snapshots[0, 0], np.float32(1))
self.assertEqual(result.snapshots[1, 1:].tolist(), [1., 1.])
self.assertLessEqual(float(result.final.max()), 1.)
def test_interval_decay_is_each_tick_not_power_jump(self):
result = run_trace([(0, 1)], steps=1001, commands=(0, 1, 1000))
expected = np.float32(1)
decay = np.float32(math.exp(-.1 / 100.))
for _ in range(1000):
expected = np.float32(expected * decay)
self.assertEqual(result.snapshots[-1, 0].view(np.uint32), expected.view(np.uint32))
self.assertEqual(result.snapshots[1, 0].view(np.uint32), decay.view(np.uint32))
def test_us_before_future_cs_has_zero_delta(self):
result = run_trace([(2, 1)], commands=(1,))
args = update_args()
args["trace"] = result.last_command_trace
delta, _ = bridge.apply_eligibility(**args)
self.assertTrue(bridge.bit_equal(delta, args["delta"]))
def test_plus_1000_ms_ratio_strict_below_point01(self):
result = run_trace([(0, 1)], steps=10001, commands=(0, 10000))
args = update_args()
args["base_candidate"][:] = 100 # no saturation in this temporal check
args["trace"] = result.snapshots[0]
zero, _ = bridge.apply_eligibility(**args)
args["trace"] = result.snapshots[1]
late, _ = bridge.apply_eligibility(**args)
self.assertLess(float(np.abs(late).sum() / np.abs(zero).sum()), .01)
self.assertGreater(float(result.snapshots[-1, 0]), 0.)
def test_non_kc_events_do_not_enter_trace(self):
a = run_trace([(0, 1), (3, 3)])
b = run_trace([(0, 0), (0, 1), (2, 9), (3, 3)])
self.assertTrue(bridge.bit_equal(a.snapshots, b.snapshots))
self.assertEqual(b.audit["actual_kc_events"], 2)
def test_inputs_and_outputs_are_not_mutated(self):
step, node, kc = np.array([0, 7], np.int32), np.array([1, 3], np.int32), KC.copy()
before = [a.copy() for a in (step, node, kc)]
result = bridge.trace_from_events(step, node, kc, 8, [7], phase4j_source=SOURCE, n_neurons=10)
for a, b in zip((step, node, kc), before):
self.assertTrue(bridge.bit_equal(a, b))
for a in (result.final, result.snapshots, result.command_steps, result.last_command_trace):
self.assertFalse(a.flags.writeable)
def test_bad_event_and_command_schema_is_rejected(self):
for rows in ([(0, 1), (0, 1)], [(1, 1), (0, 1)], [(-1, 1)], [(8, 1)], [(0, 10)]):
with self.subTest(rows=rows), self.assertRaises(ValueError):
run_trace(rows)
for commands in ((1, 1), (3, 1), (-1,), (8,), (.5,), (True,), np.empty((0, 2), np.int32)):
with self.subTest(commands=commands), self.assertRaises(ValueError):
run_trace(commands=commands)
with self.assertRaises(ValueError):
bridge.trace_from_events(np.array([], np.int64), np.array([], np.int32), KC, 8, [], phase4j_source=SOURCE)
def test_bad_kc_and_backend_are_rejected(self):
for kc in (np.array([3, 1], np.int32), np.array([1, 1], np.int32), np.array([], np.int32)):
with self.assertRaises(ValueError):
bridge.trace_from_events(np.array([], np.int32), np.array([], np.int32), kc, 1, [], phase4j_source=SOURCE)
with self.assertRaises(ValueError):
run_trace(backend="auto")
@unittest.skipUnless(importlib.util.find_spec("torch") is not None, "Torch absent: CPU bitwise compatibility NOT established locally")
def test_torch_original_expression_bitwise_against_numpy(self):
rng = np.random.default_rng(719)
mask = rng.random((1001, 10)) < .07
tick, node = np.nonzero(mask)
rows = np.stack((tick, node), axis=1).tolist()
numpy_result = run_trace(rows, steps=1001, commands=(0, 1, 7, 999, 1000))
torch_result = run_trace(rows, steps=1001, commands=(0, 1, 7, 999, 1000), backend="torch")
self.assertTrue(bridge.bit_equal(numpy_result.snapshots, torch_result.snapshots))
self.assertTrue(bridge.bit_equal(numpy_result.final, torch_result.final))
empty_np = run_trace([(0, 1)], steps=10001, commands=(0, 10000))
empty_torch = run_trace([(0, 1)], steps=10001, commands=(0, 10000), backend="torch")
self.assertTrue(bridge.bit_equal(empty_np.snapshots, empty_torch.snapshots))
class FrozenUpdateTests(unittest.TestCase):
def test_actual_source_sha_and_ast_only_extraction(self):
_, report = bridge.apply_eligibility(**update_args())
self.assertEqual(report["source_sha256"], bridge.PHASE4J_SHA256)
self.assertFalse(report["actual_dan_activity_used_to_gate"])
self.assertFalse(report["learning_pass_claimed"])
json.dumps(report, allow_nan=False)
def test_source_drift_is_rejected_before_execution(self):
with tempfile.TemporaryDirectory() as directory:
path = Path(directory) / "phase4j.py"
path.write_bytes(SOURCE.read_bytes() + b"\nraise RuntimeError('must not execute')\n")
args = update_args()
args["phase4j_source"] = path
with self.assertRaisesRegex(ValueError, "SHA256 mismatch"):
bridge.apply_eligibility(**args)
def test_bitwise_against_independently_extracted_original_apply_v2(self):
tree = ast.parse(SOURCE.read_text(encoding="utf-8"))
function = next(x for x in tree.body if isinstance(x, ast.FunctionDef) and x.name == "apply_v2")
namespace = {"np": np, "Validator": object, "Any": Any}
exec(compile(ast.Module(body=[function], type_ignores=[]), "independent-old-apply-v2", "exec"), namespace)
class Column:
def __init__(self, values):
self.values = values
def to_numpy(self, dtype=None):
return np.array(self.values, dtype=dtype)
def astype(self, dtype):
return Column(np.asarray(self.values).astype(dtype))
args = update_args()
validator = SimpleNamespace(n=10, kc=KC, base_candidate=args["base_candidate"],
cand={"source_neuron_idx": Column(args["candidate_sources"]),
"target_compartment_verbatim": Column(args["candidate_compartments"])})
cfg = {"eligibility_v2": {"eta_effective_mv": .00275, "max_fractional_depression": .25}}
for _ in range(50):
actual, report = bridge.apply_eligibility(**args)
expected, old_report = namespace["apply_v2"](validator, args["trace"], args["compartment"], 1., args["delta"], cfg)
self.assertTrue(bridge.bit_equal(actual, expected))
self.assertEqual(report["original_report"], old_report)
args["delta"] = actual
def test_zero_d_and_frozen_preserve_existing_overlay(self):
args = update_args()
args["delta"][:] = -.25 * args["base_candidate"]
for d, frozen in ((0., False), (1., True), (0., True)):
args.update(d=d, frozen=frozen)
result, report = bridge.apply_eligibility(**args)
self.assertTrue(bridge.bit_equal(result, args["delta"]))
self.assertEqual(report["actual_changed_edges"], 0)
def test_off_compartment_and_inactive_source_exact_unchanged(self):
args = update_args()
args["delta"][1] = -.01
result, _ = bridge.apply_eligibility(**args)
self.assertTrue(bridge.bit_equal(result[[1, 3, 4]], args["delta"][[1, 3, 4]]))
self.assertEqual(result[0], np.float32(-.00275))
def test_original_floor_clamps_and_does_not_reverse_sign(self):
args = update_args()
result, report = bridge.apply_eligibility(**args)
self.assertEqual(result[2], (-.25 * args["base_candidate"])[2])
args["delta"] = result
again, _ = bridge.apply_eligibility(**args)
self.assertEqual(again[2].view(np.uint32), result[2].view(np.uint32))
self.assertTrue(np.all(again <= 0))
# Original updated_edges counts attempted updates, including saturation.
self.assertEqual(report["original_report"]["updated_edges"], 2)
def test_all_original_compartments_are_literal_not_inferred(self):
args = update_args()
args["candidate_sources"] = np.full(4, 1, np.int32)
args["candidate_compartments"] = np.array(bridge.COMPARTMENTS)
args["delta"] = np.zeros(4, np.float32)
args["base_candidate"] = np.ones(4, np.float32)
for comp in bridge.COMPARTMENTS:
args["compartment"] = comp
result, _ = bridge.apply_eligibility(**args)
self.assertEqual(int(np.count_nonzero(result)), 1)
self.assertNotEqual(result[list(bridge.COMPARTMENTS).index(comp)], 0)
def test_update_does_not_mutate_inputs_and_returns_readonly(self):
args = update_args()
before = {k: v.copy() for k, v in args.items() if isinstance(v, np.ndarray)}
result, _ = bridge.apply_eligibility(**args)
for k, value in before.items():
self.assertTrue(bridge.bit_equal(args[k], value))
self.assertFalse(result.flags.writeable)
def test_invalid_units_dtypes_values_and_compartment_fail_closed(self):
bad = [("trace", np.array([1, .25, 0], np.float64)),
("trace", np.array([1, np.nan, 0], np.float32)),
("trace", np.array([1.1, 0, 0], np.float32)),
("candidate_sources", np.array([1, 1, 3, 8, 3], np.int32)),
("compartment", "PAM15"), ("d", -.1), ("d", .5), ("d", float("nan")),
("d", True), ("frozen", 1),
("base_candidate", np.zeros(5, np.float32)),
("delta", np.ones(5, np.float32)),
("delta", np.full(5, -.5, np.float32)),
("delta", np.full(5, -0., np.float32))]
for key, value in bad:
with self.subTest(key=key, value=value):
args = update_args()
args[key] = value
with self.assertRaises(ValueError):
bridge.apply_eligibility(**args)
def test_empty_candidate_subset_is_safe_but_not_claimed_full_mask(self):
args = update_args()
for key in ("candidate_sources", "candidate_compartments", "delta", "base_candidate"):
args[key] = args[key][:0]
result, report = bridge.apply_eligibility(**args)
self.assertEqual(result.shape, (0,))
self.assertFalse(report["complete_mask_identity_verified_by_this_function"])
if __name__ == "__main__":
unittest.main()
@@ -0,0 +1,275 @@
"""Pure synthetic inputs/AST tests; no Torch import, GPU, or brain execution."""
import ast
import hashlib
import json
from pathlib import Path
import tempfile
import types
import unittest
import time
import numpy as np
import adapter
import overlay
HERE = Path(__file__).absolute().parent
AJ = HERE.parent / 'apl-timing-lab-v1/gpu_timing.py'
class ArrayTests(unittest.TestCase):
def setUp(self):
self.ids = np.array([2, 7, 15], np.int64)
self.base32 = np.array([.275, 1.1, 2.75], np.float32)
def plan(self, delta=None):
if delta is None:
delta = np.zeros(3, np.float32)
return overlay.validate_arrays(self.ids, delta, self.ids, self.base32)
def test_zero_preserves_unrelated_signed_zero_and_original_bytes(self):
ids = np.array([0, 2, 7, 15, 17], np.int64)
base = np.array([-0., .000275, .0011, .00275, -1.], np.float64)
original = base.tobytes()
result, mapping = overlay.materialize_numpy(base, ids, np.zeros(5, bool), self.plan())
self.assertEqual(result.tobytes(), original)
self.assertEqual(base.tobytes(), original)
self.assertEqual(mapping['installed_nonzero_count'], 0)
self.assertEqual(len(mapping['rows']), 0)
self.assertFalse(np.shares_memory(result, base))
def test_negative_zero_delta_does_not_write(self):
plan = self.plan(np.full(3, -0., np.float32))
result, mapping = overlay.materialize_numpy(self.base32.astype(np.float64) * .001,
self.ids, np.zeros(3, bool), plan)
self.assertEqual(len(mapping['rows']), 0)
self.assertTrue(np.signbit(plan['plastic_delta_mv']).all())
def test_original_float32_floor_then_widen_and_multiply(self):
delta = np.float32(-.25) * self.base32
plan = self.plan(delta)
base_si = np.array([.000275, .0011, .00275], np.float64)
result, mapping = overlay.materialize_numpy(base_si, self.ids, np.zeros(3, bool), plan)
reference = np.add(base_si, np.multiply(delta.astype(np.float64), np.float64(.001)))
self.assertTrue(overlay.bit_equal(result, reference))
self.assertTrue(np.any(result.view(np.uint64) != (base_si * .75).view(np.uint64)))
self.assertEqual(mapping['installed_nonzero_count'], 3)
def test_global_id_mapping_fixture_intersection_and_missing_nonzero_reject(self):
plan = self.plan(np.array([0., -.1, 0.], np.float32))
ids = np.array([1, 7, 20], np.int64)
result, mapping = overlay.materialize_numpy(np.array([1., .002, -0.], np.float64), ids,
np.array([True, False, False]), plan)
np.testing.assert_array_equal(mapping['rows'], np.array([1], np.int64))
self.assertEqual(mapping['missing_candidate_count'], 2)
self.assertEqual(result[0].view(np.uint64), 0)
self.assertTrue(np.signbit(result[2]))
with self.assertRaises(ValueError):
overlay.materialize_numpy(np.array([1.], np.float64), np.array([1], np.int64), np.zeros(1, bool), plan)
def test_apl_overlap_sign_nonfinite_bad_mapping_fail_closed(self):
base = self.base32.astype(np.float64) * .001
for ids, values, apl in ((self.ids, base, np.array([1, 0, 0], bool)),
(self.ids[::-1], base, np.zeros(3, bool)),
(self.ids, -base, np.zeros(3, bool)),
(self.ids, np.array([np.nan, 1., 2.]), np.zeros(3, bool))):
with self.subTest(ids=ids), self.assertRaises(ValueError):
overlay.map_installation(values, ids, apl, self.plan())
def test_validation_bad_dtype_shape_sign_finite_bound_and_mask(self):
bad_deltas = [np.zeros(3, np.float64), np.zeros((3, 1), np.float32), np.zeros(2, np.float32),
np.array([.1, 0, 0], np.float32), np.array([np.nan, 0, 0], np.float32),
np.array([-np.inf, 0, 0], np.float32), np.array([-1., 0, 0], np.float32)]
for delta in bad_deltas:
with self.subTest(delta=delta), self.assertRaises(ValueError):
self.plan(delta)
for ids in (self.ids.astype(np.int32), self.ids[::-1], np.array([2, 2, 15], np.int64),
np.array([-1, 7, 15], np.int64), np.array([2, 7, overlay.EDGE_COUNT], np.int64)):
with self.subTest(ids=ids), self.assertRaises(ValueError):
overlay.validate_arrays(ids, np.zeros(3, np.float32), self.ids, self.base32)
with self.assertRaises(ValueError):
overlay.validate_arrays(self.ids, np.array([-.01, 0, 0], np.float32), self.ids)
def test_positive_original_base_and_bound_bits_readonly(self):
for base in (np.zeros(3, np.float32), -self.base32, self.base32.astype(np.float64),
np.array([np.inf, 1., 1.], np.float32)):
with self.assertRaises(ValueError):
overlay.validate_arrays(self.ids, np.zeros(3, np.float32), self.ids, base)
self.ids.flags.writeable = False
self.base32.flags.writeable = False
plan = self.plan()
self.assertFalse(plan['edge_id'].flags.writeable)
self.assertFalse(plan['plastic_delta_mv'].flags.writeable)
self.assertFalse(np.shares_memory(plan['base_candidate_mv'], self.base32))
lower = np.float32(-.25) * self.base32
too_low = lower.copy(); too_low[0] = np.nextafter(lower[0], np.float32(-np.inf))
with self.assertRaises(ValueError):
self.plan(too_low)
def test_chunked_expected_hash_matches_materialization(self):
ids = np.array([0, 2, 7, 15, 20], np.int64)
base = np.array([-0., .001, .002, .003, -1.], np.float64)
apl = np.array([False, False, False, False, True])
plan = self.plan(np.array([-.01, 0, -.2], np.float32))
result, mapping = overlay.materialize_numpy(base, ids, apl, plan)
for chunk in (1, 2, 3, 100):
self.assertEqual(overlay.expected_hashes(base, apl, mapping, chunk),
(overlay.raw_hash(base), overlay.raw_hash(result)))
class FileTests(unittest.TestCase):
def setUp(self):
self.temp = tempfile.TemporaryDirectory()
self.addCleanup(self.temp.cleanup)
self.root = Path(self.temp.name)
self.ids = np.arange(overlay.CANDIDATE_COUNT, dtype=np.int64)
self.base = np.full(overlay.CANDIDATE_COUNT, .275, np.float32)
np.save(self.root / 'mask.npy', self.ids)
np.save(self.root / 'base.npy', self.base)
def files(self, name='zero', embedded=False, base=True):
delta = np.zeros_like(self.base) if name == 'zero' else np.float32(-.25) * self.base
values = dict(edge_id=self.ids, plastic_delta_mv=delta)
if embedded:
values['base_candidate_mv'] = self.base
np.savez(self.root / 'overlay.npz', **values)
manifest = dict(schema=overlay.SCHEMA, overlay_name=name,
overlay_sha256=overlay.file_hash(self.root / 'overlay.npz'),
mask_path=str(self.root / 'mask.npy'), mask_sha256=overlay.file_hash(self.root / 'mask.npy'),
base_candidate_path=str(self.root / 'base.npy') if base else None,
base_candidate_sha256=overlay.file_hash(self.root / 'base.npy') if base else None,
aj_model_dir=str(self.root))
(self.root / 'manifest.json').write_text(json.dumps(manifest), encoding='utf-8')
return self.root / 'overlay.npz', self.root / 'manifest.json'
def test_full_mask_zero_optional_base_and_static_floor(self):
for name, embedded, base in (('zero', False, False), ('zero', True, True), ('static25', True, True)):
plan = overlay.load_overlay(*self.files(name, embedded, base))
self.assertEqual(len(plan['edge_id']), overlay.CANDIDATE_COUNT)
overlay.verify_inputs(plan)
def test_hash_tamper_and_wrong_count_reject(self):
paths = self.files()
(self.root / 'base.npy').write_bytes(b'not the anchored source')
with self.assertRaises(ValueError):
overlay.load_overlay(*paths)
np.save(self.root / 'base.npy', self.base)
np.save(self.root / 'mask.npy', self.ids[:-1])
paths = self.files()
with self.assertRaises(ValueError):
overlay.load_overlay(*paths)
def test_static25_needs_original_base_and_postload_tampering_is_detected(self):
with self.assertRaises(ValueError):
overlay.load_overlay(*self.files('static25', base=False))
paths = self.files()
plan = overlay.load_overlay(*paths)
(self.root / 'manifest.json').write_text('{}', encoding='utf-8')
with self.assertRaises(ValueError):
overlay.verify_inputs(plan)
class AstTests(unittest.TestCase):
def source(self):
if not AJ.is_file():
self.skipTest('Pinned AJ static source is not installed at its declared sibling path')
return AJ.read_bytes()
def test_exact_whole_tick_loop_and_only_one_preloop_insertion(self):
source = self.source()
transformed, audit = adapter.derive_ast(source)
original = next(node for node in ast.parse(source).body if isinstance(node, ast.FunctionDef) and node.name == 'run_gpu')
getloop = lambda function: next(node for node in ast.walk(function) if isinstance(node, ast.For) and
isinstance(node.target, ast.Name) and node.target.id == 'tick')
self.assertEqual(ast.dump(getloop(original), include_attributes=False), ast.dump(getloop(transformed), include_attributes=False))
hooks = [node for node in ast.walk(transformed) if isinstance(node, ast.Call) and
isinstance(node.func, ast.Name) and node.func.id == adapter.HOOK_NAME]
self.assertEqual(len(hooks), 1)
self.assertFalse(any(node is hooks[0] for node in ast.walk(getloop(transformed))))
self.assertTrue(audit['entire_tick_loop_ast_identical'])
self.assertEqual(audit['inserted_ast_statements'], 1)
def test_mutated_source_fails_even_if_loop_looks_plausible(self):
with self.assertRaises(ValueError):
adapter.derive_ast(self.source() + b'\n# unregistered change\n')
def test_compilation_new_namespace_no_fake_file_no_old_global_patch(self):
self.source()
# Compile only; the function is never called, so no Torch or GPU needed.
sealed = types.ModuleType('synthetic_sealed_namespace')
sealed.__file__ = str(AJ)
sealed.marker = object()
before = dict(sealed.__dict__)
hook = lambda *args: None
function, audit = adapter.compile_derived(sealed, hook)
self.assertEqual(sealed.__dict__, before)
self.assertNotIn(adapter.HOOK_NAME, sealed.__dict__)
self.assertIs(function.__globals__[adapter.HOOK_NAME], hook)
self.assertIs(function.__globals__['marker'], sealed.marker)
self.assertEqual(function.__globals__['__file__'], str(Path(adapter.__file__).absolute()))
self.assertNotEqual(function.__globals__['__file__'], sealed.__file__)
self.assertFalse(audit['fake_original_file_used'])
self.assertFalse(audit['original_module_globals_patched'])
def test_real_source_dependency_hashes_without_importing_gpu(self):
self.source()
proof = adapter.verify_sources(AJ.parent)
self.assertEqual({key: row['sha256'] for key, row in proof.items()}, adapter.PINS)
self.assertEqual(hashlib.sha256(AJ.read_bytes()).hexdigest(), adapter.AJ_SHA256)
def test_derived_hook_runs_after_apl_zero_and_before_any_state_tick(self):
self.source()
class StopBeforeBrain(BaseException):
pass
class Tensor:
def __init__(self, array):
self.array = np.array(array, copy=True)
def to(self, *, device, dtype):
return Tensor(self.array.astype(dtype))
def contiguous(self):
return self
def clone(self):
return Tensor(self.array)
def __setitem__(self, item, value):
self.array[item.array if isinstance(item, Tensor) else item] = value
torch_stub = types.SimpleNamespace(from_numpy=Tensor, float64=np.float64, int64=np.int64,
int32=np.int32, bool=bool, cuda=types.SimpleNamespace(is_available=lambda: True,
device_count=lambda: 1, get_device_name=lambda: 'synthetic RTX4090', reset_peak_memory_stats=lambda _: None))
graph = {'weights': np.array([.1, -.2], np.float64), 'nodes': np.array([3, 9], np.int32),
'edge_id': np.array([4, 12], np.int64), 'ptr': np.array([0, 1, 2], np.int64),
'dst': np.array([1, 0], np.int32), 'src': np.array([0, 1], np.int32)}
apl = types.SimpleNamespace(device='no-device', apl_globals=np.array([9], np.int32), metadata={})
sealed = types.ModuleType('synthetic_before_loop')
sealed.__file__ = str(AJ)
sealed.__dict__.update(Path=Path, time=time, np=np, torch=torch_stub, require=overlay.require,
source_audit=lambda _: {'scope': 'synthetic inherited AJ source'}, write_json=lambda *_: None,
load_inputs=lambda _: ({'apl_bundle_dir': 'unused', 'dt_ms': .1, 'steps': 2}, graph, {},
np.empty(0, np.int32), np.empty(0, np.int32), np.empty(0, np.int32), {}),
sealed_backend=lambda: types.SimpleNamespace(build_extension=lambda _: (None, {})),
sealed_apl=lambda: types.SimpleNamespace(LegacyAPL=lambda *_: apl))
observed = []
def hook(weights, actual_graph, mask, upload, out_dir, provenance):
self.assertTrue(overlay.bit_equal(weights.array, np.array([.1, 0.], np.float64)))
self.assertTrue(overlay.bit_equal(graph['weights'], np.array([.1, -.2], np.float64)))
np.testing.assert_array_equal(mask, [False, True])
observed.append(provenance)
raise StopBeforeBrain()
derived, _ = adapter.compile_derived(sealed, hook)
with tempfile.TemporaryDirectory() as directory:
with self.assertRaises(StopBeforeBrain):
derived(Path(directory), Path(directory) / 'new-output', Path(directory) / 'new-build')
self.assertEqual(len(observed), 1)
if __name__ == '__main__':
unittest.main()
@@ -0,0 +1,55 @@
"""Small independent checks of provenance/summary mechanics."""
import ast
from pathlib import Path
import tempfile
import unittest
import numpy as np
from prepare import old_base_candidate
from summarize import first_ticks, metrics
from run_suite import output_inventory, verify_completed
from context import save
class WorkflowTests(unittest.TestCase):
def test_old_expression_float32(self):
candidates = [Path(__file__).resolve().parent.parent / 'phase4c.py',
Path(__file__).resolve().parent.parent / 'models/male-cns-lif/phase4c.py']
source = next(p for p in candidates if p.is_file())
x = np.array([1, 2, 9, 19, 1234, 1048577], np.int64)
value, sha = old_base_candidate(x, source)
expected = x.astype(np.float32) * np.int8(1) * float(.275)
self.assertEqual(value.tobytes(), expected.tobytes())
self.assertEqual(len(sha), 64)
def test_first_tick_and_missing(self):
state = dict(step=np.array([0, 2, 3, 4], np.int32), neuron_idx=np.array([1, 2, 1, 2], np.int32))
np.testing.assert_array_equal(first_ticks(state, 4), [-1, 0, 2, -1])
def test_same_counts_event_change_not_hidden(self):
a = dict(step=np.array([0], np.int32), neuron_idx=np.array([1], np.int32),
counts=np.array([0, 1, 0], np.int32), v=np.zeros(3), g=np.zeros(3))
b = {k: v.copy() for k, v in a.items()}; b['step'][0] = 2
m = metrics(a, b, np.array([1], np.int32))
self.assertTrue(m['event_sequence_changed']); self.assertEqual(m['count_changed_cells'], 0)
self.assertEqual(m['first_spike_changed_cells'], 1); self.assertEqual(m['first_event_divergence_ms'], 0)
def test_extra_or_changed_output_rejected(self):
with tempfile.TemporaryDirectory() as temp:
folder = Path(temp)
save(folder / 'comparison.json', {'pass_all': True})
save(folder / 'summary.json', {'complete': True})
save(folder / 'output-hashes.json', output_inventory(folder))
verify_completed(folder)
save(folder / 'unexpected.json', {})
with self.assertRaises(AssertionError):
verify_completed(folder)
def test_exclusive_json(self):
with tempfile.TemporaryDirectory() as temp:
path = Path(temp) / 'value.json'; save(path, {})
with self.assertRaises(FileExistsError):
save(path, {})
if __name__ == '__main__':
unittest.main()
@@ -0,0 +1,220 @@
"""Synthetic AM workflow identity/dispatch tests; no old evidence or network."""
import builtins
import copy
import io
import json
import os
from pathlib import Path
import sys
import tempfile
from types import ModuleType
import unittest
from unittest.mock import Mock, patch
import run_suite as runner
class WorkflowIdentityTests(unittest.TestCase):
def setUp(self):
self.temp = tempfile.TemporaryDirectory()
self.addCleanup(self.temp.cleanup)
self.root = Path(self.temp.name).resolve()
self.exp = self.root / "experiments/new-am"
self.ak = self.root / "experiments/fake-ak"
self.patches = patch.multiple(runner, ROOT=self.root, EXP=self.exp, AK=self.ak)
self.patches.start()
self.addCleanup(self.patches.stop)
def fixture(self, stage="zero", repeat=0, name="synthetic-odor"):
row = dict(name=name, repeat=repeat, cohort="seed_validation")
case = self.ak / "cases" / row["cohort"] / name
case.mkdir(parents=True, exist_ok=True)
(case / "spec.json").write_bytes(b'{"synthetic":true}\n')
# This is a hash-only mock input, never parsed as scientific NPZ data.
(case / "requests.npz").write_bytes(b"synthetic-request-bytes")
overlays = self.exp / "overlays"
overlays.mkdir(parents=True, exist_ok=True)
(overlays / (stage + ".npz")).write_bytes((stage + "-synthetic-overlay").encode())
(overlays / (stage + ".json")).write_bytes((stage + "-synthetic-manifest").encode())
folder = self.exp / "gpu" / stage / (name + "-r" + str(repeat))
folder.mkdir(parents=True, exist_ok=False)
summary = dict(case=name, complete=True, pass_all=True, input_sha256={
key: runner.digest(case / key) for key in ("spec.json", "requests.npz")})
overlay = dict(complete=True, overlay_name=stage, input={
"overlay_sha256": runner.digest(overlays / (stage + ".npz")),
"manifest_sha256": runner.digest(overlays / (stage + ".json"))})
if stage == "zero":
mode = "zero"
left = self.ak / "gpu" / row["cohort"] / (name + "-r" + str(repeat))
elif repeat == 1:
mode = "repeat"
left = self.exp / "gpu" / stage / (name + "-r0")
else:
mode, left = "self", folder
report = dict(pass_all=True, overlay_name=stage, case_dir=str(case),
right=str(folder), left=str(left), mode=mode)
for key, value in (("summary.json", summary), ("overlay-audit.json", overlay),
("comparison.json", report)):
runner.save(folder / key, value)
runner.save(folder / "output-hashes.json", runner.output_inventory(folder))
return row, case, folder, report
@staticmethod
def replace_json(path, value):
# Mutations are deliberate corruptions of NEW temporary test fixtures.
path.write_text(json.dumps(value), encoding="utf-8")
def corrupt(self, folder, filename, field, value):
original = runner.read(folder / filename)
changed = copy.deepcopy(original)
target = changed
for key in field[:-1]:
target = target[key]
target[field[-1]] = value
self.replace_json(folder / filename, changed)
return original
def test_three_legitimate_identities_and_zero_repeat(self):
for stage, repeat in (("zero", 0), ("zero", 1), ("static25", 0), ("static25", 1)):
with self.subTest(stage=stage, repeat=repeat):
row, _, folder, _ = self.fixture(stage, repeat)
runner.verify_identity(folder, stage, row)
runner.verify_completed(folder, stage, row)
def test_wrong_case_and_cohort_fail_even_with_valid_hash_inventory(self):
row, _, folder, _ = self.fixture()
for altered in (dict(row, name="other-odor"), dict(row, cohort="novel_to_aj")):
with self.subTest(altered=altered), self.assertRaises((AssertionError, FileNotFoundError)):
runner.verify_identity(folder, "zero", altered)
self.corrupt(folder, "summary.json", ("case",), "other-odor")
self.replace_json(folder / "output-hashes.json", runner.output_inventory(folder))
with self.assertRaises(AssertionError):
runner.verify_completed(folder, "zero", row)
def test_wrong_stage_and_repeat_path_are_rejected(self):
row, _, folder, _ = self.fixture()
for stage, wrong_row in (("static25", row), ("zero", dict(row, repeat=1)),
("unknown", row), ("zero", dict(row, repeat=2))):
with self.subTest(stage=stage, row=wrong_row), self.assertRaises(AssertionError):
runner.verify_identity(folder, stage, wrong_row)
def test_overlay_stage_identity_and_two_input_hashes_are_required(self):
row, _, folder, _ = self.fixture("static25")
for field, value in ((("overlay_name",), "zero"), (("complete",), False),
(("input", "overlay_sha256"), "0" * 64),
(("input", "manifest_sha256"), "0" * 64)):
original = self.corrupt(folder, "overlay-audit.json", field, value)
with self.subTest(field=field), self.assertRaises(AssertionError):
runner.verify_identity(folder, "static25", row)
self.replace_json(folder / "overlay-audit.json", original)
def test_summary_completion_and_actual_case_hashes_are_required(self):
row, _, folder, _ = self.fixture()
for field, value in ((("complete",), False), (("pass_all",), False),
(("input_sha256", "spec.json"), "0" * 64),
(("input_sha256", "requests.npz"), "0" * 64)):
original = self.corrupt(folder, "summary.json", field, value)
with self.subTest(field=field), self.assertRaises(AssertionError):
runner.verify_identity(folder, "zero", row)
self.replace_json(folder / "summary.json", original)
def test_comparison_case_paths_mode_and_stage_are_required(self):
for stage, repeat in (("zero", 0), ("static25", 0), ("static25", 1)):
row, _, folder, _ = self.fixture(stage, repeat)
for field, value in ((("case_dir",), str(self.root / "wrong-case")),
(("right",), str(self.root / "wrong-output")),
(("left",), str(self.root / "wrong-reference")),
(("overlay_name",), "not-the-stage"),
(("mode",), "invalid-mode"), (("pass_all",), False)):
original = self.corrupt(folder, "comparison.json", field, value)
with self.subTest(stage=stage, repeat=repeat, field=field), self.assertRaises(AssertionError):
runner.verify_identity(folder, stage, row)
self.replace_json(folder / "comparison.json", original)
def test_self_report_cannot_substitute_for_repeat(self):
row, _, folder, _ = self.fixture("static25", 1)
report = runner.read(folder / "comparison.json")
report.update(mode="self", left=str(folder))
self.replace_json(folder / "comparison.json", report)
self.replace_json(folder / "output-hashes.json", runner.output_inventory(folder))
with self.assertRaises(AssertionError):
runner.verify_completed(folder, "static25", row)
def test_recompute_must_match_full_stored_report(self):
row, _, folder, report = self.fixture("static25", 1)
with patch.object(runner, "compare_expected", return_value=copy.deepcopy(report)) as compare:
runner.verify_completed(folder, "static25", row, recompute=True)
compare.assert_called_once_with("static25", row, folder)
for result in (dict(report, pass_all=False), dict(report, newly_detected_difference=True)):
with patch.object(runner, "compare_expected", return_value=result), self.assertRaises(AssertionError):
runner.verify_completed(folder, "static25", row, recompute=True)
def test_partial_folder_is_preserved_without_attempted_comparison(self):
row, _, folder, _ = self.fixture()
(folder / "output-hashes.json").unlink() # Deliberately incomplete NEW fixture.
before = {p.name: p.read_bytes() for p in folder.iterdir()}
with patch.object(runner, "compare_expected") as compare, self.assertRaises(FileNotFoundError):
runner.verify_completed(folder, "zero", row, recompute=True)
compare.assert_not_called()
self.assertEqual(before, {p.name: p.read_bytes() for p in folder.iterdir()})
def test_compare_expected_zero_dispatches_to_corresponding_ak_repeat(self):
self.assert_dispatch("zero", 0)
self.assert_dispatch("zero", 1)
def test_compare_expected_static_repeat_dispatches_to_r0(self):
self.assert_dispatch("static25", 1)
def test_compare_expected_static_primary_uses_self_validation(self):
self.assert_dispatch("static25", 0)
def assert_dispatch(self, stage, repeat):
fake = ModuleType("comparison")
fake.compare_runs = Mock(return_value={"marker": "pair"})
fake.validate_run = Mock(return_value={"marker": "single"})
row = dict(name="synthetic", cohort="novel_to_aj", repeat=repeat)
folder = self.exp / "gpu" / stage / (row["name"] + "-r" + str(repeat))
case = self.ak / "cases" / row["cohort"] / row["name"]
with patch.dict(sys.modules, {"comparison": fake}):
result = runner.compare_expected(stage, row, folder)
if stage == "zero":
reference = self.ak / "gpu" / row["cohort"] / (row["name"] + "-r" + str(repeat))
fake.compare_runs.assert_called_once_with(case, reference, folder, mode="zero")
fake.validate_run.assert_not_called()
self.assertEqual(result, {"marker": "pair"})
elif repeat:
reference = self.exp / "gpu" / stage / (row["name"] + "-r0")
fake.compare_runs.assert_called_once_with(case, reference, folder, mode="repeat")
fake.validate_run.assert_not_called()
self.assertEqual(result, {"marker": "pair"})
else:
fake.validate_run.assert_called_once_with(case, folder)
fake.compare_runs.assert_not_called()
self.assertEqual(result, {"marker": "single"})
# No output_path was passed: the comparator cannot write into evidence.
def test_preflight_sets_cuda_environment_without_torch_or_network(self):
imported = builtins.__import__
def guarded_import(name, *args, **kwargs):
if name == "torch" or name.startswith("torch."):
self.fail("preflight imported Torch")
return imported(name, *args, **kwargs)
def response(url, timeout):
self.assertEqual(os.environ["CUDA_VISIBLE_DEVICES"], runner.CFG["gpu_uuid"])
self.assertEqual(os.environ["CUDA_HOME"], "/usr/local/cuda")
self.assertEqual(os.environ["TORCH_CUDA_ARCH_LIST"], "8.9")
self.assertEqual(timeout, 5)
return io.BytesIO(b'{"queue_running":[],"queue_pending":[]}')
with patch.dict(os.environ, {"PATH": "synthetic-original-path"}), \
patch("builtins.__import__", side_effect=guarded_import), \
patch.object(runner.urllib.request, "urlopen", side_effect=response) as urlopen:
runner.preflight()
self.assertEqual(urlopen.call_count, 3)
self.assertTrue(os.environ["PATH"].endswith("synthetic-original-path"))
if __name__ == "__main__":
unittest.main()
@@ -0,0 +1,47 @@
"""Old deterministic-v2 references, into new output paths only."""
import sys
import time
import numpy as np
import pandas as pd
import yaml
from context import ROOT, EXP, check, save, bit_equal
from run_suite import preflight
def main():
check(full=True)
assert not (EXP / 'regression/frozen-five.json').exists()
preflight()
runtime_path = ROOT / 'models/male-cns-lif/deterministic-runtime-v2'
pc = yaml.safe_load((runtime_path / 'phase4p.yaml').read_text())
sys.path.insert(0, str(ROOT / 'models/male-cns-lif'))
sys.path.insert(0, str(runtime_path))
import torch
import phase4p
assert torch.cuda.mem_get_info()[0] > 2 * 1024**3
torch.cuda.reset_peak_memory_stats()
started = time.perf_counter()
runtime = phase4p.CanonicalRuntime(pc, runtime_path, EXP)
rows = []
for spec in pc['reference_trials']:
preflight()
reference_dir = ROOT / 'experiments/phase4p-deterministic-runtime/phase4c-v2/reference' / spec['name']
events = pd.read_parquet(reference_dir / 'spike-events.parquet')
reference = dict(step=events.step.to_numpy(), neuron_idx=events.neuron_idx.to_numpy(),
counts=np.load(reference_dir / 'per-neuron-spike-counts.int32.npy'),
v=np.load(reference_dir / 'final-voltage.float32.npy'), g=np.load(reference_dir / 'final-g.float32.npy'))
result = runtime.run(np.flatnonzero(runtime.pops[spec['population']]), spec['rate_hz'], spec['seed'], spec['duration_ms'])
row = dict(trial=spec['name'], exact={key: bool(bit_equal(value, result[key])) for key, value in reference.items()},
dtype_shape={key: dict(reference_dtype=str(value.dtype), actual_dtype=str(result[key].dtype),
reference_shape=list(value.shape), actual_shape=list(result[key].shape)) for key, value in reference.items()},
wall_seconds=result['metrics']['wall_seconds'])
rows.append(row); print(row, flush=True)
passed = len(rows) == 5 and all(all(row['exact'].values()) for row in rows)
save(EXP / 'regression/frozen-five.json', dict(pass_all=passed, trials=rows,
wall_seconds=time.perf_counter() - started, peak_allocated_vram=int(torch.cuda.max_memory_allocated()),
scope='Old frozen deterministic-v2 references; not a claim D18 equals old runtime'))
assert passed
if __name__ == '__main__':
main()