"""Rebuild through the hardened generator; keep this run's source/output audit.""" import json from datetime import datetime, timezone from pathlib import Path import subprocess import sys ROOT = Path(__file__).resolve().parents[3] sys.path.insert(0, str(ROOT / 'scripts')) import ambience_audio as audio EVIDENCE = Path(__file__).resolve().parent plan_path = ROOT / '.agent/AMBIENCE-SOURCES-v0.2.3.json' plan_bytes = plan_path.read_bytes() plan = json.loads(plan_bytes) source_directory = Path('/tmp/findword-ambience-sources') records = [] for asset in plan['assets']: path = audio.source_path(source_directory, asset['environmentId']) probe = json.loads(subprocess.check_output(['ffprobe', '-v', 'error', '-show_entries', 'format=duration', '-of', 'json', str(path)], text=True)) record = {'environmentId': asset['environmentId'], 'sha256': audio.digest(path), 'bytes': path.stat().st_size, 'directMediaDurationSeconds': float(probe['format']['duration']), 'selectedSegmentStartSeconds': asset['selectedSegmentStartSeconds']} assert record['sha256'] == asset['expectedSourceSha256'] assert record['bytes'] == asset['sourceBytes'] assert record['directMediaDurationSeconds'] == asset['directMediaDurationSeconds'] records.append(record) print('All eight source SHA-256, byte counts and direct-media durations match before conversion.', flush=True) manifest = audio.generate(plan, source_directory, ROOT / 'public/ambience') assert plan_path.read_bytes() == plan_bytes assert plan == json.loads(plan_bytes) audio.validate_bundle(ROOT / 'public/ambience', plan) record = {'completedAtUtc': datetime.now(timezone.utc).isoformat(), 'method': 'ambience_audio.generate: source preflight, full staged bundle validation, atomic directory exchange', 'allSourcesMatchedBeforeConversion': True, 'planUnmodified': True, 'sources': records, 'manifestSha256': audio.digest(ROOT / 'public/ambience/manifest.json'), 'toolVersions': manifest['toolVersions'], 'outputs': [{k: e[k] for k in ('environmentId', 'selectedSegmentStartSeconds', 'sha256', 'bytes', 'duration', 'rms', 'peak', 'conversion')} for e in manifest['files']]} with (EVIDENCE / 'regeneration.json').open('x') as stream: stream.write(json.dumps(record, ensure_ascii=False, indent=2) + '\n') print(json.dumps(record, ensure_ascii=False, indent=2))