import re, glob, os, yaml sys_ids = set(os.path.basename(f)[:-3] for f in glob.glob('context/*.md')) # glossary top-level keys = valid link targets too try: gl = yaml.safe_load(open('reference/glossary.yaml',encoding='utf-8')) gloss_keys = set(gl.keys()) if isinstance(gl, dict) else set() except Exception as e: gloss_keys = set(re.findall(r'^([A-Za-z][A-Za-z0-9_-]*):', open('reference/glossary.yaml',encoding='utf-8').read(), re.M)) valid = sys_ids | gloss_keys # template placeholders that are documentation, not real links: IGNORE = {'other-topic','other-topic-a','other-topic-b','topic-id','name'} print("topic ids:", len(sys_ids), "| glossary keys:", len(gloss_keys)) bad=0 for f in glob.glob('context/*.md') + ['CLAUDE.md']: txt=open(f,encoding='utf-8',errors='replace').read() for m in re.findall(r'\[\[([a-z0-9-]+)\]\]', txt): if m not in valid and m not in IGNORE: print(f" UNRESOLVED [[{m}]] in {f}"); bad+=1 cl=open('CLAUDE.md',encoding='utf-8',errors='replace').read() for m in re.findall(r'`(context/[a-z0-9-]+\.md)`', cl): if not os.path.exists(m): print(f" MISSING quick-lookup {m}"); bad+=1 for m in re.findall(r'`(docs/[A-Z0-9_]+\.md)`', cl): if not os.path.exists(m): print(f" MISSING docs ref {m}"); bad+=1 print("RESULT:", "CLEAN" if bad==0 else f"{bad} unresolved")