feat(automation): enforce assessment scope and document activation blockers

This commit is contained in:
cesnimda
2026-10-30 09:40:12 +01:00
parent 140e182516
commit 750d76317c
22 changed files with 7065 additions and 12 deletions
+31
View File
@@ -0,0 +1,31 @@
"""Read-only verification of a trusted, source-bound assessment receipt; no services."""
import hashlib
import json
from pathlib import Path
def verify(repository, receipt_path, expected_sha256):
repository = Path(repository).resolve()
raw = Path(receipt_path).read_bytes()
if len(raw) > 8 * 1024 * 1024 or hashlib.sha256(raw).hexdigest() != expected_sha256:
raise ValueError('Assessment receipt differs from the protected manifest pin')
receipt = json.loads(raw)
if (receipt.get('schemaVersion') != 1 or receipt.get('scope') != 'P10-00-ASSESSMENT-ONLY'
or receipt.get('integrity') != 'PASS' or not receipt.get('files')
or not receipt.get('nativeReports') or not receipt.get('retainedDecisions')):
raise ValueError('Incomplete assessment qualification receipt')
for name, expected in receipt['files'].items():
path = (repository / name).resolve()
if not path.is_relative_to(repository) or not path.is_file():
raise ValueError('Frozen assessment source missing or outside repository: ' + name)
if hashlib.sha256(path.read_bytes()).hexdigest() != expected:
raise ValueError('Frozen assessment source changed; fresh affected qualification required: ' + name)
evidence_root = Path(receipt_path).resolve().parent
for name, expected in receipt.get('evidenceFiles', {}).items():
path = (evidence_root / name).resolve()
if not path.is_relative_to(evidence_root) or not path.is_file() or hashlib.sha256(path.read_bytes()).hexdigest() != expected:
raise ValueError('Accepted handoff evidence changed or missing: ' + name)
return dict(kind='REUSED_SOURCE_BOUND_EVIDENCE', receiptSha256=expected_sha256,
nativeReports=receipt['nativeReports'],
retainedDecisions=receipt['retainedDecisions'],
limits='P10-00 assessment only. No fresh product runs or implementation qualification.')