#!/usr/bin/env python3 """Audit Hub completions against a freshly resolved origin/main Git tree. Exit 0: checks pass (or explicitly allowed acknowledged historical gaps). Exit 1: missing/invalid evidence. Exit 2: verification could not run reliably. --require-date YYYY-MM-DD also requires a valid completion for that day. """ from __future__ import annotations import argparse from datetime import date import json import os from pathlib import Path import re import subprocess import sys import urllib.parse import urllib.request ROOT = Path(__file__).resolve().parents[1] REPO = 'freedom-intelligence' CONTRACT_START = '2026-09-13' CORRECTION_TYPE = 'fi_daily_brief_reconciliation' SHA = re.compile(r'[0-9a-f]{40}') def brief_path(day: str) -> str: if date.fromisoformat(day).isoformat() != day: raise ValueError('date must be YYYY-MM-DD') return f'briefs/{day[:4]}/{day[5:7]}/{day}.md' def git(root: Path, *args: str, check=True): result = subprocess.run(['git', '-C', str(root), *args], capture_output=True, text=True, timeout=120) if check and result.returncode: raise RuntimeError(f'git {args[0]} failed: {result.stderr.strip()}') return result class Origin: def __init__(self, root: Path): self.root = root # Never trust a stale tracking ref or the checked-out branch. remote = git(root, 'ls-remote', '--exit-code', 'origin', 'refs/heads/main').stdout.split() if len(remote) != 2 or not SHA.fullmatch(remote[0]): raise RuntimeError('origin/main did not resolve to one commit') self.sha = remote[0] if git(root, 'cat-file', '-e', f'{self.sha}^{{commit}}', check=False).returncode: git(root, 'fetch', '--no-tags', '--no-write-fetch-head', 'origin', 'refs/heads/main') git(root, 'cat-file', '-e', f'{self.sha}^{{commit}}') def blob(self, path: str, revision: str | None = None) -> bool: revision = revision or self.sha if not SHA.fullmatch(revision): return False entry = git(self.root, 'ls-tree', revision, '--', path, check=False) fields = entry.stdout.split() # Reject symlinks, trees and empty files as completion artifacts. if entry.returncode or len(fields) != 4 or fields[0] not in {'100644', '100755'}: return False return fields[1] == 'blob' and int(git(self.root, 'cat-file', '-s', fields[2]).stdout) > 0 def published(self, revision: str, path: str) -> bool: if not SHA.fullmatch(revision): return False return (git(self.root, 'merge-base', '--is-ancestor', revision, self.sha, check=False).returncode == 0 and self.blob(path, revision)) def correction_recorded(self, detail: dict) -> bool: revision = str(detail.get('evidence_sha', '')) path = str(detail.get('evidence_path', '')) if not self.published(revision, path): return False try: evidence = json.loads(git(self.root, 'show', f'{revision}:{path}').stdout) records = evidence['corrections'] except (ValueError, KeyError, TypeError): return False fields = ('original_event_id', 'date', 'path', 'disposition', 'reason') return any(isinstance(row, dict) and all(row.get(k) == detail.get(k) for k in fields) for row in records) def load_events(url: str, timeout: float, event_type='fi_daily_brief', page_size=1000) -> list[dict]: events = [] seen = set() for offset in range(0, 1_000_000, page_size): query = urllib.parse.urlencode(dict(event_type=event_type, limit=page_size, offset=offset)) req = urllib.request.Request(f"{url.rstrip('/')}/progress/?{query}", headers={'Accept': 'application/json'}) with urllib.request.urlopen(req, timeout=timeout) as response: page = json.load(response) if not isinstance(page, list): raise RuntimeError('unexpected Hub progress payload: expected a list') for event in page: if not isinstance(event, dict) or not event.get('id') or event['id'] in seen: raise RuntimeError('malformed or unstable Hub pagination; retry verification') seen.add(event['id']) events.extend(page) if len(page) < page_size: return events raise RuntimeError('Hub pagination exceeded safety bound') def assess(events, corrections, origin, required_date=None): result = {'origin_sha': origin.sha, 'valid': [], 'legacy': [], 'reconciled': [], 'failures': []} correction_index = {} for correction in corrections: d = correction.get('detail') or {} if not isinstance(d, dict) or d.get('repo') != REPO: continue if (d.get('disposition') == 'false_completion' and d.get('reason') and origin.correction_recorded(d)): correction_index.setdefault(d.get('original_event_id'), []).append(d) for event in events: d = event.get('detail') or {} if not isinstance(d, dict): result['failures'].append({'id': event.get('id'), 'reason': 'invalid event detail'}) continue if d.get('repo') not in {None, REPO}: continue row = {'id': event.get('id'), 'date': d.get('date')} try: path = brief_path(d.get('date', '')) except (ValueError, TypeError): result['failures'].append(dict(row, reason='invalid or missing date')) continue if not origin.blob(path): acknowledged = any(c.get('date') == d['date'] and c.get('path') == path for c in correction_index.get(event.get('id'), [])) target = 'reconciled' if acknowledged else 'failures' result[target].append(dict(row, reason='brief absent from origin/main', path=path)) continue if d.get('path', path) != path: result['failures'].append(dict(row, reason='event path does not match date')) continue modern = d['date'] >= CONTRACT_START or 'pushed' in d or 'origin_sha' in d if modern: if (d.get('pushed') is not True or d.get('path') != path or not origin.published(str(d.get('origin_sha', '')), path)): result['failures'].append(dict(row, reason='invalid pushed/origin_sha publication evidence')) continue result['valid'].append(row) else: # Historic files exist on origin but predate the push-attestation contract. result['legacy'].append(row) if required_date and required_date not in {r['date'] for r in result['valid']}: result['failures'].append({'date': required_date, 'reason': 'required day has no valid published completion'}) return result def main() -> int: ap = argparse.ArgumentParser(description=__doc__) ap.add_argument('--hub', default=os.environ.get('STATE_HUB_URL', 'http://127.0.0.1:8000')) ap.add_argument('--timeout', type=float, default=8) ap.add_argument('--require-hub', action='store_true', help='compatibility flag; Hub is always required') ap.add_argument('--require-date', help='require a valid pushed completion for this exact day') ap.add_argument('--allow-reconciled', action='store_true', help='acknowledged historical gaps do not fail the audit') ap.add_argument('--json', action='store_true', help='machine-readable audit result') args = ap.parse_args() try: if args.require_date: brief_path(args.require_date) origin = Origin(ROOT) events = load_events(args.hub, args.timeout) corrections = load_events(args.hub, args.timeout, CORRECTION_TYPE) result = assess(events, corrections, origin, args.require_date) except (OSError, ValueError, RuntimeError, subprocess.SubprocessError) as exc: if args.json: print(json.dumps({'ok': False, 'error': str(exc)})) else: print(f'ERROR verification unavailable: {exc}', file=sys.stderr) return 2 result['ok'] = not result['failures'] and (args.allow_reconciled or not result['reconciled']) if args.json: print(json.dumps(result, indent=2)) else: print(f'origin/main: {origin.sha} (resolved from live remote)') print(f"valid published events: {len(result['valid'])}; legacy files on origin: {len(result['legacy'])}") for row in result['reconciled']: print(f"GAP acknowledged false completion: {row['date']} event={row['id']}") for row in result['failures']: print(f"FAIL {row.get('date', '-')}: {row['reason']}") print('PASS (acknowledged gaps remain missing)' if result['ok'] and result['reconciled'] else 'PASS' if result['ok'] else 'FAIL durability audit') return 0 if result['ok'] else 1 if __name__ == '__main__': sys.exit(main())