37 lines
2.2 KiB
Python
37 lines
2.2 KiB
Python
#!/usr/bin/env python3
|
|
import hashlib
|
|
import json
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
manifest_path = ROOT / "docs/p6/python-api-manifest.json"
|
|
manifest = json.loads(manifest_path.read_text())
|
|
records = manifest["records"]
|
|
tier4 = [row for row in records if row["tier"] == "tier-4-restricted"]
|
|
disposition_counts = {
|
|
disposition: sum(row["disposition"] == disposition for row in tier4)
|
|
for disposition in ("restricted", "nonportable")
|
|
}
|
|
valid = (
|
|
len(records) == 13385
|
|
and len(tier4) == 63
|
|
and all(row["disposition"] in {"restricted", "nonportable"} for row in tier4)
|
|
and all(row.get("dispositionReason") for row in tier4)
|
|
and all(row.get("evidence", {}).get("path") for row in tier4)
|
|
)
|
|
report = {
|
|
"schema": "freecad-web-p6-python-api-restricted-gate/v1",
|
|
"taskId": "FW-P6-FPA-F4",
|
|
"result": "pass" if valid else "fail",
|
|
"coverage": {"inventoryRecords": len(records), "tier4Records": len(tier4), "dispositionCounts": disposition_counts, "plannedTier4Records": sum(row["disposition"] == "planned" for row in tier4)},
|
|
"policy": {"allowedDispositions": ["restricted", "nonportable"], "reasonRequired": True, "sourceEvidenceRequired": True, "arbitraryExecution": False},
|
|
"manifest": {"path": "docs/p6/python-api-manifest.json", "sha256": hashlib.sha256(manifest_path.read_bytes()).hexdigest()},
|
|
"records": [{"id": row["id"], "module": row["module"], "name": row["name"], "disposition": row["disposition"], "reason": row["dispositionReason"], "source": row["evidence"]} for row in tier4],
|
|
"boundaries": ["Restricted means the source symbol is tracked but not exposed as arbitrary Web execution.", "GUI/PySide/Pivy/desktop capabilities require a separate portable implementation before any exposed disposition."],
|
|
}
|
|
out = ROOT / "docs/p6/python-api-restricted-gate.json"
|
|
out.write_text(json.dumps(report, ensure_ascii=False, indent=2) + "\n")
|
|
(ROOT / "docs/freecad-p6-python-api-restricted-gate.log").write_text(json.dumps({"result": report["result"], "tier4": len(tier4), "dispositionCounts": disposition_counts}) + "\n")
|
|
print(json.dumps({"result": report["result"], "tier4": len(tier4), "dispositionCounts": disposition_counts}))
|
|
raise SystemExit(0 if valid else 1)
|