#!/usr/bin/env python3 """Write the RPF-WP-0015-T03 synthetic E2 approval receipt for one founder window. Usage: scripts/rpf-wp-0015-e2-receipt.py OUTPUT.json [--start-in-min N] The window is 15 minutes and starts now, or N minutes from now. Writing the receipt and running the window is the founder GO for that window; D5 (2fd5849c) authorizes the exercise class only. The owner acknowledgements are the round-9 approvals of review contract 014627d6 (audit-core 0d0da0d2, rapp-postgres 6d047a08, railiance-platform c4a80a60). They stay valid only while the pinned artifacts in interfaces/RAILIANCE-WP-0024-owner-reviews.json are unchanged; the script refuses otherwise. The receipt holds no credential values. It refuses to overwrite an existing file. """ import hashlib import json import sys from datetime import datetime, timedelta, timezone from pathlib import Path ROOT = Path(__file__).resolve().parents[1] pins = json.loads((ROOT / "interfaces/RAILIANCE-WP-0024-owner-reviews.json").read_text())["artifact_sha256"] drift = [p for p, h in pins.items() if hashlib.sha256((ROOT / p).read_bytes()).hexdigest() != h] if drift: sys.exit("owner-reviewed artifacts changed since contract 014627d6; new owner approvals needed: " + ", ".join(drift)) if len(sys.argv) < 2: sys.exit(__doc__) out = sys.argv[1] delay = int(sys.argv[sys.argv.index('--start-in-min') + 1]) if '--start-in-min' in sys.argv else 0 start = datetime.now(timezone.utc).replace(second=0, microsecond=0) + timedelta(minutes=delay) end = start + timedelta(minutes=15) tag = start.strftime('%Y%m%dt%H%M') z = lambda t: t.strftime('%Y-%m-%dT%H:%M:%SZ') receipt = { "procedure": "audit-core-database-lease-recovery", "task_id": "RAILIANCE-WP-0024-T03", "status": "approved", "approval_id": f"rpf-wp-0015-t03-e2-{tag}z-founder-go", "window": {"start": z(start), "end": z(end)}, "abort_operator": "founder (platform-root), attended", "owners": { "audit-core": {"acknowledged": True, "message_id": "0d0da0d2-36a1-4ffc-b7bf-7896fad691f6"}, "rapp-postgres": {"acknowledged": True, "message_id": "6d047a08-e9c8-4dbf-95b9-dca039791329"}, "railiance-platform": {"acknowledged": True, "message_id": "c4a80a60-a415-4f2b-8928-751407473641"}, }, "synthetic_load": {"contract_id": "RAILIANCE-WP-0024-T02-SYNTHETIC-01", "driver_revision": "sha256:941ba251f638869626b06e9cbf430c70188c0bdf4715e3eff9c7610366f68662"}, "synthetic_sender": {"identity": f"t03-e2-synthetic-sender-{start:%Y%m%d}", "source": f"t03-e2-synthetic-{start:%Y%m%d}", "tenant": f"tenant:trial:t03-e2-synthetic-{start:%Y%m%d}", "expires_at": z(end)}, } with open(out, 'x') as f: json.dump(receipt, f, indent=2); f.write('\n') print(json.dumps({"approval_id": receipt["approval_id"], "window": receipt["window"], "confirm": f"audit-core-synthetic-sender:{receipt['approval_id']}:attended"}))