Implement AXIS parity UI and execution baseline
This commit is contained in:
@@ -6,6 +6,7 @@ from __future__ import annotations
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
import re
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
@@ -29,6 +30,33 @@ def sha256(path: Path) -> str:
|
||||
return hashlib.sha256(path.read_bytes()).hexdigest()
|
||||
|
||||
|
||||
def evidence_error(root: Path, evidence_row: Any) -> str | None:
|
||||
"""Validate an evidence reference without allowing paths outside the repo."""
|
||||
if not isinstance(evidence_row, dict):
|
||||
return "evidence_not_object"
|
||||
path_value = evidence_row.get("path")
|
||||
hash_value = evidence_row.get("sha256")
|
||||
if not isinstance(path_value, str) or not path_value.strip():
|
||||
return "evidence_path_missing"
|
||||
if "\\" in path_value or Path(path_value).is_absolute():
|
||||
return "evidence_path_not_relative"
|
||||
path = Path(path_value)
|
||||
if ".." in path.parts:
|
||||
return "evidence_path_escapes_repo"
|
||||
if not isinstance(hash_value, str) or not re.fullmatch(r"[0-9a-f]{64}", hash_value):
|
||||
return "evidence_hash_invalid"
|
||||
resolved = (root / path).resolve()
|
||||
try:
|
||||
resolved.relative_to(root)
|
||||
except ValueError:
|
||||
return "evidence_path_escapes_repo"
|
||||
if not resolved.is_file():
|
||||
return "evidence_file_missing"
|
||||
if sha256(resolved) != hash_value:
|
||||
return "evidence_hash_mismatch"
|
||||
return None
|
||||
|
||||
|
||||
def load_json(path: Path) -> tuple[dict[str, Any], str | None]:
|
||||
try:
|
||||
value = json.loads(path.read_text(encoding="utf-8"))
|
||||
@@ -45,6 +73,16 @@ def validate(root: Path, input_path: Path = INPUT, output_path: Path = OUTPUT) -
|
||||
input_present = (root / input_path).is_file()
|
||||
errors = [error for error in (lock_error, input_error) if error]
|
||||
decisions = value.get("decisions") if isinstance(value.get("decisions"), list) else []
|
||||
if input_present:
|
||||
for field in ("schema", "context_id", "decision_set_id", "decisions"):
|
||||
field_value = value.get(field)
|
||||
invalid_field = (
|
||||
not isinstance(field_value, list)
|
||||
if field == "decisions"
|
||||
else not isinstance(field_value, str) or not field_value.strip()
|
||||
)
|
||||
if invalid_field:
|
||||
errors.append(f"{field}_missing")
|
||||
observed = [row.get("blocker") for row in decisions if isinstance(row, dict)]
|
||||
duplicate_ids = sorted({blocker for blocker in observed if observed.count(blocker) > 1 and blocker is not None})
|
||||
missing_ids = sorted(set(BLOCKERS) - set(observed))
|
||||
@@ -62,8 +100,9 @@ def validate(root: Path, input_path: Path = INPUT, output_path: Path = OUTPUT) -
|
||||
if not isinstance(evidence, list) or not evidence: row_errors.append({"index": index, "error": "evidence_missing"})
|
||||
else:
|
||||
for evidence_row in evidence:
|
||||
if not isinstance(evidence_row, dict) or not isinstance(evidence_row.get("path"), str) or not isinstance(evidence_row.get("sha256"), str) or len(evidence_row["sha256"]) != 64:
|
||||
row_errors.append({"index": index, "error": "evidence_invalid"})
|
||||
evidence_issue = evidence_error(root, evidence_row)
|
||||
if evidence_issue:
|
||||
row_errors.append({"index": index, "error": evidence_issue})
|
||||
context_ok = bool(lock.get("context_id")) and value.get("context_id") == lock.get("context_id") if input_present else False
|
||||
shape_ok = input_present and not errors and value.get("schema") == "owner-decision-intake.v1" and len(decisions) == 6 and not duplicate_ids and not missing_ids and not unknown_ids and not row_errors and context_ok
|
||||
all_approved = shape_ok and all(row.get("decision") == "approve" for row in decisions)
|
||||
@@ -80,7 +119,7 @@ def validate(root: Path, input_path: Path = INPUT, output_path: Path = OUTPUT) -
|
||||
"schema": "owner-decision-intake-report.v1",
|
||||
"context_id": lock.get("context_id"),
|
||||
"task_id": "K8-REL-18",
|
||||
"status": "verified" if shape_ok else "blocked",
|
||||
"status": "verified" if all_approved else "blocked",
|
||||
"implementation_status": "verified",
|
||||
"release_status": "blocked_external_owner",
|
||||
"candidate_eligible": False,
|
||||
|
||||
Reference in New Issue
Block a user