#!/usr/bin/env python3 # ============================================================================= # Project : modelmap # File : tools/publish.py # Purpose : Export validated atlas entries to site/data — refuses incomplete # Author : Simon-Pierre Boucher # Contact : contact@spboucher.ai # Website : https://modelmap.io # Created : 2026-08-12 # Modified : 2026-08-12 # Platform : macOS / Apple Silicon (arm64) # License : All rights reserved (research code) # ============================================================================= """Publish gate for the atlas (charter §14 hard constraints). Walks atlas////, validates each entry's mapcard.json (schema v0) plus the presence of provenance.json and confidence.md, and exports valid entries to site/data/atlas-index.json. Any violation blocks that entry and is reported; nothing incomplete ever reaches modelmap.io. """ from __future__ import annotations import json import sys from pathlib import Path ROOT = Path(__file__).resolve().parent.parent sys.path.insert(0, str(ROOT / "src")) from modelmap.atlas.mapcard import MapCard def entries(): atlas = ROOT / "atlas" for model in sorted(p for p in atlas.iterdir() if p.is_dir()): for map_type in sorted(p for p in model.iterdir() if p.is_dir()): yield from sorted(p for p in map_type.iterdir() if p.is_dir()) def main() -> int: exported, blocked = [], [] for entry in entries(): rel = entry.relative_to(ROOT) problems = [] for required in ("provenance.json", "confidence.md", "mapcard.json"): if not (entry / required).exists(): problems.append(f"missing {required}") card = None if not problems: try: card = MapCard.load(entry / "mapcard.json") problems += card.validate() except (json.JSONDecodeError, TypeError) as e: problems.append(f"mapcard.json unreadable: {e}") if problems: blocked.append((str(rel), problems)) else: exported.append({ "path": str(rel), "map_id": card.map_id, "map_type": card.map_type, "model_id": card.model_id, "quantization": card.quantization, "confidence_level": card.confidence_level, "replication_rate": card.replication_rate, "negative_result": card.negative_result, "created": card.created, }) out = ROOT / "site" / "data" out.mkdir(parents=True, exist_ok=True) (out / "atlas-index.json").write_text(json.dumps({ "author": "Simon-Pierre Boucher", "contact": "contact@spboucher.ai", "website": "https://modelmap.io", "entries": exported, }, indent=2) + "\n") print(f"publish: {len(exported)} entry(ies) exported to site/data/atlas-index.json") for rel, problems in blocked: print(f"BLOCKED {rel}:") for p in problems: print(f" - {p}") return 1 if blocked else 0 if __name__ == "__main__": sys.exit(main())