from __future__ import annotations import json from html.parser import HTMLParser from pathlib import Path from urllib.parse import urlparse SITE_ROOT = Path(__file__).parents[1] / "docs" / "site" ALLOWED_STATUSES = {"baseline", "validated", "backlog"} class SiteParser(HTMLParser): def __init__(self) -> None: super().__init__() self.ids: set[str] = set() self.references: list[str] = [] def handle_starttag(self, tag: str, attrs: list[tuple[str, str | None]]) -> None: values = dict(attrs) if values.get("id"): self.ids.add(values["id"]) attribute = "href" if tag in {"a", "link"} else "src" if tag in {"script", "img"} else None if attribute and values.get(attribute): self.references.append(values[attribute]) def _parser() -> SiteParser: parser = SiteParser() parser.feed((SITE_ROOT / "index.html").read_text()) return parser def test_docs_site_required_files_are_present() -> None: for relative_path in ("index.html", "styles.css", "app.js", "experiments.json", "og.png"): path = SITE_ROOT / relative_path assert path.is_file(), relative_path assert path.stat().st_size > 0, relative_path assert (SITE_ROOT / "og.png").read_bytes().startswith(b"\x89PNG\r\n\x1a\n") def test_docs_site_local_links_and_anchors_resolve() -> None: parser = _parser() for reference in parser.references: if reference.startswith("#"): assert reference[1:] in parser.ids, reference continue parsed = urlparse(reference) if parsed.scheme or parsed.netloc or reference.startswith("/"): continue if reference == "../static/favicon.svg": continue local_path = (SITE_ROOT / parsed.path).resolve() assert local_path.is_relative_to(SITE_ROOT.resolve()), reference assert local_path.is_file(), reference def test_docs_site_navigation_targets_every_top_level_section() -> None: parser = _parser() html = (SITE_ROOT / "index.html").read_text() expected_sections = { "overview", "architecture", "agent-loop", "workspace", "models", "experiments", "operations", "timeline", "repository", } assert expected_sections <= parser.ids for section_id in expected_sections: assert f'href="#{section_id}"' in html def test_experiment_ledger_has_unique_stable_records() -> None: experiments = json.loads((SITE_ROOT / "experiments.json").read_text()) assert len(experiments) >= 5 ids = [item["id"] for item in experiments] assert len(ids) == len(set(ids)) for item in experiments: assert item["status"] in ALLOWED_STATUSES assert item["title"].strip() assert item["summary"].strip() assert item["area"].strip() assert item["version"].strip() assert isinstance(item["metrics"], list)