spb/anomaly-atlas Public License
Systematic discovery & rigorous validation of statistical anomalies in open HF market data (hfmarketdata.io) — pre-registered, artifact-null-driven, fully reproducible. Live atlas: www.anomaly-atlas.io
Python 61.4%
JavaScript 28.7%
CSS 8.6%
Shell 0.7%
Makefile 0.5%
1#!/usr/bin/env python32# =============================================================================3# Project : anomaly-atlas4# File : tools/new_finding.py5# Purpose : Scaffold a compliant atlas entry — refuses incomplete provenance6# Author : Simon-Pierre Boucher7# Contact : contact@spboucher.ai8# Data src : hfmarketdata.io (sole data source)9# Created : 2026-08-1210# Modified : 2026-08-1211# Platform : macOS / Apple Silicon (arm64)12# License : All rights reserved (research code)13# =============================================================================14"""Create atlas/<anomaly_id>/<version>/ from a completed finding payload.1516Refuses to create an entry unless BOTH a complete provenance.json and a17confidence.md are supplied (CLAUDE.md §3, §10). Level 0 findings are refused18outright — in-sample-only output never enters the atlas.1920Usage:21 python3 tools/new_finding.py <anomaly_id> <version> \\22 --finding finding.json --provenance provenance.json --confidence confidence.md2324Required provenance keys:25 commit, config, data_manifest_hash, hardware_manifest, generated_utc,26 n_hypotheses_tested, correction_method, oos_status27Required confidence.md content: a 'Level: <1|2|3>' line plus front matter.28"""2930from __future__ import annotations3132import argparse33import json34import re35import shutil36import sys37from pathlib import Path3839REPO_ROOT = Path(__file__).resolve().parent.parent4041PROVENANCE_KEYS = (42 "commit",43 "config",44 "data_manifest_hash",45 "hardware_manifest",46 "generated_utc",47 "n_hypotheses_tested",48 "correction_method",49 "oos_status",50)51FINDING_ATTRIBUTION = {52 "author": "Simon-Pierre Boucher",53 "contact": "contact@spboucher.ai",54 "data_source": "hfmarketdata.io",55}565758def fail(msg: str) -> None:59 sys.exit(f"REFUSED: {msg}")606162def validate_provenance(path: Path) -> dict:63 try:64 prov = json.loads(path.read_text())65 except (OSError, json.JSONDecodeError) as exc:66 fail(f"provenance.json unreadable/invalid: {exc}")67 missing = [k for k in PROVENANCE_KEYS if not prov.get(k)]68 if missing:69 fail(f"provenance.json incomplete — missing/empty: {', '.join(missing)}")70 return prov717273def validate_confidence(path: Path) -> int:74 try:75 text = path.read_text()76 except OSError as exc:77 fail(f"confidence.md unreadable: {exc}")78 m = re.search(r"^Level:\s*([0-3])\b", text, re.MULTILINE)79 if not m:80 fail("confidence.md must contain a 'Level: <0-3>' line with evidence")81 level = int(m.group(1))82 if level < 1:83 fail("Level 0 (in-sample only) never enters the atlas — scan output only")84 return level858687def main() -> None:88 ap = argparse.ArgumentParser(description=__doc__)89 ap.add_argument("anomaly_id")90 ap.add_argument("version")91 ap.add_argument("--finding", required=True, type=Path)92 ap.add_argument("--provenance", required=True, type=Path)93 ap.add_argument("--confidence", required=True, type=Path)94 args = ap.parse_args()9596 prov = validate_provenance(args.provenance)97 level = validate_confidence(args.confidence)98 try:99 finding = json.loads(args.finding.read_text())100 except (OSError, json.JSONDecodeError) as exc:101 fail(f"finding.json unreadable/invalid: {exc}")102103 finding.update(FINDING_ATTRIBUTION)104 finding.setdefault("anomaly_id", args.anomaly_id)105 finding["confidence_level"] = level106107 dest = REPO_ROOT / "atlas" / args.anomaly_id / args.version108 if dest.exists():109 fail(f"{dest.relative_to(REPO_ROOT)} already exists — bump the version")110 dest.mkdir(parents=True)111 (dest / "finding.json").write_text(json.dumps(finding, indent=2) + "\n")112 (dest / "provenance.json").write_text(json.dumps(prov, indent=2) + "\n")113 shutil.copy(args.confidence, dest / "confidence.md")114 print(f"atlas entry created: {dest.relative_to(REPO_ROOT)} (Level {level})")115116117if __name__ == "__main__":118 main()119