Initialize repository snapshot
This commit is contained in:
123
tools/check_sentinel_contract_parity.py
Normal file
123
tools/check_sentinel_contract_parity.py
Normal file
@@ -0,0 +1,123 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
check_sentinel_contract_parity.py
|
||||
|
||||
Ensures Sentinel v1 contracts (docs) and verifier implementation stay aligned:
|
||||
- Every FailureCode is referenced by the verifier implementation.
|
||||
- Every FailureCode is referenced by the contract matrix.
|
||||
- The contract matrix does not reference unknown E_/W_ codes.
|
||||
|
||||
Usage:
|
||||
python3 tools/check_sentinel_contract_parity.py
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from sentinel_failure_codes import FailureCode, WarningCode
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[1]
|
||||
VERIFIER_PATH = REPO_ROOT / "tools" / "vm_verify_sentinel_bundle.py"
|
||||
CONTRACT_MATRIX_PATH = REPO_ROOT / "spec" / "SENTINEL_V1_CONTRACT_MATRIX.md"
|
||||
SEMANTICS_PATH = REPO_ROOT / "spec" / "SENTINEL_FAILURE_CODE_SEMANTICS.md"
|
||||
|
||||
|
||||
def _read_text(path: Path) -> str:
|
||||
return path.read_text(encoding="utf-8")
|
||||
|
||||
|
||||
def main() -> int:
|
||||
errors: list[str] = []
|
||||
|
||||
verifier = _read_text(VERIFIER_PATH)
|
||||
matrix = _read_text(CONTRACT_MATRIX_PATH)
|
||||
semantics = _read_text(SEMANTICS_PATH)
|
||||
|
||||
known_failure_values = {c.value for c in FailureCode}
|
||||
known_warning_values = {c.value for c in WarningCode}
|
||||
|
||||
# 1) Every FailureCode is referenced by the verifier code.
|
||||
for code in FailureCode:
|
||||
needle = f"FailureCode.{code.name}"
|
||||
if needle not in verifier:
|
||||
errors.append(f"Verifier does not reference {needle} ({code.value})")
|
||||
|
||||
# 1b) Every WarningCode is referenced by the verifier code.
|
||||
for code in WarningCode:
|
||||
needle = f"WarningCode.{code.name}"
|
||||
if needle not in verifier:
|
||||
errors.append(f"Verifier does not reference {needle} ({code.value})")
|
||||
|
||||
# 2) Every FailureCode value appears in the contract matrix.
|
||||
for code in FailureCode:
|
||||
if code.value not in matrix:
|
||||
errors.append(
|
||||
f"Contract matrix does not reference failure code {code.value}"
|
||||
)
|
||||
|
||||
# 2b) Every WarningCode value appears in the contract matrix.
|
||||
for code in WarningCode:
|
||||
if code.value not in matrix:
|
||||
errors.append(
|
||||
f"Contract matrix does not reference warning code {code.value}"
|
||||
)
|
||||
|
||||
# 3) Contract matrix does not contain unknown E_/W_ codes.
|
||||
referenced_failures = set(re.findall(r"\bE_[A-Z_]+\b", matrix))
|
||||
referenced_warnings = set(re.findall(r"\bW_[A-Z_]+\b", matrix))
|
||||
|
||||
unknown_failures = sorted(referenced_failures - known_failure_values)
|
||||
unknown_warnings = sorted(referenced_warnings - known_warning_values)
|
||||
|
||||
if unknown_failures:
|
||||
errors.append(
|
||||
"Contract matrix references unknown failure codes: "
|
||||
+ ", ".join(unknown_failures)
|
||||
)
|
||||
if unknown_warnings:
|
||||
errors.append(
|
||||
"Contract matrix references unknown warning codes: "
|
||||
+ ", ".join(unknown_warnings)
|
||||
)
|
||||
|
||||
# 4) Semantics doc must cover all codes.
|
||||
for code in FailureCode:
|
||||
if code.value not in semantics:
|
||||
errors.append(f"Failure code semantics doc does not reference {code.value}")
|
||||
|
||||
for code in WarningCode:
|
||||
if code.value not in semantics:
|
||||
errors.append(f"Warning code semantics doc does not reference {code.value}")
|
||||
|
||||
# 5) Semantics doc does not contain unknown E_/W_ codes.
|
||||
referenced_failures = set(re.findall(r"\bE_[A-Z_]+\b", semantics))
|
||||
referenced_warnings = set(re.findall(r"\bW_[A-Z_]+\b", semantics))
|
||||
|
||||
unknown_failures = sorted(referenced_failures - known_failure_values)
|
||||
unknown_warnings = sorted(referenced_warnings - known_warning_values)
|
||||
|
||||
if unknown_failures:
|
||||
errors.append(
|
||||
"Failure code semantics doc references unknown failure codes: "
|
||||
+ ", ".join(unknown_failures)
|
||||
)
|
||||
if unknown_warnings:
|
||||
errors.append(
|
||||
"Failure code semantics doc references unknown warning codes: "
|
||||
+ ", ".join(unknown_warnings)
|
||||
)
|
||||
|
||||
if errors:
|
||||
for e in errors:
|
||||
print(f"[FAIL] {e}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
print("[OK] Sentinel contract parity verified")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user