tlm-jxcl-forge / tools /gen_dependency_graph.py
SNAPKITTYWEST's picture
October 2026 main drop: mirror from GitHub (part 3)
99d3d5f verified
Raw History Blame Contribute Delete
3.37 kB
#!/usr/bin/env python3
"""Regenerates docs/DEPENDENCY_GRAPH.md from docs/crates.toml.
Keeps the dependency-graph documentation from drifting out of sync
with the registry it's supposed to describe -- run this instead of
hand-editing docs/DEPENDENCY_GRAPH.md whenever docs/crates.toml changes.
"""
import tomllib
from collections import defaultdict
from pathlib import Path
REPO_ROOT = Path(__file__).resolve().parent.parent
CAT_ORDER = [
"foundation", "isa", "execution", "memory", "toolchain", "debug",
"hardware", "crypto", "storage", "proof", "network", "security",
]
CAT_TITLE = {
"foundation": "Foundation", "isa": "ISA", "execution": "Execution",
"memory": "Memory", "toolchain": "Binary/Toolchain",
"debug": "Debug/Simulation", "hardware": "Hardware/RTL",
"crypto": "Cryptography", "storage": "Storage/Data",
"proof": "Zero-Knowledge/Proof", "network": "Network/Service",
"security": "Security/Observability/Integration",
}
LAYERING_DIAGRAM = """## Layering (high level)
```
applications
(jxcl-cli, photo-cache-service)
|
services
(jxcl-service, jxcl-rpc, jxcl-integration)
|
integration / runtime
(jxcl-simulator, jxcl-protocol, jxcl-runtime)
|
crypto / storage / proof / network primitives
(pq-*, jxcl-network, jxcl-http -- isolated from ISA internals)
|
ISA / execution kernel
(jxcl-execution, jxcl-memory, jxcl-assembler, jxcl-hardware, ...)
|
primitives
(jxcl-types, jxcl-errors, jxcl-bitops, jxcl-endian, ...)
```
Enforced mechanically: no crate in `foundation`, `isa`, `execution`,
`memory`, `toolchain`, `debug`, or `hardware` may depend on a crate in
`storage` or `network` (`tools/check_workspace.py`'s
`check_forbidden_edges`). Crypto/proof crates depend only on
`std` + audited crates.io crates, never on service-layer crates.
"""
def main():
data = tomllib.loads((REPO_ROOT / "docs" / "crates.toml").read_text())
crates = data["crate"]
by_cat = defaultdict(list)
for c in crates:
by_cat[c["category"]].append(c)
lines = [
"# Dependency Graph\n",
"Generated from `docs/crates.toml` -- do not hand-edit; regenerate with",
"`python3 tools/gen_dependency_graph.py` if the registry changes.\n",
"Validated acyclic and free of forbidden ISA-to-storage/network edges by",
"`tools/check_workspace.py` (see its output in `docs/BUILD_MATRIX.md`).\n",
]
for cat in CAT_ORDER:
lines.append(f"## {CAT_TITLE[cat]} ({len(by_cat[cat])})\n")
lines.append("| Crate | Depends on | External deps |")
lines.append("|---|---|---|")
for c in sorted(by_cat[cat], key=lambda x: x["name"]):
deps = ", ".join(f"`{d}`" for d in c.get("dependencies", [])) or "*(none)*"
ext = ", ".join(f"`{d}`" for d in c.get("external_dependencies", [])) or "*(none)*"
lines.append(f"| `{c['name']}` | {deps} | {ext} |")
lines.append("")
lines.append(LAYERING_DIAGRAM)
(REPO_ROOT / "docs" / "DEPENDENCY_GRAPH.md").write_text("\n".join(lines))
print(f"wrote docs/DEPENDENCY_GRAPH.md, {len(lines)} lines")
if __name__ == "__main__":
main()