test(hololake): validate batch01 bootstrap trust input

This commit is contained in:
冰朔 2026-09-10 04:04:18 +08:00
commit d9600a9e9e
3 changed files with 33 additions and 5 deletions

View file

@ -4,9 +4,9 @@
"state":"ARCHITECTURE_TOOL_TESTED_NOT_AN_EXIT_OR_ENTRY_RECEIPT", "state":"ARCHITECTURE_TOOL_TESTED_NOT_AN_EXIT_OR_ENTRY_RECEIPT",
"outcome":"PASS", "outcome":"PASS",
"test_count":32, "test_count":32,
"positive":["ARCHITECTURE_EXIT_SHAPE","CONSTRUCTION_ENTRY_SHAPE","CONSTRUCTION_EXIT_SHAPE"], "positive":["ARCHITECTURE_EXIT_SHAPE","CONSTRUCTION_ENTRY_SHAPE","CONSTRUCTION_EXIT_SHAPE","BATCH_02_TO_05_ENTRY_CHAIN","BATCH_01_BOOTSTRAP_PUBLIC_TRUST_POLICY"],
"negative":["MISSING_FIELD","UNKNOWN_FIELD","BAD_SHA256","WELL_FORMED_BUT_WRONG_RECEIPT_SHA256","NAIVE_TIMESTAMP","FUTURE_TIMESTAMP","ARCHITECTURE_PASS_WITH_OPEN_DEFECT","ARCHITECTURE_PASS_WITH_EMPTY_DRAWING_OR_SITE_EVIDENCE","NONEMPTY_BUT_FAKE_ARCHITECTURE_EVIDENCE","UNKNOWN_OR_SELF_INSPECTOR","INSPECTOR_OUTCOME_OR_SOURCE_SET_MISMATCH","RESOLVED_JZAO_PATH_ESCAPE","ARCHITECTURE_REWORK_OPENS_NEXT_BATCH","CONSTRUCTION_REWORK_WITHOUT_ORDER_OR_CLOSED_NEXT_BATCH","REWORK_ORDER_DOES_NOT_MATCH_EXACT_DEFECTS","UNKNOWN_BATCH","EMPTY_ENTRY_EVIDENCE_OR_ASSIGNMENT","ENTRY_ARTIFACT_HASH_MISMATCH","PHASE2_SCOPE_IN_PHASE1_ENTRY","CROSS_BATCH_SCOPE","WRONG_PREVIOUS_EXIT_HASH_OR_DRAWING","TRUNCATED_PREVIOUS_EXIT","CONSTRUCTION_EXIT_ENTRY_CHAIN_TAMPER","WRONG_CREW_FOR_BATCH","UNTRUSTED_ISSUER_ROLE","ENTRY_NOT_OPEN","SELF_GRANTED_AUTHORITY"], "negative":["MISSING_FIELD","UNKNOWN_FIELD","BAD_SHA256","WELL_FORMED_BUT_WRONG_RECEIPT_SHA256","NAIVE_TIMESTAMP","FUTURE_TIMESTAMP","ARCHITECTURE_PASS_WITH_OPEN_DEFECT","ARCHITECTURE_PASS_WITH_EMPTY_DRAWING_OR_SITE_EVIDENCE","NONEMPTY_BUT_FAKE_ARCHITECTURE_EVIDENCE","UNKNOWN_OR_SELF_INSPECTOR","INSPECTOR_OUTCOME_OR_SOURCE_SET_MISMATCH","RESOLVED_JZAO_PATH_ESCAPE","ARCHITECTURE_REWORK_OPENS_NEXT_BATCH","CONSTRUCTION_REWORK_WITHOUT_ORDER_OR_CLOSED_NEXT_BATCH","REWORK_ORDER_DOES_NOT_MATCH_EXACT_DEFECTS","UNKNOWN_BATCH","EMPTY_ENTRY_EVIDENCE_OR_ASSIGNMENT","ENTRY_ARTIFACT_HASH_MISMATCH","PHASE2_SCOPE_IN_PHASE1_ENTRY","CROSS_BATCH_SCOPE","WRONG_PREVIOUS_EXIT_HASH_OR_DRAWING","TRUNCATED_PREVIOUS_EXIT","CONSTRUCTION_EXIT_ENTRY_CHAIN_TAMPER","CONSTRUCTION_EXIT_BATCH_MISMATCH","CONSTRUCTION_INSPECTOR_SOURCE_MISMATCH","BUILDER_ROLE_NOT_RELEASED","WRONG_CREW_FOR_BATCH","EMPTY_CREW_SCOPE","WRONG_FORBIDDEN_ACTIONS","MISSING_BOOTSTRAP_INPUT","UNTRUSTED_ISSUER_ROLE","ENTRY_NOT_OPEN","SELF_GRANTED_AUTHORITY"],
"hashes":{"validator":"537e9507553e9a8549219a066a1654f1cea98398fc0639412a6d3b9f7f70f152","tests":"7cdce696350d3e1bb9ac9e277420758f5babdda9af54b10c87f5a27e502053af","handoff_contract":"91c673c34cb7d9e3bba57949de6246f689a83a8987e0d1cc6b7b9a6bbd39ed0b","foundation_schema":"da16191aeed285379a8e0ad7705b36412d66fc2a965c49442241af0e8b759279"}, "hashes":{"validator":"525b12e00ac8a1261a21d437cd79f8f61f87b6e78e30a3619a836e6e37f6ef9e","tests":"64c8243cff43685a60a9e666583e176e9b1a1a7232dd628f30cceeb57e515a5b","handoff_contract":"91c673c34cb7d9e3bba57949de6246f689a83a8987e0d1cc6b7b9a6bbd39ed0b","foundation_schema":"da16191aeed285379a8e0ad7705b36412d66fc2a965c49442241af0e8b759279"},
"receipt_written_by_validator":false, "receipt_written_by_validator":false,
"batch_00_exit_issued":false, "batch_00_exit_issued":false,
"batch_01_entry_issued":false, "batch_01_entry_issued":false,

