121 lines
4.8 KiB
Python
121 lines
4.8 KiB
Python
#!/usr/bin/env python3
|
|
"""Materialize the enterprise four-domain portal template without private context."""
|
|
|
|
import argparse
|
|
import hashlib
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
import tempfile
|
|
|
|
EXPECTED_DOMAINS = {"DOMAIN-MAIN", "DOMAIN-SUB", "DOMAIN-ZERO", "DOMAIN-ZS"}
|
|
ALLOWED_TOP = {
|
|
"schema", "lifecycle", "system_id", "language_protocols", "carrier",
|
|
"embedded_in_hololake", "reality_controller", "responsible_human_members",
|
|
"persona_controller", "number_namespace", "domains", "execution", "privacy",
|
|
"fifth_domain", "hololake",
|
|
}
|
|
|
|
|
|
def canonical(value):
|
|
return (json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":")) + "\n").encode()
|
|
|
|
|
|
def digest(data):
|
|
return hashlib.sha256(data).hexdigest()
|
|
|
|
|
|
def load(path):
|
|
if path.is_symlink() or not path.is_file() or path.stat().st_size > 1024 * 1024:
|
|
raise ValueError("regular bounded template required")
|
|
return json.loads(path.read_text())
|
|
|
|
|
|
def validate(value):
|
|
if value.get("schema") != "hololake.enterprise-four-domain-governance-template/v2":
|
|
raise ValueError("unsupported enterprise template")
|
|
if set(value) != ALLOWED_TOP:
|
|
raise ValueError("public template has unknown or missing top-level fields")
|
|
ids = [item.get("id") for item in value.get("domains", [])]
|
|
if len(ids) != 4 or set(ids) != EXPECTED_DOMAINS:
|
|
raise ValueError("exactly four canonical public domains required")
|
|
if value.get("carrier") != "ENTERPRISE_PORTAL" or value.get("embedded_in_hololake") is not False:
|
|
raise ValueError("enterprise domains must not be embedded in HoloLake")
|
|
if value.get("reality_controller") != "GUANGHU_TEAM":
|
|
raise ValueError("Guanghu Team reality controller required")
|
|
if any(item.get("reality_controller") != "GUANGHU_TEAM" for item in value["domains"]):
|
|
raise ValueError("domain reality responsibility mismatch")
|
|
if next(item for item in value["domains"] if item["id"] == "DOMAIN-ZS").get("public_access") is not False:
|
|
raise ValueError("Zero-Sense Domain must remain restricted")
|
|
raw = canonical(value).decode()
|
|
if any(marker in raw for marker in ("ICE-", "ZCODE-", "/Volumes/", "/Users/")):
|
|
raise ValueError("private namespace or host path rejected")
|
|
|
|
|
|
def write(path, data):
|
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
with tempfile.NamedTemporaryFile(dir=path.parent, prefix=".public-world-", delete=False) as handle:
|
|
handle.write(data)
|
|
handle.flush()
|
|
os.fsync(handle.fileno())
|
|
temporary = Path(handle.name)
|
|
temporary.replace(path)
|
|
|
|
|
|
def build(template_path, output):
|
|
value = load(template_path)
|
|
validate(value)
|
|
if output.exists() and any(output.iterdir()):
|
|
raise ValueError("output directory must be absent or empty")
|
|
output.mkdir(parents=True, exist_ok=True)
|
|
files = {}
|
|
world = {
|
|
"schema": "hololake.materialized-language-world/v1",
|
|
"flavor": "enterprise-four-domain",
|
|
"source_sha256": digest(canonical(value)),
|
|
"node_ids": [item["id"] for item in value["domains"]],
|
|
"language_protocols": value["language_protocols"],
|
|
}
|
|
write(output / "WORLD.json", canonical(world))
|
|
files["WORLD.json"] = digest((output / "WORLD.json").read_bytes())
|
|
for item in value["domains"]:
|
|
path = output / item["id"].lower() / "NODE.json"
|
|
write(path, canonical(item))
|
|
files[str(path.relative_to(output))] = digest(path.read_bytes())
|
|
receipt = {
|
|
"schema": "hololake.language-system-materialization-receipt/v1",
|
|
"outcome": "PASS",
|
|
"flavor": "enterprise-four-domain",
|
|
"source_sha256": digest(canonical(value)),
|
|
"files": files,
|
|
"model_api_used": False,
|
|
"network_used": False,
|
|
}
|
|
write(output / "RECEIPT.json", canonical(receipt))
|
|
return receipt
|
|
|
|
|
|
def verify(root):
|
|
receipt = load(root / "RECEIPT.json")
|
|
for relative, expected in receipt.get("files", {}).items():
|
|
path = root / relative
|
|
if path.is_symlink() or not path.is_file() or digest(path.read_bytes()) != expected:
|
|
raise ValueError("public output hash mismatch")
|
|
return {"outcome": "PASS", "files_verified": len(receipt["files"])}
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser()
|
|
sub = parser.add_subparsers(dest="command", required=True)
|
|
build_parser = sub.add_parser("build")
|
|
build_parser.add_argument("--template", required=True, type=Path)
|
|
build_parser.add_argument("--output", required=True, type=Path)
|
|
verify_parser = sub.add_parser("verify")
|
|
verify_parser.add_argument("--root", required=True, type=Path)
|
|
args = parser.parse_args()
|
|
result = build(args.template, args.output) if args.command == "build" else verify(args.root)
|
|
print(json.dumps(result, ensure_ascii=False, sort_keys=True))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|