Complete 3axis tutorial native and Web/WASM parity tools
This commit is contained in:
135
scripts/generate_wasm_simulation_release_gate_t7.py
Normal file
135
scripts/generate_wasm_simulation_release_gate_t7.py
Normal file
@@ -0,0 +1,135 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Generate a read-only simulation release-gate audit for T7."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
OUTPUT = Path("coverage/wasm-simulation-release-gate-t7.report.json")
|
||||
CONTEXT = Path("context-lock.json")
|
||||
CONTEXT_ID = "linuxcnc-2.10.0-pre0-wasm-m1-py-c1"
|
||||
REQUIRED_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 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": hashlib.sha256(full.read_bytes()).hexdigest()}
|
||||
|
||||
|
||||
def load(root: Path, path: str) -> dict[str, Any]:
|
||||
return json.loads((root / path).read_text(encoding="utf-8"))
|
||||
|
||||
|
||||
def generate(root: Path, output: Path = OUTPUT) -> dict[str, Any]:
|
||||
root = root.resolve()
|
||||
lock = load(root, "context-lock.json")
|
||||
t6 = load(root, "coverage/wasm-function-closure-t6.report.json")
|
||||
t5 = load(root, "coverage/wasm-feature-matrix-t5.report.json")
|
||||
gate = load(root, "coverage/release-candidate-gate.report.json")
|
||||
acceptance = load(root, "coverage/full-case-acceptance-s8-10.report.json")
|
||||
roundup = load(root, "coverage/remediation-evidence-roundup.report.json")
|
||||
owner = load(root, "coverage/owner-review-gate-refresh.report.json")
|
||||
remediation = {
|
||||
"official_oracle": load(root, "coverage/official-oracle-remediation.report.json"),
|
||||
"configuration_resources": load(root, "coverage/configuration-resource-remediation.report.json"),
|
||||
"browser_matrix": load(root, "coverage/browser-matrix-remediation.report.json"),
|
||||
"implementation_license": load(root, "coverage/implementation-license-remediation.report.json"),
|
||||
}
|
||||
blocker_ids = {item.get("id") for item in gate.get("blockers", [])}
|
||||
evidence_reports = [gate, acceptance, roundup, owner, *remediation.values()]
|
||||
context_values = {item.get("context_id") for item in [t5, t6, acceptance, roundup, owner, *remediation.values()] if item.get("context_id")}
|
||||
inputs = [
|
||||
artifact(root, "context-lock.json", "context_lock"),
|
||||
artifact(root, "nextTask.md", "owner_pointer_read_only"),
|
||||
artifact(root, "coverage/wasm-function-closure-t6.report.json", "t6_closure"),
|
||||
artifact(root, "coverage/wasm-feature-matrix-t5.report.json", "t5_matrix"),
|
||||
artifact(root, "coverage/release-candidate-gate.report.json", "release_gate_read_only"),
|
||||
artifact(root, "coverage/full-case-acceptance-s8-10.report.json", "case_acceptance"),
|
||||
artifact(root, "coverage/remediation-evidence-roundup.report.json", "remediation_roundup"),
|
||||
artifact(root, "coverage/owner-review-gate-refresh.report.json", "owner_gate_read_only"),
|
||||
artifact(root, "coverage/official-oracle-remediation.report.json", "oracle_remediation"),
|
||||
artifact(root, "coverage/configuration-resource-remediation.report.json", "resource_remediation"),
|
||||
artifact(root, "coverage/browser-matrix-remediation.report.json", "browser_remediation"),
|
||||
artifact(root, "coverage/implementation-license-remediation.report.json", "license_remediation"),
|
||||
]
|
||||
checks = {
|
||||
"context_consistency": {"status": "verified" if lock.get("context_id") == CONTEXT_ID and context_values == {CONTEXT_ID} else "blocked", "context_id": lock.get("context_id")},
|
||||
"t6_dependency_recorded": {"status": "verified" if t6.get("task_id") == "T6-FUNCTION-CLOSURE-01" and t6.get("status") == "blocked" else "blocked", "closure_status": t6.get("status")},
|
||||
"candidate_not_eligible": {"status": "verified" if all(item.get("candidate_eligible") is False for item in evidence_reports if "candidate_eligible" in item) else "blocked"},
|
||||
"stop_release_preserved": {"status": "verified" if all(item.get("release_action") == "STOP_RELEASE" for item in evidence_reports if "release_action" in item) else "blocked", "release_action": gate.get("release_action")},
|
||||
"blocker_identity": {"status": "verified" if REQUIRED_BLOCKERS.issubset(blocker_ids) and set(roundup.get("checks", {}).get("blocker_identity_preserved", {}).get("ids", [])) == REQUIRED_BLOCKERS else "blocked", "ids": sorted(blocker_ids)},
|
||||
"owner_refresh_blocked": {"status": "verified" if owner.get("checks", {}).get("gate_refresh_allowed", {}).get("status") == "blocked" and owner.get("checks", {}).get("owner_inputs_present", {}).get("present") == 0 else "blocked"},
|
||||
"remediation_self_hashes": {"status": "verified" if roundup.get("checks", {}).get("remediation_report_self_hashes", {}).get("status") == "verified" else "blocked"},
|
||||
"gate_mutation_forbidden": {"status": "verified", "policy": "this report never writes release-candidate-gate, context-lock, manifest or owner decisions"},
|
||||
"input_closure": {"status": "verified" if all(item["status"] == "present" for item in inputs) else "blocked", "missing": [item["path"] for item in inputs if item["status"] != "present"]},
|
||||
}
|
||||
blockers = [
|
||||
{"id": "t6_function_closure_blocked", "status": "blocked", "reason": t6.get("stop_reason")},
|
||||
*[item for item in gate.get("blockers", []) if item.get("id") in REQUIRED_BLOCKERS],
|
||||
{"id": "owner_inputs_missing", "status": "blocked", "reason": "six owner decisions or a new reviewed context are absent"},
|
||||
]
|
||||
report: dict[str, Any] = {
|
||||
"schema": "wasm-simulation-release-gate-t7.v1",
|
||||
"status": "blocked",
|
||||
"implementation_status": "verified",
|
||||
"task_id": "T7-RELEASE-GATE-01",
|
||||
"context_id": lock.get("context_id"),
|
||||
"candidate_eligible": False,
|
||||
"release_action": "STOP_RELEASE",
|
||||
"scope": "simulation_track_read_only_audit",
|
||||
"gate_mutation": "forbidden",
|
||||
"inputs": inputs,
|
||||
"checks": checks,
|
||||
"blockers": blockers,
|
||||
"gate_snapshot": {"path": "coverage/release-candidate-gate.report.json", "status": gate.get("status"), "candidate_eligible": gate.get("candidate_eligible"), "release_action": gate.get("release_action"), "blocker_count": len(gate.get("blockers", []))},
|
||||
"failure_samples": [
|
||||
{"code": "t6_closure_blocked", "source": "coverage/wasm-function-closure-t6.report.json", "observed": t6.get("counts")},
|
||||
{"code": "owner_inputs_missing", "source": "coverage/owner-review-gate-refresh.report.json", "observed": {"present": owner.get("checks", {}).get("owner_inputs_present", {}).get("present"), "required": owner.get("checks", {}).get("owner_inputs_present", {}).get("required")}},
|
||||
{"code": "release_blocker_identity_preserved", "source": "coverage/release-candidate-gate.report.json", "observed": sorted(REQUIRED_BLOCKERS)},
|
||||
],
|
||||
"next_transition": "wait for approved owner/source/browser/resource inputs; do not auto-refresh K8 gate",
|
||||
"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"wasm_simulation_release_gate_t7={report['status']} blockers={len(report['blockers'])}")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user