| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 |
- """Run bounded local P3-WP14 verification and write a machine-readable ledger.
- The ledger intentionally stores digests of captured stdout/stderr, not their
- contents, so it carries no service configuration or credentials. It neither
- starts Compose nor contacts an enterprise system; the config validator performs
- only a local Compose render.
- """
- from __future__ import annotations
- import hashlib
- import json
- import os
- import re
- import subprocess
- import sys
- from datetime import datetime, timedelta, timezone
- from pathlib import Path
- from p3_wp14_secure_io import atomic_write_bytes, exclusive_lock, read_bytes_once, read_json_once
- ROOT = Path(__file__).resolve().parents[1]
- COMMAND_HOME = ROOT / "work/p3_wp14_ledger_command_home"
- PYTHON = ROOT / ".venv/bin/python"
- LEDGER = ROOT / "docs/validation/P3_WP14_LOCAL_VERIFICATION_LEDGER.json"
- LOG = ROOT / "docs/validation/P3_WP14_LOCAL_VERIFICATION.log"
- TRACE = ROOT / "docs/phase3/P3_WP14_RELEASE_TRACEABILITY.json"
- MANIFEST = ROOT / "docs/phase3/P3_WP14_RELEASE_MANIFEST.json"
- STATE = ROOT / "docs/validation/P3_WP14_VERIFICATION_RUN_STATE.json"
- LOCK = ROOT / "work/p3_wp14_ledger_lock_scope/lock"
- TTL_SECONDS = 900
- INPUT_PATHS = (
- "docs/phase3/P3_WP14_RELEASE_MANIFEST.json",
- "docs/validation/P3_WP14_LOCAL_CONFIG_A.json",
- "docs/validation/P3_WP14_LOCAL_CONFIG_B.json",
- "docs/validation/P3_WP14_LOCAL_CONFIG_COMPARISON.json",
- "docs/acceptance/P3_WP14_UAT_CASES.json",
- "tests/test_phase3_wp14_acceptance_handover_contract.py",
- "scripts/validate_p3_wp14_local_configs.py",
- "scripts/generate_p3_wp14_release_manifest.py",
- "scripts/generate_p3_wp14_verification_ledger.py",
- "scripts/verify_p3_wp14_fresh_local_engineering.py",
- "scripts/p3_wp14_secure_io.py",
- )
- TARGETED_TESTS = (
- "tests/test_phase3_wp01_enterprise_acceptance_contract.py",
- "tests/test_phase3_wp02_enterprise_identity_contract.py",
- "tests/test_phase3_wp03_enterprise_connectors.py",
- "tests/test_phase3_wp04_delivery_contract.py",
- "tests/test_phase3_wp04_production_runtime.py",
- "tests/core/orchestration/test_production_observability.py",
- "tests/test_phase3_wp06_subscription_migration_contract.py",
- "tests/test_phase3_wp07_enterprise_delivery_contract.py",
- "tests/acceptance/test_phase3_wp08_third_domain_replication.py",
- "tests/agent/test_wp09_model_gateway.py",
- "tests/test_wp10_tenant_api.py",
- "tests/test_wp11_bi_ai_catalog_api.py",
- "tests/test_wp12_metering_showback_api.py",
- "tests/test_wp13_plugin_platform_api.py",
- "tests/test_permission_matrix.py",
- )
- def _sha256_bytes(value: bytes) -> str:
- return hashlib.sha256(value).hexdigest()
- def _sha256_path(path: Path) -> str:
- return _sha256_bytes(read_bytes_once(path))
- def ledger_is_fresh(payload: dict, now: datetime | None = None) -> bool:
- current = now or datetime.now(timezone.utc)
- return datetime.fromisoformat(payload["expires_at"].replace("Z", "+00:00")) > current
- def _write_json(path: Path, value: object) -> None:
- atomic_write_bytes(path, json.dumps(value, ensure_ascii=False, indent=2).encode("utf-8") + b"\n")
- def _sanitized(value: str) -> str:
- return re.sub(r"(?i)(password|token|secret|api[_-]?key)\s*[:=]\s*\S+", r"\1=<REDACTED>", value)
- def _entry_path(command: list[str], dependencies: list[Path]) -> Path:
- """The entry is the first repository file explicitly passed to the command."""
- for part in command[1:]:
- path = ROOT / part
- if path.is_file():
- return path
- return dependencies[0]
- def _minimal_command_env() -> dict[str, str]:
- """Run bounded local commands without inherited credential/config paths."""
- return {
- "PATH": os.environ.get("PATH", ""),
- "HOME": str(COMMAND_HOME),
- "TMPDIR": str(COMMAND_HOME / "tmp"),
- "DOCKER_CONFIG": str(COMMAND_HOME / "docker"),
- "PYTHONDONTWRITEBYTECODE": "1",
- "LANG": "C.UTF-8",
- "LC_ALL": "C.UTF-8",
- }
- def _run(command_id: str, command: list[str], case_ids: list[str]) -> tuple[dict, str]:
- completed = subprocess.run(
- command,
- cwd=ROOT,
- env=_minimal_command_env(),
- text=True,
- capture_output=True,
- check=False,
- timeout=300,
- )
- output = completed.stdout + completed.stderr
- sanitized_output = _sanitized(output)
- match = re.search(r"(\d+) passed", output)
- dependencies = [ROOT / part for part in command[1:] if (ROOT / part).is_file()]
- if command_id == "p3_targeted_regression": dependencies.extend(ROOT / target for target in TARGETED_TESTS)
- dependencies.append(ROOT / "scripts/p3_wp14_secure_io.py")
- dependencies = sorted(set(dependencies))
- dependency_digests = {path.relative_to(ROOT).as_posix(): _sha256_path(path) for path in dependencies}
- run = {
- "command_id": command_id,
- "command": command,
- "case_ids": case_ids,
- "run_at": datetime.now(timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z"),
- "status": "PASS" if completed.returncode == 0 else "FAIL",
- "exit_code": completed.returncode,
- "passed_count": int(match.group(1)) if match else 1 if completed.returncode == 0 else 0,
- "timeout_seconds": 300,
- "cwd": ".",
- "command_sha256": _sha256_bytes(json.dumps(command, separators=(",", ":")).encode("utf-8")),
- "entry_path": _entry_path(command, dependencies).relative_to(ROOT).as_posix(),
- "script_sha256": _sha256_path(_entry_path(command, dependencies)),
- "dependency_sha256": dependency_digests,
- "dependency_aggregate_sha256": _sha256_bytes(json.dumps(dependency_digests, sort_keys=True, separators=(",", ":")).encode("utf-8")),
- "stdout_sha256": _sha256_bytes(_sanitized(completed.stdout).encode("utf-8")),
- "stderr_sha256": _sha256_bytes(_sanitized(completed.stderr).encode("utf-8")),
- }
- return run, f"{command_id} exit={completed.returncode} passed={run['passed_count']} output_sha256={_sha256_bytes(sanitized_output.encode('utf-8'))}"
- def main() -> int:
- with exclusive_lock(LOCK) as nonce:
- now = datetime.now(timezone.utc).replace(microsecond=0)
- _write_json(STATE, {
- "schema_version": "1.0", "status": "RUNNING", "run_nonce": nonce,
- "started_at": now.isoformat().replace("+00:00", "Z"),
- "expires_at": (now + timedelta(seconds=TTL_SECONDS)).isoformat().replace("+00:00", "Z"),
- })
- try:
- return _main_locked(nonce, now)
- except (subprocess.TimeoutExpired, Exception) as error:
- _write_json(STATE, {"schema_version": "1.0", "status": "FAILED", "run_nonce": nonce, "error_type": type(error).__name__, "invalidates_prior_ledger_and_trace": True})
- return 1
- def _main_locked(nonce: str, now: datetime) -> int:
- commands = (
- (
- "p3_targeted_regression",
- [str(PYTHON), "-m", "pytest", "-q", *TARGETED_TESTS],
- [f"P3-WP14-UAT-{number:02d}" for number in range(1, 14)] + ["P3-WP14-UAT-23", "P3-WP14-UAT-25", "P3-WP14-UAT-27"],
- ),
- (
- "local_config_compose_render",
- [str(PYTHON), "scripts/validate_p3_wp14_local_configs.py"],
- ["P3-WP14-UAT-30"],
- ),
- (
- "release_manifest_generation",
- [str(PYTHON), "scripts/generate_p3_wp14_release_manifest.py"],
- ["P3-WP14-UAT-29"],
- ),
- (
- "wp14_264_audit_contract",
- [str(PYTHON), "-m", "pytest", "-q", "tests/test_phase3_wp14_acceptance_handover_contract.py", "-k", "264_item_closure"],
- ["P3-WP14-UAT-26"],
- ),
- (
- "wp14_browser_boundary_contract",
- [str(PYTHON), "-m", "pytest", "-q", "tests/test_phase3_wp14_acceptance_handover_contract.py", "-k", "report_ledger_signoff_runbook"],
- ["P3-WP14-UAT-28"],
- ),
- )
- runs: list[dict] = []
- log_sections: list[str] = []
- for command_id, command, case_ids in commands:
- run, output = _run(command_id, command, case_ids)
- runs.append(run)
- log_sections.append(output)
- if run["exit_code"] != 0:
- atomic_write_bytes(LOG, ("\n".join(log_sections) + "\n").encode("utf-8"))
- _write_json(STATE, {"schema_version": "1.0", "status": "FAILED", "run_nonce": nonce, "failed_command_id": command_id})
- return run["exit_code"]
- atomic_write_bytes(LOG, ("\n".join(log_sections) + "\n").encode("utf-8"))
- controlled = {path: _sha256_path(ROOT / path) for path in INPUT_PATHS}
- payload = {
- "schema_version": "1.0",
- "work_package": "P3-WP14",
- "cache_class": "UNSIGNED_REPRODUCIBILITY_CACHE",
- "pass_local_authority": "FRESH_VERIFIER_CURRENT_PROCESS_ONLY",
- "external_signature_anchor": {"status": "TBD_EXTERNAL", "gate": "BLOCKED_EXTERNAL"},
- "generated_at": datetime.now(timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z"),
- "expires_at": (now + timedelta(seconds=TTL_SECONDS)).isoformat().replace("+00:00", "Z"),
- "run_nonce": nonce,
- "security_envelope": {
- "locked": True,
- "atomic_write": True,
- "fd_single_read": True,
- "minimal_environment": True,
- "stdout_stderr_persisted": "SANITIZED_DIGEST_ONLY",
- },
- "controlled_input_paths": list(INPUT_PATHS),
- "controlled_input_sha256": _sha256_bytes(
- json.dumps(controlled, sort_keys=True, separators=(",", ":")).encode("utf-8")
- ),
- "log_path": "docs/validation/P3_WP14_LOCAL_VERIFICATION.log",
- "log_sha256": _sha256_path(LOG),
- "runs": runs,
- "boundary": "This file and its log/trace are unsigned reproducibility caches and cannot independently grant PASS_LOCAL. Only the fresh verifier may report a current-process local result. All commands are local engineering checks; Compose is rendered only; no deployment, enterprise endpoint, or enterprise UAT is performed.",
- }
- _write_json(LEDGER, payload)
- trace = read_json_once(TRACE)
- assert isinstance(trace, dict)
- trace["release_manifest_path"] = "docs/phase3/P3_WP14_RELEASE_MANIFEST.json"
- trace["release_manifest_sha256"] = _sha256_path(MANIFEST)
- trace["verification_ledger_sha256"] = _sha256_path(LEDGER)
- trace["verification_log_sha256"] = _sha256_path(LOG)
- trace["local_verification_cache"] = {
- "classification": "UNSIGNED_REPRODUCIBILITY_CACHE",
- "pass_local_authority": "FRESH_VERIFIER_CURRENT_PROCESS_ONLY",
- "external_signature_status": "TBD_EXTERNAL",
- "enterprise_gate": "BLOCKED_EXTERNAL",
- }
- trace["second_isolated_local_environment"] = {
- "formal_same_signed_version_status": "BLOCKED_EXTERNAL",
- "formal_same_signed_version_reason": "manifest is unsigned; signature and enterprise second-environment authority are TBD_EXTERNAL",
- "local_portability_rehearsal": {
- "result": "PASS_LOCAL",
- "manifest_sha256": trace["release_manifest_sha256"],
- "manifest_signed": False,
- "boundary": "Two closed, non-secret local configuration renders are bound to this unsigned manifest digest. This is portability rehearsal only, not the required same signed-version second isolated environment.",
- },
- }
- _write_json(TRACE, trace)
- _write_json(STATE, {
- "schema_version": "1.0", "status": "COMPLETE", "run_nonce": nonce,
- "generated_at": payload["generated_at"], "expires_at": payload["expires_at"],
- })
- return 0
- if __name__ == "__main__":
- sys.exit(main())
|