Seal Phase 4AK frozen D18 independent validation
This commit is contained in:
@@ -0,0 +1,234 @@
|
||||
"""Exclusive small-evidence publication after both Phase 4AK seals verify.
|
||||
|
||||
Publication verifies and copies bytes. It never runs a brain, re-evaluates a
|
||||
scientific gate, converts FAIL/INCOMPLETE into PASS, or changes frozen sources.
|
||||
The source-pinned Phase 4AI verification/copy helpers are executed unchanged.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import importlib.util
|
||||
import json
|
||||
from pathlib import Path, PurePosixPath
|
||||
|
||||
|
||||
ROOT = Path('/data/digital-drosophila')
|
||||
MODEL_RELATIVE = Path('models/male-cns-lif/apl-timing-validation-v1')
|
||||
EXPERIMENT_RELATIVE = Path('experiments/phase4ak-apl-timing-validation')
|
||||
REGISTRY_RELATIVE = Path('registry/phase4ak-apl-timing-validation')
|
||||
HELPER_RELATIVE = Path('models/male-cns-lif/pn-recruitment-audit-v1/publication.py')
|
||||
HELPER_SHA256 = '7a79c499098b74163e7bb16adabcbc54e7069dafa204d0b99c7f4c03d79f8016'
|
||||
MAX_EVIDENCE_BYTES = 4 * 1024 ** 2
|
||||
EVIDENCE_SUFFIXES = frozenset(('.json', '.csv', '.md', '.log', '.sha256'))
|
||||
FINAL_STATUSES = frozenset((
|
||||
'PASS-FROZEN-D18-INDEPENDENT-VALIDATION',
|
||||
'FAIL-SEED-VALIDATION-REPRESENTATION',
|
||||
'FAIL-NOVEL-ODOR-REPRESENTATION',
|
||||
'FAIL-FROZEN-INTEGRITY-OR-REGRESSION',
|
||||
'FAIL-NUMERICAL-OR-EXECUTION-POLICY',
|
||||
'INCOMPLETE-VALIDATION-EXECUTION',
|
||||
))
|
||||
REQUIRED_EVIDENCE = ('audit/final-status.json', 'regression/old-integrity-after.json')
|
||||
REFERENCE_EVIDENCE = 'regression/frozen-five.json'
|
||||
GATE_FIELDS = ('numerical_gate_pass', 'seed_validation_pass', 'novel_to_aj_pass',
|
||||
'novel_dynamics_executed', 'novel_unlock_policy_violation',
|
||||
'old_frozen_integrity_pass', 'frozen_five_reference_pass')
|
||||
COUNT_FIELDS = ('planned_primary_cases', 'actual_primary_cases',
|
||||
'aggregated_valid_primary_cases', 'actual_checked_repeats')
|
||||
|
||||
|
||||
def require(condition, message):
|
||||
if not condition:
|
||||
raise ValueError(message)
|
||||
|
||||
|
||||
def load_helpers(path):
|
||||
"""Instantiate the unchanged module from its exact pinned source bytes.
|
||||
|
||||
Using module_from_spec plus the source bytes avoids writing/importing a pyc
|
||||
inside the sealed old model, even if the publisher was invoked without -B.
|
||||
No old module global is redirected or modified after module initialization.
|
||||
"""
|
||||
path = Path(path)
|
||||
require(path.is_absolute() and path.is_file() and not path.is_symlink(), 'Invalid frozen helper path')
|
||||
data = path.read_bytes()
|
||||
require(hashlib.sha256(data).hexdigest() == HELPER_SHA256, 'Frozen AI publication helper hash mismatch')
|
||||
spec = importlib.util.spec_from_file_location('phase4ak_frozen_ai_publication_helpers', path)
|
||||
require(spec is not None and spec.loader is not None, 'Unable to define frozen helper module')
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
exec(compile(data, str(path), 'exec'), module.__dict__)
|
||||
require(module._digest(path) == HELPER_SHA256, 'Helper source changed while loading')
|
||||
return module
|
||||
|
||||
|
||||
def _copy(helper, source, destination, size, checksum):
|
||||
"""Separate local delegation point for interruption-only synthetic tests."""
|
||||
helper._copy_verified(source, destination, size, checksum)
|
||||
|
||||
|
||||
def _write_small_json(helper, path, value):
|
||||
data = (json.dumps(value, indent=2, ensure_ascii=False, allow_nan=False) + '\n').encode('utf-8')
|
||||
require(len(data) <= MAX_EVIDENCE_BYTES, 'Generated registry evidence exceeds 4 MiB: ' + str(path))
|
||||
with Path(path).open('xb') as stream:
|
||||
stream.write(data)
|
||||
require(Path(path).stat().st_size == len(data), 'Generated registry evidence size changed')
|
||||
|
||||
|
||||
def _status_evidence(helper, experiment, rows):
|
||||
"""Check declaration consistency only, not the scientific gate itself."""
|
||||
for relative in REQUIRED_EVIDENCE:
|
||||
require(relative in rows, 'Required finalized evidence absent from seal: ' + relative)
|
||||
require(rows[relative]['bytes'] <= MAX_EVIDENCE_BYTES, 'Required finalized evidence exceeds 4 MiB')
|
||||
status, integrity = [helper._json_bytes((experiment / relative).read_bytes())
|
||||
for relative in REQUIRED_EVIDENCE]
|
||||
reference = None
|
||||
if REFERENCE_EVIDENCE in rows:
|
||||
require(rows[REFERENCE_EVIDENCE]['bytes'] <= MAX_EVIDENCE_BYTES, 'Frozen reference evidence exceeds 4 MiB')
|
||||
reference = helper._json_bytes((experiment / REFERENCE_EVIDENCE).read_bytes())
|
||||
require(isinstance(reference, dict) and type(reference.get('pass_all')) is bool and
|
||||
isinstance(reference.get('trials'), list), 'Invalid frozen reference report')
|
||||
if reference['pass_all']:
|
||||
require(len(reference['trials']) == 5, 'Declared frozen-five PASS must contain five trial records')
|
||||
require(isinstance(status, dict) and status.get('status') in FINAL_STATUSES,
|
||||
'Unrecognized Phase 4AK final status')
|
||||
for key in GATE_FIELDS:
|
||||
require(type(status.get(key)) is bool, 'Missing/non-Boolean finalized result: ' + key)
|
||||
for key in COUNT_FIELDS:
|
||||
require(type(status.get(key)) is int and status[key] >= 0, 'Missing/invalid finalized count: ' + key)
|
||||
require(status['planned_primary_cases'] == 120, 'Declared planned validation design changed')
|
||||
# Preserve unexpected actual coverage in a declared failure, not censor it.
|
||||
# A PASS below still requires exactly the predeclared 120 + 24 coverage.
|
||||
for key in ('candidate_generated', 'learning_achieved', 'full_scientific_goal_achieved',
|
||||
'dynamics_changed', 'old_heldout_dynamic_results_parsed', 'biological_delay_measured'):
|
||||
require(status.get(key) is False, 'Unexpected finalized scope claim: ' + key)
|
||||
require(status.get('unchanged_sealed_runtime') is True and
|
||||
status.get('shared_APL_arithmetic_oracle_limitation') is True and
|
||||
type(status.get('APL_nonKC_fast_edges_unreplaced')) is int and
|
||||
status['APL_nonKC_fast_edges_unreplaced'] == 1212, 'Missing/changed finalized runtime limitations')
|
||||
require(status.get('novel_scope') == 'Unused for AG/AJ calibration, not historically never simulated',
|
||||
'Unrecognized novel-odor scope')
|
||||
require(isinstance(integrity, dict) and bool(integrity) and all(
|
||||
isinstance(row, dict) and type(row.get('pass')) is bool for row in integrity.values()),
|
||||
'Missing/invalid frozen-integrity report')
|
||||
require(status['old_frozen_integrity_pass'] == all(row['pass'] for row in integrity.values()),
|
||||
'Final status contradicts its frozen-integrity report')
|
||||
reference_pass = bool(reference is not None and reference['pass_all'])
|
||||
require(status['frozen_five_reference_pass'] == reference_pass,
|
||||
'Final status contradicts its frozen-reference report/presence')
|
||||
if status['status'].startswith('PASS-'):
|
||||
require(status['numerical_gate_pass'] and status['seed_validation_pass'] and
|
||||
status['novel_to_aj_pass'] and status['novel_dynamics_executed'] and
|
||||
not status['novel_unlock_policy_violation'] and status['old_frozen_integrity_pass'] and
|
||||
reference_pass and status['actual_primary_cases'] == 120 and
|
||||
status['aggregated_valid_primary_cases'] == 120 and status['actual_checked_repeats'] == 24,
|
||||
'Declared PASS contradicts finalized gate/coverage flags')
|
||||
return status, reference, integrity
|
||||
|
||||
|
||||
def publish(root=ROOT, helper_path=None):
|
||||
"""Publish the fixed AK registry exclusively; root override is for tests.
|
||||
|
||||
Only sealed small experiment evidence and the two model seal controls are
|
||||
copied. Every bulk payload is nevertheless verified before and after copying.
|
||||
An interrupted registry is preserved and cannot be overwritten or resumed.
|
||||
"""
|
||||
root = Path(root)
|
||||
require(root.is_absolute() and root.is_dir() and not root.is_symlink(), 'Invalid project root')
|
||||
root = root.resolve(strict=True)
|
||||
model, experiment, registry = (root / part for part in
|
||||
(MODEL_RELATIVE, EXPERIMENT_RELATIVE, REGISTRY_RELATIVE))
|
||||
require(not registry.exists() and not registry.is_symlink(), 'Registry already exists; no overwrite/resume')
|
||||
helper_path = root / HELPER_RELATIVE if helper_path is None else Path(helper_path)
|
||||
helper = load_helpers(helper_path)
|
||||
for path in (model, experiment, registry.parent):
|
||||
current = root
|
||||
for part in path.relative_to(root).parts:
|
||||
current = current / part
|
||||
require(not current.is_symlink(), 'Symlink in publication root path: ' + str(current))
|
||||
verified = {'model': helper.verify_seal(model), 'experiment': helper.verify_seal(experiment)}
|
||||
experiment_rows = {row['path']: row for row in verified['experiment']['files']}
|
||||
status, reference, integrity = _status_evidence(helper, experiment, experiment_rows)
|
||||
plans, omitted = [], []
|
||||
for row in verified['experiment']['files'] + helper._control_rows(experiment, verified['experiment']):
|
||||
if PurePosixPath(row['path']).suffix.lower() in EVIDENCE_SUFFIXES and row['bytes'] <= MAX_EVIDENCE_BYTES:
|
||||
plans.append((experiment, row, 'evidence/' + row['path']))
|
||||
else:
|
||||
omitted.append(dict(path=row['path'], bytes=row['bytes'], sha256=row['sha256'],
|
||||
reason='exceeds_4_MiB' if row['bytes'] > MAX_EVIDENCE_BYTES else 'bulk_or_non_evidence_extension'))
|
||||
for row in helper._control_rows(model, verified['model']):
|
||||
require(row['bytes'] <= MAX_EVIDENCE_BYTES, 'Model seal control exceeds small-evidence limit')
|
||||
plans.append((model, row, 'model/' + row['path']))
|
||||
destinations = {target for _, _, target in plans}
|
||||
required_copies = ['manifest.json', 'checksums.sha256', *REQUIRED_EVIDENCE]
|
||||
if reference is not None:
|
||||
required_copies.append(REFERENCE_EVIDENCE)
|
||||
for relative in required_copies:
|
||||
require('evidence/' + relative in destinations, 'Required experiment evidence cannot be copied: ' + relative)
|
||||
require(len(destinations) == len(plans), 'Duplicate planned evidence destination')
|
||||
registry.parent.mkdir(parents=True, exist_ok=True)
|
||||
registry.mkdir(exist_ok=False)
|
||||
try:
|
||||
records = []
|
||||
for source_root, row, relative in plans:
|
||||
source = helper._regular_file(source_root.resolve(), row['path'])
|
||||
_copy(helper, source, registry / relative, row['bytes'], row['sha256'])
|
||||
records.append(dict(source=source.relative_to(root).as_posix(), copy=relative,
|
||||
bytes=row['bytes'], sha256=row['sha256']))
|
||||
after = {'model': helper.verify_seal(model), 'experiment': helper.verify_seal(experiment)}
|
||||
require(after == verified, 'A sealed tree changed during publication')
|
||||
require(helper._digest(helper_path) == HELPER_SHA256, 'Frozen helper changed during publication')
|
||||
proof = {name: {key: value for key, value in report.items() if key != 'files'}
|
||||
for name, report in verified.items()}
|
||||
_write_small_json(helper, registry / 'seal-verification.json', proof)
|
||||
_write_small_json(helper, registry / 'evidence-index.json', records)
|
||||
files = [dict(path=path.relative_to(registry).as_posix(), bytes=path.stat().st_size,
|
||||
sha256=helper._digest(path)) for path in sorted(registry.rglob('*')) if path.is_file()]
|
||||
receipt = dict(publication_complete=True, registry=registry.relative_to(root).as_posix(),
|
||||
project_root=str(root), declared_audit_status=status['status'],
|
||||
declared_gate_results={key: status[key] for key in GATE_FIELDS},
|
||||
declared_validation_counts={key: status[key] for key in COUNT_FIELDS},
|
||||
declared_novel_scope=status['novel_scope'],
|
||||
frozen_reference_report=dict(present=reference is not None,
|
||||
path='evidence/' + REFERENCE_EVIDENCE if reference is not None else None,
|
||||
sha256=experiment_rows[REFERENCE_EVIDENCE]['sha256'] if reference is not None else None,
|
||||
declared_pass_all=reference['pass_all'] if reference is not None else None,
|
||||
reported_trial_count=len(reference['trials']) if reference is not None else None,
|
||||
missing_is_not_a_success_or_fabricated_trial_failure=True),
|
||||
frozen_integrity_report=dict(path='evidence/regression/old-integrity-after.json',
|
||||
sha256=experiment_rows['regression/old-integrity-after.json']['sha256'],
|
||||
declared_pass_by_root={name: row['pass'] for name, row in integrity.items()}),
|
||||
frozen_helper_source=str(helper_path), frozen_helper_sha256=HELPER_SHA256,
|
||||
publisher_sha256=helper._digest(Path(__file__)), helper_globals_redirected=False,
|
||||
model_manifest_sha256=verified['model']['manifest_sha256'],
|
||||
experiment_manifest_sha256=verified['experiment']['manifest_sha256'],
|
||||
source_trees_verified_before_and_after_copy=True,
|
||||
copied_evidence_files=len(records), copied_evidence_bytes=sum(row['bytes'] for row in records),
|
||||
files=files, experiment_payload_not_copied=omitted,
|
||||
model_payload_not_duplicated=True, model_payload_remains_at=MODEL_RELATIVE.as_posix(),
|
||||
bulk_remains_at=EXPERIMENT_RELATIVE.as_posix(), complete_bulk_backup=False,
|
||||
scientific_gate_executed_by_publisher=False, scientific_gate_certified_by_publication=False,
|
||||
publication_success_is_not_scientific_pass=True, candidate_generated=False,
|
||||
learning_achieved=False, full_scientific_goal_achieved=False,
|
||||
old_heldout_dynamic_results_parsed=False, existing_files_modified=False,
|
||||
receipt_self_hash='Not self-referential; returned by publish() and printed by main()',
|
||||
limits=dict(max_selected_evidence_file_bytes=MAX_EVIDENCE_BYTES,
|
||||
selected_suffixes=sorted(EVIDENCE_SUFFIXES)))
|
||||
receipt_path = registry / 'publication-receipt.json'
|
||||
_write_small_json(helper, receipt_path, receipt)
|
||||
return dict(publication_complete=True, registry=str(registry), declared_audit_status=status['status'],
|
||||
copied_evidence_files=len(records), receipt_sha256=helper._digest(receipt_path),
|
||||
scientific_gate_executed_by_publisher=False, publication_success_is_not_scientific_pass=True)
|
||||
except Exception as error:
|
||||
failure = registry / 'publication-failure.json'
|
||||
if not failure.exists():
|
||||
_write_small_json(helper, failure, dict(publication_complete=False, type=type(error).__name__,
|
||||
message=str(error), partial_outputs_preserved=True, existing_files_modified=False))
|
||||
raise
|
||||
|
||||
|
||||
def main():
|
||||
print(json.dumps(publish(), ensure_ascii=False, allow_nan=False), flush=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user