Files
Claro/tools/validate_documentation_status.py
Hermes Agent ed23524817 fix: harden Claro diagnostics and runtime guards
Preserve source locations, validate malformed JSON, and add opt-in resource limits. Include executable error-guide coverage, learner pilot materials, native Windows acceptance helpers, and updated CI/documentation.
2026-10-25 02:42:53 +00:00

67 lines
3.5 KiB
Python

#!/usr/bin/env python3
"""Check active status/navigation without treating historical claims as current."""
import ast
from pathlib import Path
import re
from urllib.parse import unquote, urlsplit
ROOT = Path(__file__).resolve().parents[1]
ACTIVE = (
'README.md', 'docs/README.md', 'docs/CURRENT_STATUS.md',
'docs/RELEASE_STATUS.md', 'docs/FINAL_RELEASE_CHECKLIST.md',
'docs/CLASSROOM_READINESS.md', 'docs/TESTING.md', 'docs/HARDENING.md',
'docs/PORTABILITY.md', 'docs/RELIABILITY.md',
'docs/ERRORS.md', 'docs/RUNTIME_LIMITS.md', 'docs/LEARNER_PILOT.md',
'docs/LEARNER_FEEDBACK_TEMPLATE.md', 'docs/NATIVE_WINDOWS_TESTING.md',
'docs/SIX_TRACK_STATUS.md',
'docs/history/CURRENT_STATUS_BEFORE_STATUS_CLEANUP.md',
'docs/history/HARDENING_BEFORE_STATUS_CLEANUP.md',
)
def validate():
match = re.search(r'#define CLARO_VERSION "Claro ([^"]+)"',
(ROOT / 'src/claro.c').read_text())
assert match, 'Missing runtime version'
version = match.group(1)
readme = (ROOT / 'README.md').read_text()
assert 'Current release:' not in readme, 'A development stamp is not a published release'
assert f'Development version: **{version}**' in readme, 'README must match the runtime development stamp'
status = (ROOT / 'docs/CURRENT_STATUS.md').read_text()
assert version in status and 'RELEASE_STATUS.md' in status
assert len(status.splitlines()) <= 100, 'Keep the current status concise; archive detailed history'
assert 'not a sandbox' in status.lower()
release = (ROOT / 'docs/RELEASE_STATUS.md').read_text()
assert 'not published' in release.lower() and 'wine' in release.lower()
assert 'unverified' in release.lower() and 'MSVC600' in release
checklist = (ROOT / 'docs/FINAL_RELEASE_CHECKLIST.md').read_text()
assert 'v1.xx.yy' not in checklist and 'vYYYY.MM.DD.HHMMSS' in checklist
assert '[ ]' in checklist, 'Release actions must be explicit, unchecked gates'
classroom = (ROOT / 'docs/CLASSROOM_READINESS.md').read_text().lower()
assert 'learner testing' in classroom and 'not yet validated' in classroom
hardening = (ROOT / 'docs/HARDENING.md').read_text()
assert 'historical' in hardening.lower() and 'RELIABILITY.md' in hardening
for name in ['CURRENT_STATUS_BEFORE_STATUS_CLEANUP.md', 'HARDENING_BEFORE_STATUS_CLEANUP.md']:
assert (ROOT / 'docs/history' / name).is_file(), ('Missing historical record', name)
tree = ast.parse((ROOT / 'tools/stamp_version.py').read_text())
current_docs = next(ast.literal_eval(n.value) for n in tree.body
if isinstance(n, ast.Assign) and any(isinstance(t, ast.Name) and t.id == 'CURRENT_DOCS' for t in n.targets))
assert 'RELEASE_STATUS.md' not in current_docs, 'Do not re-stamp immutable verification checkpoints'
checked = 0
for name in ACTIVE:
path = ROOT / name
text = re.sub(r'```.*?```', '', path.read_text(), flags=re.S)
for target in re.findall(r'!?\[[^\]]*\]\(([^\s)]+)\)', text):
url = urlsplit(target)
if url.scheme or url.netloc or not url.path:
continue
destination = (path.parent / unquote(url.path)).resolve()
assert destination.is_relative_to(ROOT), (name, 'Link leaves the repository', target)
assert destination.exists(), (name, 'Broken local link', target)
checked += 1
print(f'PASS: development/release separation, archived history, claim scope, and {checked} local documentation links')
if __name__ == '__main__':
validate()