Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a09c77-b1a9-7eb3-b501-6cb24b458c97
223 lines
11 KiB
Python
223 lines
11 KiB
Python
"""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('')
|
|
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 .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'))
|
|
commands.add_parser('health', help='show durable scheduler health')
|
|
args = parser.parse_args(argv)
|
|
try:
|
|
if 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))
|
|
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())
|