View file

@ -6,6 +6,7 @@ import argparse
import hashlib import hashlib
import json import json
import re import re
import subprocess
from datetime import datetime from datetime import datetime
from pathlib import Path from pathlib import Path
from typing import Any from typing import Any
@ -37,6 +38,7 @@ ARCHITECTURE_CHARTER = HERE.parents[5] / "runtime/fifth-domain-language-system/l
HANDOFF_TEST_RECEIPT = STAGE1 / "BATCH-00-HANDOFF-VALIDATOR-TEST-RECEIPT.json" HANDOFF_TEST_RECEIPT = STAGE1 / "BATCH-00-HANDOFF-VALIDATOR-TEST-RECEIPT.json"
SELF_SCHEMA_REVIEW_RECEIPT = STAGE1 / "BATCH-00-SELF-OBSERVATION-SCHEMA-REVIEW-RECEIPT.json" SELF_SCHEMA_REVIEW_RECEIPT = STAGE1 / "BATCH-00-SELF-OBSERVATION-SCHEMA-REVIEW-RECEIPT.json"
MOD013_SITE_PROBE_RECEIPT = Path("/Volumes/JZAO/铸渊-ICE-GL-ZY001/CODEX-DEV-20260909/hololake-phase1-persona-container/site-probe/TEST-RECEIPT-001.json") MOD013_SITE_PROBE_RECEIPT = Path("/Volumes/JZAO/铸渊-ICE-GL-ZY001/CODEX-DEV-20260909/hololake-phase1-persona-container/site-probe/TEST-RECEIPT-001.json")
BOOTSTRAP_POLICY = Path("/Volumes/JZAO/铸渊-ICE-GL-ZY001/CODEX-DEV-20260909/hololake-phase1-persona-container/batch01-entry/HLP-BOOTSTRAP-PUBLIC-TRUST-POLICY-001.json")
JZAO_ROOT = Path("/Volumes/JZAO").resolve() JZAO_ROOT = Path("/Volumes/JZAO").resolve()
CONSTRUCTION = STAGE1 / "CONSTRUCTION-SEQUENCE.json" CONSTRUCTION = STAGE1 / "CONSTRUCTION-SEQUENCE.json"
ALLOWED_ISSUER_ROLES = {"ENGINEERING_LEAD"} ALLOWED_ISSUER_ROLES = {"ENGINEERING_LEAD"}
@ -126,6 +128,30 @@ def verify_previous_exit(item: Any, batch_id: str, expected_sha256: Any) -> list
return errors return errors
def verify_bootstrap_policy(item: Any) -> list[str]:
if not isinstance(item, dict): return ["BOOTSTRAP_POLICY_EVIDENCE_MISSING"]
try: policy = load(Path(item["path"]))
except (OSError, ValueError, json.JSONDecodeError): return ["BOOTSTRAP_POLICY_UNREADABLE"]
required = {"schema", "policy_id", "state", "public_source", "signature", "trusted_test_signers", "revocation", "private_key_packaged", "private_payload_bytes", "real_public_policy_required_before_batch01_exit", "policy_sha256", "authority_granted"}
errors=[]
if set(policy) != required or policy.get("schema") != "hololake.bootstrap-public-trust-policy/v1" or policy.get("policy_id") != "HLP-BOOTSTRAP-PUBLIC-TRUST-POLICY-001": errors.append("BOOTSTRAP_POLICY_SHAPE_OR_ID_INVALID")
candidate=dict(policy); declared=candidate.pop("policy_sha256", None)
if declared != hashlib.sha256(json.dumps(candidate,ensure_ascii=False,sort_keys=True,separators=(",",":")).encode()).hexdigest(): errors.append("BOOTSTRAP_POLICY_HASH_MISMATCH")
if policy.get("private_key_packaged") is not False or policy.get("private_payload_bytes") != 0 or policy.get("authority_granted") is not False or policy.get("real_public_policy_required_before_batch01_exit") is not True: errors.append("BOOTSTRAP_POLICY_BOUNDARY_INVALID")
signers=policy.get("trusted_test_signers")
if not isinstance(signers,list) or len({row.get("signer_id") for row in signers if isinstance(row,dict)}) < 2: errors.append("BOOTSTRAP_POLICY_DISTINCT_SIGNERS_MISSING")
else:
for row in signers:
path=Path(str(row.get("public_key_path","")))
if not path.is_file() or file_sha256(path)!=row.get("public_key_sha256") or ".private." in path.name: errors.append("BOOTSTRAP_PUBLIC_KEY_INVALID")
source=policy.get("public_source",{}); repo=Path(str(source.get("path",""))); commit=str(source.get("git_commit","")); seed=repo/"SEED.json"
if not inside(repo,JZAO_ROOT) or not seed.is_file() or file_sha256(seed)!=source.get("seed_sha256") or source.get("real_remote_fetch") is not False: errors.append("BOOTSTRAP_TEST_MIRROR_INVALID")
else:
check=subprocess.run(["git","-C",str(repo),"cat-file","-e",commit+"^{commit}"],capture_output=True,text=True,timeout=10)
if check.returncode: errors.append("BOOTSTRAP_TEST_MIRROR_COMMIT_MISSING")
return errors
def type_ok(value: Any, expected: Any) -> bool: def type_ok(value: Any, expected: Any) -> bool:
values = expected if isinstance(expected, list) else [expected] values = expected if isinstance(expected, list) else [expected]
mapping = {"object": dict, "array": list, "string": str, "boolean": bool, "null": type(None), "number": (int, float), "integer": int} mapping = {"object": dict, "array": list, "string": str, "boolean": bool, "null": type(None), "number": (int, float), "integer": int}
@ -254,6 +280,9 @@ def validate(kind: str, receipt: dict[str, Any], now: datetime | None = None) ->
if actual_scopes != planned_scopes: errors.append("CREW_MODULE_SCOPES_DO_NOT_MATCH_PLAN") if actual_scopes != planned_scopes: errors.append("CREW_MODULE_SCOPES_DO_NOT_MATCH_PLAN")
accepted_ids = {item.get("id") for item in receipt.get("accepted_input_artifacts", []) if isinstance(item, dict)} accepted_ids = {item.get("id") for item in receipt.get("accepted_input_artifacts", []) if isinstance(item, dict)}
if accepted_ids != set(batch.get("required_input_ids", [])): errors.append("REQUIRED_BATCH_INPUT_SET_MISMATCH") if accepted_ids != set(batch.get("required_input_ids", [])): errors.append("REQUIRED_BATCH_INPUT_SET_MISMATCH")
if receipt.get("batch_id") == "HLP-BATCH-01":
bootstrap = next((item for item in receipt.get("accepted_input_artifacts", []) if isinstance(item,dict) and item.get("id") == "HLP-BOOTSTRAP-PUBLIC-TRUST-POLICY-001"), None)
errors.extend(verify_bootstrap_policy(bootstrap))
if set(receipt.get("forbidden_actions", [])) != set(batch.get("mandatory_forbidden_actions", [])): errors.append("MANDATORY_FORBIDDEN_ACTIONS_MISMATCH") if set(receipt.get("forbidden_actions", [])) != set(batch.get("mandatory_forbidden_actions", [])): errors.append("MANDATORY_FORBIDDEN_ACTIONS_MISMATCH")
if receipt.get("batch_id") == "HLP-BATCH-01": if receipt.get("batch_id") == "HLP-BATCH-01":
drawing = ARCHITECTURE_FILES["HLP-BATCH-00-FOUNDATION-DRAWINGS-001"] drawing = ARCHITECTURE_FILES["HLP-BATCH-00-FOUNDATION-DRAWINGS-001"]

