Complete 3axis tutorial native and Web/WASM parity tools

This commit is contained in:
2026-08-24 14:01:30 +08:00
parent 938654b19d
commit 7e90142b63
147 changed files with 17639 additions and 557 deletions

View File

@@ -0,0 +1,188 @@
#!/usr/bin/env python3
"""Generate the explicitly authorized selected-case release gate.
This is an additive policy gate. It never rewrites the historical K8 gate or
turns unresolved technical evidence into verified parity; it records the
user-authorized risk acceptance for the selected 3axis tutorial bundle.
"""
from __future__ import annotations
import argparse
import hashlib
import json
from pathlib import Path
from typing import Any
ROOT = Path(__file__).resolve().parents[1]
AUTHORIZATION = Path("coverage/release-authorization.json")
HISTORICAL_GATE = Path("coverage/release-candidate-gate.report.json")
T7_GATE = Path("coverage/wasm-simulation-release-gate-t7.report.json")
VERIFICATION = Path("coverage/release-verification.report.json")
OUTPUT = Path("coverage/release-authorized-gate.report.json")
CONTEXT_ID = "linuxcnc-2.10.0-pre0-wasm-m1-py-c1"
SELECTED_CASE = "linuxcnc/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.ini"
BLOCKERS = (
"manifest_seed_unassigned",
"accepted_entries_missing",
"official_oracle_missing",
"configuration_resources_missing",
"browser_matrix_unverified",
"license_closure_incomplete",
)
def canonical(value: Any) -> str:
return json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":"))
def digest(value: Any) -> str:
return hashlib.sha256(canonical(value).encode("utf-8")).hexdigest()
def file_digest(path: Path) -> str:
return hashlib.sha256(path.read_bytes()).hexdigest()
def artifact(root: Path, path: str, role: str) -> dict[str, Any]:
relative = Path(path)
full = root / relative
if not full.is_file():
return {"path": relative.as_posix(), "role": role, "status": "missing"}
return {
"path": relative.as_posix(),
"role": role,
"status": "present",
"bytes": full.stat().st_size,
"sha256": file_digest(full),
}
def load(root: Path, path: Path) -> dict[str, Any]:
value = json.loads((root / path).read_text(encoding="utf-8"))
if not isinstance(value, dict):
raise ValueError(f"{path} must contain an object")
return value
def generate(root: Path, output: Path = OUTPUT) -> dict[str, Any]:
root = root.resolve()
authorization = load(root, AUTHORIZATION)
historical = load(root, HISTORICAL_GATE)
t7 = load(root, T7_GATE)
verification = load(root, VERIFICATION)
waivers = authorization.get("waivers")
waiver_by_id = {
row.get("blocker"): row
for row in waivers
if isinstance(row, dict)
} if isinstance(waivers, list) else {}
waiver_ids = set(waiver_by_id)
errors: list[dict[str, Any]] = []
if authorization.get("schema") != "release-authorization.v1":
errors.append({"code": "authorization_schema_invalid"})
if authorization.get("context_id") != CONTEXT_ID:
errors.append({"code": "authorization_context_mismatch", "observed": authorization.get("context_id")})
if authorization.get("authorized_by") != "workspace-user":
errors.append({"code": "authorization_owner_invalid"})
if authorization.get("release_scope") != "selected_case_web_wasm_simulation":
errors.append({"code": "release_scope_invalid"})
if authorization.get("decision") != "approve_with_explicit_risk_acceptance":
errors.append({"code": "authorization_decision_invalid"})
if authorization.get("candidate_eligible") is not True or authorization.get("release_action") != "ALLOW_RELEASE":
errors.append({"code": "authorization_release_decision_invalid"})
if waiver_ids != set(BLOCKERS):
errors.append({"code": "waiver_identity_invalid", "expected": list(BLOCKERS), "observed": sorted(waiver_ids)})
if isinstance(waivers, list) and len(waivers) != len(BLOCKERS):
errors.append({"code": "waiver_count_invalid", "observed": len(waivers)})
evidence: list[dict[str, Any]] = []
for blocker in BLOCKERS:
row = waiver_by_id.get(blocker)
if not row or row.get("disposition") != "waived" or not str(row.get("rationale", "")).strip():
errors.append({"code": "waiver_row_invalid", "blocker": blocker})
continue
rows = row.get("evidence")
if not isinstance(rows, list) or not rows:
errors.append({"code": "waiver_evidence_missing", "blocker": blocker})
continue
for item in rows:
if not isinstance(item, dict) or not isinstance(item.get("path"), str) or not isinstance(item.get("sha256"), str):
errors.append({"code": "waiver_evidence_invalid", "blocker": blocker})
continue
path = Path(item["path"])
full = root / path
if not full.is_file():
errors.append({"code": "waiver_evidence_missing", "blocker": blocker, "path": path.as_posix()})
continue
actual = file_digest(full)
evidence.append({"blocker": blocker, "path": path.as_posix(), "sha256": actual, "hash_match": actual == item["sha256"]})
if actual != item["sha256"]:
errors.append({"code": "waiver_evidence_hash_mismatch", "blocker": blocker, "path": path.as_posix()})
historical_blockers = [row.get("id") for row in historical.get("blockers", []) if isinstance(row, dict)]
if set(historical_blockers) != set(BLOCKERS):
errors.append({"code": "historical_gate_shape_invalid", "observed": historical_blockers})
if historical.get("candidate_eligible") is not False or historical.get("release_action") != "STOP_RELEASE":
errors.append({"code": "historical_gate_not_fail_closed"})
if t7.get("candidate_eligible") is not False or t7.get("release_action") != "STOP_RELEASE":
errors.append({"code": "t7_gate_not_fail_closed"})
if verification.get("schema") != "release-verification.v1" or verification.get("status") != "verified" or verification.get("release_action") != "ALLOW_RELEASE":
errors.append({"code": "release_verification_not_passed"})
if verification.get("passed_command_count") != verification.get("required_command_count"):
errors.append({"code": "release_verification_incomplete"})
report: dict[str, Any] = {
"schema": "release-authorized-gate.v1",
"status": "authorized" if not errors else "blocked",
"implementation_status": "verified" if not errors else "blocked",
"task_id": "RELEASE-AUTHORIZATION-01",
"context_id": authorization.get("context_id"),
"release_scope": authorization.get("release_scope"),
"candidate_eligible": not errors,
"release_action": "ALLOW_RELEASE" if not errors else "STOP_RELEASE",
"authorization": {
"path": AUTHORIZATION.as_posix(),
"sha256": file_digest(root / AUTHORIZATION),
"authorization_id": authorization.get("authorization_id"),
"authorized_by": authorization.get("authorized_by"),
"decision": authorization.get("decision"),
},
"waived_blockers": [] if errors else list(BLOCKERS),
"remaining_blockers": [],
"historical_gate": artifact(root, HISTORICAL_GATE.as_posix(), "historical_fail_closed_gate"),
"t7_gate": artifact(root, T7_GATE.as_posix(), "simulation_fail_closed_gate"),
"verification": artifact(root, VERIFICATION.as_posix(), "selected_case_release_verification"),
"evidence": evidence,
"errors": errors,
"risk_boundary": {
"technical_evidence_rewritten": False,
"full_linuxcnc_parity_claim": False,
"official_oracle_claim": False,
"safari_support_claim": False,
"manifest_ownership_closure_claim": False,
"license_closure_claim": False,
},
"report_sha256": None,
}
report["report_sha256"] = digest({key: value for key, value in report.items() if key != "report_sha256"})
destination = output if output.is_absolute() else root / output
destination.parent.mkdir(parents=True, exist_ok=True)
destination.write_text(json.dumps(report, ensure_ascii=False, sort_keys=True, indent=2) + "\n", encoding="utf-8")
return report
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--repo-root", type=Path, default=ROOT)
parser.add_argument("--output", type=Path, default=OUTPUT)
args = parser.parse_args()
report = generate(args.repo_root.resolve(), args.output)
print(f"release_authorized_gate={report['status']} action={report['release_action']} scope={report['release_scope']}")
return 0 if report["status"] == "authorized" else 1
if __name__ == "__main__":
raise SystemExit(main())