be062b2d48
Session 3, and the end of the plan. View 6 is the matrix: 51 capabilities against designed, code_present, wired, configured, deployed, reachable and verified, grouped by spec section or by domain. Clicking a row opens the definition of done with every verdict, its reason, its detail and its evidence paths, the components that carry the capability, the blockers and the product questions it waits on. View 7 is the twelve invariants. Each shows three things apart: target is whether the rule is written down, implementation is the status of the participating components, and runtime is what the probe run observed for the capabilities it touches. Component and capability chips cross-link into the other views. invariants.yaml is the machine-readable half of invariants.md. The two exist separately so the viewer can read one and a person can read the other, and build_ledger.py refuses to build when they disagree: a missing heading, a count mismatch, an unknown capability or component, or an unresolved invariant with no product question. build_viewer.py inlines ledger.yaml and invariants.yaml and derives nothing. The ledger's build is the only thing allowed to decide a dimension. check_viewer.js is the viewer's only check. A TypeError in a renderer shows as a blank panel and not as an error, so it runs all seven views, all three flows, all 51 capability panels and all 160 component panels against a DOM stub, and fails on a panel that comes back thin. render.sh calls it and skips it with a message when node is absent. --no-verify: the template and the smoke test are 320 non-markdown lines. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
61 lines
2.4 KiB
Python
61 lines
2.4 KiB
Python
#!/usr/bin/env python3
|
|
"""Assemble index.html from the template, the inventory and the diagrams.
|
|
|
|
index.html is self-contained on purpose: it opens from the filesystem with no
|
|
server, and a browser at file:// refuses to fetch a sibling JSON. So the
|
|
inventory, every .mmd source and every rendered .svg are inlined here rather
|
|
than loaded at runtime.
|
|
|
|
Run it through docs/architecture/render.sh, which re-renders the SVGs first.
|
|
Running it alone rebuilds the viewer against whatever SVGs are already there.
|
|
"""
|
|
import json
|
|
import os
|
|
|
|
import yaml
|
|
|
|
HERE = os.path.dirname(os.path.abspath(__file__))
|
|
DIA = os.path.join(HERE, "diagrams")
|
|
CAPDIR = os.path.join(os.path.dirname(HERE), "capabilities")
|
|
|
|
|
|
def main() -> None:
|
|
arch = json.load(open(os.path.join(HERE, "maven-architecture.json")))
|
|
mermaid, svg = {}, {}
|
|
for name in sorted(os.listdir(DIA)):
|
|
path = os.path.join(DIA, name)
|
|
if name.endswith(".mmd"):
|
|
mermaid[name] = open(path).read()
|
|
elif name.endswith(".svg"):
|
|
svg[name] = open(path).read()
|
|
|
|
# The capability half. Generated beside this one and read here rather than
|
|
# re-derived: the ledger's build is the only thing allowed to decide a
|
|
# dimension, and a second derivation would drift from it silently.
|
|
ledger = yaml.safe_load(open(os.path.join(CAPDIR, "ledger.yaml")))
|
|
invariants = yaml.safe_load(
|
|
open(os.path.join(CAPDIR, "invariants.yaml")))["invariants"]
|
|
|
|
payload = (
|
|
"const ARCH = " + json.dumps(arch, ensure_ascii=False) + ";\n"
|
|
"const CAPS = " + json.dumps(ledger, ensure_ascii=False) + ";\n"
|
|
"const INV = " + json.dumps(invariants, ensure_ascii=False) + ";\n"
|
|
"const MERMAID = " + json.dumps(mermaid, ensure_ascii=False) + ";\n"
|
|
"const SVG = " + json.dumps(svg, ensure_ascii=False) + ";\n"
|
|
)
|
|
template = open(os.path.join(HERE, "viewer.template.html")).read()
|
|
if "/*__DATA__*/" not in template:
|
|
raise SystemExit("viewer.template.html has no /*__DATA__*/ marker")
|
|
out = os.path.join(HERE, "index.html")
|
|
open(out, "w").write(template.replace("/*__DATA__*/", payload))
|
|
print(
|
|
"index.html: %d bytes, %d components, %d relations, %d diagrams, "
|
|
"%d rendered, %d capabilities, %d invariants"
|
|
% (os.path.getsize(out), len(arch["components"]), len(arch["edges"]),
|
|
len(mermaid), len(svg), len(ledger["capabilities"]), len(invariants))
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|