"""Run with python3 -m intelligence_radar. Standard library only.""" import argparse from datetime import date, datetime import hashlib import json from pathlib import Path import re import sys from urllib.parse import urlparse def canonical(value): return json.dumps(value, sort_keys=True, separators=(',', ':'), ensure_ascii=False, allow_nan=False).encode() def digest(value): return hashlib.sha256(canonical(value)).hexdigest() def validate(record): if not isinstance(record, dict): raise ValueError('record must be an object') required = {'schema_version', 'title', 'claim', 'source_url', 'source_kind', 'content_sha256', 'observed_at', 'event_date', 'status', 'observer'} allowed = required | {'supersedes', 'notes'} if set(record) - allowed or required - set(record): raise ValueError('record has missing or unknown fields') if type(record['schema_version']) is not int or record['schema_version'] != 1: raise ValueError('schema_version must be 1') for key in allowed - {'schema_version'}: if key in record and (not isinstance(record[key], str) or not record[key].strip()): raise ValueError(f'{key} must be nonempty text') if record['source_kind'] not in {'primary', 'secondary', 'local', 'synthetic'}: raise ValueError('invalid source_kind') if record['status'] not in {'reported', 'corroborated', 'disputed', 'retracted'}: raise ValueError('invalid status') url = urlparse(record['source_url']) if url.scheme not in {'https', 'http', 'file'} or (url.scheme != 'file' and not url.netloc): raise ValueError('source_url must be an http(s) or file URL') if url.username or url.password: raise ValueError('source_url must not contain credentials') for key in ('content_sha256', 'supersedes'): if key in record and not re.fullmatch('[0-9a-f]{64}', record[key]): raise ValueError(f'{key} must be a lowercase SHA-256') observed = datetime.fromisoformat(record['observed_at'].replace('Z', '+00:00')) if observed.tzinfo is None: raise ValueError('observed_at requires a timezone') event = date.fromisoformat(record['event_date']) if event.isoformat() != record['event_date']: raise ValueError('event_date requires YYYY-MM-DD') if event > observed.date(): raise ValueError('event_date cannot follow observation date; describe future plans in claim') def ledger(root): result = [] for path in sorted((root / 'data/observations').glob('*.json')): envelope = json.loads(path.read_text()) if not isinstance(envelope, dict) or set(envelope) != {'id', 'record'}: raise ValueError(f'invalid envelope: {path}') validate(envelope['record']) ident = digest(envelope['record']) if envelope['id'] != ident or path.stem != ident: raise ValueError(f'integrity mismatch: {path}') result.append(envelope) ids = {item['id'] for item in result} for item in result: parent = item['record'].get('supersedes') if parent and parent not in ids: raise ValueError(f'unknown superseded observation: {parent}') return result def record(root, value): validate(value) items = ledger(root) if value.get('supersedes') and value['supersedes'] not in {x['id'] for x in items}: raise ValueError('supersedes must reference an existing observation') ident = digest(value) path = root / 'data/observations' / f'{ident}.json' path.parent.mkdir(parents=True, exist_ok=True) envelope = {'id': ident, 'record': value} from .store import atomic atomic(path, (json.dumps(envelope, indent=2, ensure_ascii=False) + '\n').encode(), immutable=True) return ident def draft(root, period): if re.fullmatch(r'\d{4}-W\d{2}', period): year, week = period.split('-W') start = date.fromisocalendar(int(year), int(week), 1) matches = lambda d: d.isocalendar()[:2] == start.isocalendar()[:2] kind = 'weekly' else: start = date.fromisoformat(period) if start.isoformat() != period: raise ValueError('use YYYY-MM-DD or YYYY-Www') matches = lambda d: d == start kind = 'daily' items = [x for x in ledger(root) if matches(date.fromisoformat(x['record']['event_date']))] lines = [f'# Radar {kind} draft — {period}', '', 'Status: draft; editorial review required. Claims retain their reported status.', '', 'Selection: event date; observation timestamps below preserve when evidence was received.', ''] if not items: lines += ['No recorded observations for this period. This does not establish that no events occurred.', ''] for item in items: r = item['record'] lines += [f"## {r['title']}", '', r['claim'], '', f"- Status: {r['status']}; source kind: {r['source_kind']}", f"- Source: {r['source_url']}", f"- Observed: {r['observed_at']}", f"- Observation: {item['id']}"] if r.get('supersedes'): lines.append(f"- Supersedes: {r['supersedes']}") lines.append('') from .external_briefs import briefs_for_period briefs = briefs_for_period(root, period) if briefs: lines += ['## External automation briefs', '', 'Unverified ChatGPT or Grok automation output retained for this period.', 'These briefs are not reviewed facts.', ''] for brief in briefs: lines += [f"- {brief['provider']} {brief['cadence']}: {brief['digest_path']}", f"- Content: {brief['content_sha256']}"] lines.append('') lines += ['## Editorial follow-up', '', 'Review source claims, contradictions, frontier/price impacts, compendium edits,', 'benchmark health, and evidence gaps. Draft generation is not fact verification.', ''] path = root / 'digests' / kind / f'{period}.md' path.parent.mkdir(parents=True, exist_ok=True) with path.open('x') as stream: stream.write('\n'.join(lines)) return path def check(root): required = ['INTENT.md', 'GOAL.md', 'SCOPE.md', 'AGENTS.md', 'README.md', 'TaskModelEvaluationMethod.md', 'task-router/METHOD.md', 'policies/model-ranking-v0.1.yaml', 'policies/benchmark-selection-v0.1.yaml', 'ops/RUNBOOK.md', 'history/MANIFEST.json'] for name in required: if not (root / name).is_file(): raise ValueError(f'missing {name}') manifest = json.loads((root / 'history/MANIFEST.json').read_text()) for item in manifest['archives']: path = (root / item['path']).resolve() if not path.is_relative_to((root / 'history').resolve()): raise ValueError('archive path escapes history') if hashlib.sha256(path.read_bytes()).hexdigest() != item['sha256']: raise ValueError(f'archive checksum mismatch: {path}') from .ingest import check_artifacts from .store import all_records check_artifacts(root) for kind in ('recommendations', 'outcomes', 'ingestion-runs', 'scheduler-runs'): all_records(root, kind) from .external_briefs import verify verify(root) from .publications import verify as verify_publications verify_publications(root) from .advisor import replay for ident, _ in all_records(root, 'recommendations'): replay(root, ident) return len(ledger(root)) def main(argv=None): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument('--root', type=Path, default=Path.cwd(), help='repository or isolated ledger root') commands = parser.add_subparsers(dest='command', required=True) commands.add_parser('check', help='check repository, archive integrity, and ledger') commands.add_parser('validate', help='validate every observation and integrity hash') add = commands.add_parser('record', help='record a source observation JSON without overwriting history') add.add_argument('input', type=Path) render = commands.add_parser('digest', help='create a daily or ISO-week draft, refusing overwrite') render.add_argument('period') ingest_command = commands.add_parser('ingest', help='capture registered primary-source artifacts') ingest_command.add_argument('registry', type=Path) advisor_command = commands.add_parser('advise', help='save a reproducible task-specific recommendation') advisor_command.add_argument('task', type=Path) advisor_command.add_argument('--catalog', type=Path, required=True) advisor_command.add_argument('--policy', type=Path, default=Path('policies/advisor-v0.2.json')) advisor_command.add_argument('--as-of', required=True) advisor_command.add_argument('--synthetic', action='store_true') report_command = commands.add_parser('report', help='render a saved comparison as Markdown') report_command.add_argument('id') replay_command = commands.add_parser('replay', help='verify a saved recommendation using its frozen inputs') replay_command.add_argument('id') outcome_command = commands.add_parser('outcome', help='record an actual task execution and acceptance result') outcome_command.add_argument('input', type=Path) schedule_command = commands.add_parser('run-due', help='run latest due daily/weekly jobs; safe to invoke repeatedly') schedule_command.add_argument('--config', type=Path, default=Path('ops/schedule.json')) briefs_command = commands.add_parser('import-briefs', help='retain unarchived ChatGPT and Grok briefs from the local inbox') briefs_command.add_argument('--config', type=Path, default=Path('ops/schedule.json')) briefs_command.add_argument('--inbox', type=Path, help='override the configured inbox for this run') publish_command = commands.add_parser('publish', help='record a reviewed publication linked to captures') publish_command.add_argument('input', type=Path) commands.add_parser('health', help='show durable scheduler health') export_command = commands.add_parser('export', help='export a recommendation and source dependencies as a tar bundle') export_command.add_argument('id') export_command.add_argument('output', type=Path) import_command = commands.add_parser('import', help='validate and import a portable recommendation bundle') import_command.add_argument('input', type=Path) trials_command = commands.add_parser('trials', help='run authorized OpenRouter work samples within a campaign budget') trials_command.add_argument('--config', type=Path, required=True) trials_command.add_argument('--suite', type=Path, required=True) trials_command.add_argument('--pilot', action='store_true') trials_command.add_argument('--plan', action='store_true', help='review request identities and budget without calls or writes') reconcile_command = commands.add_parser('reconcile', help='settle a pending trial reservation from reviewed external billing evidence') reconcile_command.add_argument('--campaign', required=True) reconcile_command.add_argument('--run-id', required=True) reconcile_command.add_argument('--actual-usd', required=True) reconcile_command.add_argument('--evidence-ref', required=True, help='pointer (hash or path) to retained evidence, not a credential') reconcile_command.add_argument('--reviewer', required=True) args = parser.parse_args(argv) try: if args.command == 'trials': from .trials import plan, run action = plan if args.plan else run print(json.dumps(action(args.root, json.loads(args.config.read_text()), json.loads(args.suite.read_text()), args.pilot), indent=2)) elif args.command == 'reconcile': from .trials import reconcile print(reconcile(args.root, args.campaign, args.run_id, args.actual_usd, args.evidence_ref, args.reviewer)) elif args.command == 'export': from .bundles import export_bundle print(json.dumps(export_bundle(args.root, args.id, args.output), indent=2)) elif args.command == 'import': from .bundles import import_bundle print(json.dumps(import_bundle(args.root, args.input), indent=2)) elif args.command == 'ingest': from .ingest import ingest result = ingest(args.root, json.loads(args.registry.read_text())) print(json.dumps(result, indent=2)) return 0 if result['ok'] else 1 elif args.command == 'advise': from .advisor import recommend ident, report = recommend(args.root, json.loads(args.task.read_text()), json.loads(args.catalog.read_text()), json.loads(args.policy.read_text()), args.as_of, args.synthetic) print(json.dumps({'recommendation_id': ident, **report}, indent=2)) elif args.command == 'report': from .advisor import render_report print(render_report(args.root, args.id)) elif args.command == 'replay': from .advisor import replay print(json.dumps(replay(args.root, args.id), indent=2)) elif args.command == 'outcome': from .advisor import outcome print(outcome(args.root, json.loads(args.input.read_text()))) elif args.command == 'run-due': from .scheduler import run_due result = run_due(args.root, json.loads(args.config.read_text())) print(json.dumps(result, indent=2)) external = result.get('external_briefs') or {} return 0 if result['ok'] and external.get('ok', True) else 1 elif args.command == 'publish': from .publications import publish print(publish(args.root, json.loads(args.input.read_text()))) elif args.command == 'import-briefs': from .external_briefs import import_inbox, native_status, resolve_inbox spec = json.loads(args.config.read_text()).get('external_briefs', {}) inbox = args.inbox or resolve_inbox(spec) result = import_inbox(args.root, inbox, archive_dirname=spec.get('archive_dirname', 'archive')) result['native'] = native_status() print(json.dumps(result, indent=2)) return 0 if result['ok'] else 1 elif args.command == 'health': path = args.root / '.runtime/scheduler.json' print(path.read_text() if path.exists() else '{"status": "not_run"}') elif args.command == 'record': print(record(args.root, json.loads(args.input.read_text()))) elif args.command == 'digest': print(draft(args.root, args.period)) elif args.command == 'validate': print(f'{len(ledger(args.root))} valid observations') else: print(f'Repository and archives valid; {check(args.root)} observations') except (ValueError, OSError, KeyError, TypeError) as exc: print(f'error: {exc}', file=sys.stderr) return 1 return 0 if __name__ == '__main__': sys.exit(main())