View file

@ -42,8 +42,7 @@ def entry():
previous_path=EVIDENCE_ROOT/"previous-architecture-exit.json" previous_path=EVIDENCE_ROOT/"previous-architecture-exit.json"
previous=architecture(); previous_path.write_text(json.dumps(previous,sort_keys=True,separators=(",",":"))) previous=architecture(); previous_path.write_text(json.dumps(previous,sort_keys=True,separators=(",",":")))
previous_evidence=evidence("HLP-BATCH-00-EXIT",previous_path,"PASS") previous_evidence=evidence("HLP-BATCH-00-EXIT",previous_path,"PASS")
policy_path=EVIDENCE_ROOT/"bootstrap-policy.json"; policy_path.write_text('{"policy_id":"HLP-BOOTSTRAP-PUBLIC-TRUST-POLICY-001","state":"TEST_ONLY"}') accepted=[previous_evidence,evidence("HLP-BOOTSTRAP-PUBLIC-TRUST-POLICY-001",MODULE.BOOTSTRAP_POLICY),evidence("HLP-BATCH-00-TCS-CONTAINER-SITE-SURVEY-001",MODULE.SITE_SURVEY),evidence("HLP-BATCH-00-FOUNDATION-DRAWINGS-001",MODULE.ARCHITECTURE_FILES["HLP-BATCH-00-FOUNDATION-DRAWINGS-001"])]
accepted=[previous_evidence,evidence("HLP-BOOTSTRAP-PUBLIC-TRUST-POLICY-001",policy_path),evidence("HLP-BATCH-00-TCS-CONTAINER-SITE-SURVEY-001",MODULE.SITE_SURVEY),evidence("HLP-BATCH-00-FOUNDATION-DRAWINGS-001",MODULE.ARCHITECTURE_FILES["HLP-BATCH-00-FOUNDATION-DRAWINGS-001"])]
forbidden=["PUBLISH","DEPLOY","DELETE","MODIFY_OTHER_HOST_DEV_ROOT","ENTER_PHASE2","SELF_ACCEPT"] forbidden=["PUBLISH","DEPLOY","DELETE","MODIFY_OTHER_HOST_DEV_ROOT","ENTER_PHASE2","SELF_ACCEPT"]
return seal({"schema":"hololake.construction-batch-entry/v1","receipt_id":"R-ENTRY-001","batch_id":"HLP-BATCH-01","previous_batch_exit_receipt_sha256":previous_evidence["sha256"],"previous_batch_exit_receipt":previous_evidence,"construction_drawing_id":"HLP-BATCH-00-FOUNDATION-DRAWINGS-001","construction_drawing_sha256":MODULE.file_sha256(MODULE.ARCHITECTURE_FILES["HLP-BATCH-00-FOUNDATION-DRAWINGS-001"]),"accepted_input_artifacts":accepted,"crew_admissions":[{"development_id":"HLP-TDEV-CODEX-0001","role":"BUILDER","scope":["HLP-NATIVE-MOD-001","HLP-NATIVE-MOD-003","HLP-NATIVE-MOD-004"]},{"development_id":"HLP-TDEV-ZCODE-0001","role":"BUILDER","scope":["HLP-NATIVE-MOD-002"]}],"inspector_assignment":{"inspector_id":"CODEX-CHILD-BATCH01","mode":"READ_ONLY_NO_PRODUCTION_WRITE"},"scope":["HLP-NATIVE-MOD-001","HLP-NATIVE-MOD-002","HLP-NATIVE-MOD-003","HLP-NATIVE-MOD-004"],"forbidden_actions":forbidden,"issued_by_role":"ENGINEERING_LEAD","issued_at":AT,"state":"ENTRY_OPEN","authority_granted":False}) return seal({"schema":"hololake.construction-batch-entry/v1","receipt_id":"R-ENTRY-001","batch_id":"HLP-BATCH-01","previous_batch_exit_receipt_sha256":previous_evidence["sha256"],"previous_batch_exit_receipt":previous_evidence,"construction_drawing_id":"HLP-BATCH-00-FOUNDATION-DRAWINGS-001","construction_drawing_sha256":MODULE.file_sha256(MODULE.ARCHITECTURE_FILES["HLP-BATCH-00-FOUNDATION-DRAWINGS-001"]),"accepted_input_artifacts":accepted,"crew_admissions":[{"development_id":"HLP-TDEV-CODEX-0001","role":"BUILDER","scope":["HLP-NATIVE-MOD-001","HLP-NATIVE-MOD-003","HLP-NATIVE-MOD-004"]},{"development_id":"HLP-TDEV-ZCODE-0001","role":"BUILDER","scope":["HLP-NATIVE-MOD-002"]}],"inspector_assignment":{"inspector_id":"CODEX-CHILD-BATCH01","mode":"READ_ONLY_NO_PRODUCTION_WRITE"},"scope":["HLP-NATIVE-MOD-001","HLP-NATIVE-MOD-002","HLP-NATIVE-MOD-003","HLP-NATIVE-MOD-004"],"forbidden_actions":forbidden,"issued_by_role":"ENGINEERING_LEAD","issued_at":AT,"state":"ENTRY_OPEN","authority_granted":False})