Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a09cbd-43c1-79f3-809e-1ee97b40b64d
192 lines
8.8 KiB
Python
Executable file
192 lines
8.8 KiB
Python
Executable file
#!/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())
|