#!/usr/bin/env python3 """Generate/refresh the vault topology manifest note (source of truth for both trees).""" import os, json, sys, datetime sys.path.insert(0, os.path.dirname(os.path.realpath(__file__))) import vault_lib as vl def render(manifest): ts = datetime.date.today().isoformat() c = manifest["counts"] lines = [] lines.append("---") lines.append("tags: [meta, topology, jdex]") lines.append("generated: " + ts) lines.append("---") lines.append("# 00.05 Vault topology (machine-readable)") lines.append("") lines.append("> [!info] Source of truth") lines.append("> This note is the **authoritative topology** for the R/J/F/I vault. It is") lines.append("> regenerated from the live `/vault` structure by `vault-topology.py` and is") lines.append("> what the `vault` CLI and the nightly Librarian reconcile **both** `/vault`") lines.append("> (the JDex/map) and `/data` (blob territory) against. Do not hand-edit the") lines.append("> JSON block below — change the vault via the `vault` CLI and regenerate.") lines.append("") lines.append(f"**Live counts:** {c['systems']} systems · {c['areas']} areas · " f"{c['categories']} categories · {c['ids']} IDs") lines.append("") lines.append("## Systems") for k, v in manifest["systems"].items(): lines.append(f"- **{k}** — {v}") lines.append("") lines.append("## Categories by system") # group categories under systems by_sys = {} for code, name in manifest["categories"].items(): by_sys.setdefault(code[0], []).append((code, name)) for s in sorted(by_sys): lines.append(f"### {s}") for code, name in sorted(by_sys[s]): n_ids = sum(1 for idc in manifest["ids"] if idc.startswith(code + ".")) lines.append(f"- `{code}` {name.split(' ',1)[1] if ' ' in name else name} — {n_ids} IDs") lines.append("") lines.append("## Machine-readable topology") lines.append("") lines.append(vl.MANIFEST_BEGIN) lines.append("```json") lines.append(json.dumps(manifest, indent=2, ensure_ascii=False)) lines.append("```") lines.append(vl.MANIFEST_END) lines.append("") return "\n".join(lines) def main(): manifest = vl.build_manifest() content = render(manifest) dest = os.path.join(vl.VAULT, vl.MANIFEST_REL) os.makedirs(os.path.dirname(dest), exist_ok=True) dry = "--execute" not in sys.argv if dry: print("DRY-RUN. Would write manifest to:") print(" " + dest) print(f" ({manifest['counts']})") print("--- preview (first 40 lines) ---") print("\n".join(content.splitlines()[:40])) else: with open(dest, "w", encoding="utf-8") as f: f.write(content) print("WROTE " + dest) print(f" {manifest['counts']}") if __name__ == "__main__": main()