Files
xjx c895301268 Implement engineering speedup architecture (#16)
Land the B0/M0-M5/E0-E4/P0-P3 engineering-speedup control plane, including exact Swift caching, measured engineering metrics, canonical Rust identity validation, deterministic test isolation, proof fallback/promotion, and supporting architecture splits.\n\nRelease validation and dispatch are intentionally deferred to the next release.
2026-08-12 21:25:00 +08:00

1233 lines
51 KiB
Python
Executable File

#!/usr/bin/env python3
"""Manage trusted PR merge proofs and exact merged-head cleanup."""
from __future__ import annotations
import argparse
import hashlib
import io
import json
import os
import pathlib
import re
import shutil
import stat
import subprocess
import sys
import tempfile
import zipfile
from argparse import Namespace
from typing import Any
SCHEMA_VERSION = "apc.ci-candidate-proof.v1"
MERGE_TICKET_SCHEMA_VERSION = "apc.ci-merge-ticket.v1"
WORKFLOW_PATH = ".github/workflows/ci.yml"
EXPECTED_GATES = [
"bundle",
"macos-contracts",
"macos-platform",
"overlay",
"portable-contracts",
"rust-lint",
"rust-test-build",
"rust-test-proof",
"rust-tests",
"static",
"stress",
"swift-interaction",
]
TOOLCHAIN_CONTRACT_FILES = [
"Cargo.lock",
"apps/macos/Package.resolved",
"apps/macos/Package.swift",
"rust-toolchain.toml",
"script/validate_macos_build_contract.py",
]
CONTROL_PLANE_FILES = [
".github/workflows/auto-merge.yml",
".github/workflows/ci.yml",
".github/workflows/release.yml",
"development/domains.json",
"script/changelog_fragments.py",
"script/ci_proof_promotion.py",
"script/configure_main_branch_ruleset.py",
"script/development_domains.py",
"script/development_flow.py",
"script/engineering_metrics.py",
"script/interaction-contract-files.txt",
"script/prepare_interaction_attestation.sh",
"script/release_source_proof.py",
"script/resolve_release_source_proof.py",
"script/validate_build_scripts_safety.sh",
"script/validate_interaction_attestation.py",
"script/validate_macos_build_contract.py",
"script/validate_overlay_interaction.sh",
"script/validate_rust_test_shards.py",
"script/validation_scope.py",
]
COMMIT_PATTERN = re.compile(r"[0-9a-f]{40}")
REPOSITORY_PATTERN = re.compile(r"[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+")
HEAD_PATTERN = re.compile(r"gd-ops/(?:task|fix|train|release)/[A-Za-z0-9._-]+")
ARTIFACT_PATTERN = re.compile(r"ci-candidate-proof-([0-9a-f]{40})")
MERGE_TICKET_ARTIFACT_PATTERN = re.compile(
r"ci-merge-ticket-([1-9][0-9]*)-([1-9][0-9]*)"
)
DIGEST_PATTERN = re.compile(r"[0-9a-f]{64}")
def run(root: pathlib.Path, *command: str) -> str:
return subprocess.check_output(command, cwd=root, text=True).strip()
def sha256(path: pathlib.Path) -> str:
digest = hashlib.sha256()
with path.open("rb") as handle:
for block in iter(lambda: handle.read(1024 * 1024), b""):
digest.update(block)
return digest.hexdigest()
def contract_digest(root: pathlib.Path) -> str:
digest = hashlib.sha256()
for relative in TOOLCHAIN_CONTRACT_FILES:
path = root / relative
metadata = path.lstat()
if not stat.S_ISREG(metadata.st_mode) or path.is_symlink():
raise ValueError(f"toolchain contract entry is not a regular file: {relative}")
digest.update(relative.encode("utf-8"))
digest.update(b"\0")
digest.update(path.read_bytes())
digest.update(b"\0")
return digest.hexdigest()
def read_json_regular(path: pathlib.Path, *, limit: int = 1024 * 1024) -> Any:
try:
descriptor = os.open(path, os.O_RDONLY | os.O_CLOEXEC | os.O_NOFOLLOW)
except OSError as error:
raise ValueError(f"input must be a regular, non-symlink file: {path.name}") from error
try:
metadata = os.fstat(descriptor)
if not stat.S_ISREG(metadata.st_mode) or metadata.st_size > limit:
raise ValueError(f"input is not a bounded regular file: {path.name}")
with os.fdopen(descriptor, encoding="utf-8") as handle:
descriptor = -1
return json.load(handle)
finally:
if descriptor >= 0:
os.close(descriptor)
def atomic_write_json(path: pathlib.Path, payload: Any) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
descriptor, temporary_name = tempfile.mkstemp(prefix=f".{path.name}.", dir=path.parent)
try:
os.fchmod(descriptor, 0o644)
with os.fdopen(descriptor, "w", encoding="utf-8") as handle:
json.dump(payload, handle, sort_keys=True, separators=(",", ":"))
handle.write("\n")
handle.flush()
os.fsync(handle.fileno())
os.replace(temporary_name, path)
finally:
try:
os.unlink(temporary_name)
except FileNotFoundError:
pass
def require_commit(value: str, name: str) -> None:
if COMMIT_PATTERN.fullmatch(value) is None:
raise ValueError(f"{name} must be a full lowercase Git commit")
def require_identity(repository: str, commits: dict[str, str]) -> None:
if REPOSITORY_PATTERN.fullmatch(repository) is None:
raise ValueError("repository must be owner/name")
for name, value in commits.items():
require_commit(value, name)
def require_origin_repository(root: pathlib.Path, repository: str) -> None:
remote = run(root, "git", "remote", "get-url", "origin")
accepted = {
f"https://github.com/{repository}",
f"https://github.com/{repository}.git",
f"git@github.com:{repository}.git",
f"ssh://git@github.com/{repository}.git",
}
if remote not in accepted:
raise ValueError("origin does not match the verified pull-request repository")
def remote_ref_sha(root: pathlib.Path, head_ref: str) -> str | None:
full_ref = f"refs/heads/{head_ref}"
response = run(root, "git", "ls-remote", "--refs", "origin", full_ref)
if not response:
return None
lines = response.splitlines()
if len(lines) != 1:
raise ValueError("remote head lookup is ambiguous")
fields = lines[0].split("\t")
if len(fields) != 2 or fields[1] != full_ref:
raise ValueError("remote head lookup returned an invalid ref")
require_commit(fields[0], "remote head commit")
return fields[0]
def delete_merged_head(args: Namespace) -> dict[str, bool | str]:
root = args.root.resolve()
require_identity(args.repository, {"head commit": args.head_commit})
if args.pull_request_number <= 0:
raise ValueError("merged-head PR identity must be positive")
if HEAD_PATTERN.fullmatch(args.head_ref) is None:
raise ValueError("merged head is not a managed development branch")
pull = api_json(
f"repos/{args.repository}/pulls/{args.pull_request_number}"
)
head = pull.get("head") if isinstance(pull, dict) else None
head_repository = head.get("repo") if isinstance(head, dict) else None
if not (
isinstance(pull, dict)
and pull.get("number") == args.pull_request_number
and pull.get("merged") is True
and isinstance(head, dict)
and head.get("ref") == args.head_ref
and head.get("sha") == args.head_commit
and isinstance(head_repository, dict)
and head_repository.get("full_name") == args.repository
):
raise ValueError("merged-head cleanup is not bound to the exact merged pull request")
require_origin_repository(root, args.repository)
if not isinstance(args.allow_delete, bool):
raise ValueError("merged-head cleanup mode is invalid")
subprocess.run(["gh", "auth", "setup-git"], check=True)
observed = remote_ref_sha(root, args.head_ref)
result: dict[str, bool | str] = {
"deleted": False,
"head_ref": args.head_ref,
"head_commit": args.head_commit,
}
if observed is None:
return result
if not args.allow_delete:
raise ValueError(
"merged-head replay found an existing source ref; refusing deletion"
)
if observed != args.head_commit:
raise ValueError("merged source branch advanced or was reused; refusing deletion")
full_ref = f"refs/heads/{args.head_ref}"
subprocess.run(
[
"git",
"push",
f"--force-with-lease={full_ref}:{args.head_commit}",
"origin",
f":{full_ref}",
],
cwd=root,
check=True,
)
if remote_ref_sha(root, args.head_ref) is not None:
raise ValueError("merged source branch still exists after deletion")
result["deleted"] = True
return result
def require_unchanged_control_plane(
root: pathlib.Path, base_commit: str, main_commit: str
) -> None:
require_commit(base_commit, "control-plane base commit")
require_commit(main_commit, "control-plane main commit")
if CONTROL_PLANE_FILES != sorted(set(CONTROL_PLANE_FILES)):
raise ValueError("CI proof control-plane inventory is invalid")
changed = run(
root,
"git",
"diff",
"--name-only",
"--no-renames",
base_commit,
main_commit,
"--",
*CONTROL_PLANE_FILES,
)
if changed:
raise ValueError(f"CI proof control plane changed: {changed.replace(chr(10), ', ')}")
def validate_attestation(
root: pathlib.Path, attestation: pathlib.Path, tested_commit: str
) -> dict[str, Any]:
subprocess.run(
[
str(root / "script/validate_interaction_attestation.py"),
str(attestation),
"--root",
str(root),
"--expected-build-id",
f"source.{tested_commit}",
],
cwd=root,
check=True,
)
payload = read_json_regular(attestation)
if not isinstance(payload, dict):
raise ValueError("interaction attestation must contain one JSON object")
return payload
def observed_toolchains(root: pathlib.Path) -> dict[str, str]:
commands = {
"rustc": ("rustc", "-Vv"),
"swift": ("swift", "--version"),
"python": ("python3", "--version"),
"sdk": ("xcrun", "--show-sdk-version"),
}
values: dict[str, str] = {}
for name, command in commands.items():
value = subprocess.check_output(
command, cwd=root, text=True, stderr=subprocess.STDOUT
).strip()
if not value or len(value) > 4096:
raise ValueError(f"observed {name} toolchain identity is invalid")
values[name] = value
return values
def select_merged_pull(
payload: Any, repository: str, main_commit: str
) -> dict[str, int | str]:
require_identity(repository, {"main commit": main_commit})
if not isinstance(payload, list):
raise ValueError("pull request response must contain one list")
matches: list[dict[str, Any]] = []
for pull in payload:
if not isinstance(pull, dict):
continue
base = pull.get("base")
head = pull.get("head")
base_repo = base.get("repo") if isinstance(base, dict) else None
head_repo = head.get("repo") if isinstance(head, dict) else None
head_ref = head.get("ref") if isinstance(head, dict) else None
if (
pull.get("state") == "closed"
and isinstance(pull.get("merged_at"), str)
and pull.get("merge_commit_sha") == main_commit
and isinstance(pull.get("number"), int)
and pull["number"] > 0
and isinstance(base, dict)
and base.get("ref") == "main"
and isinstance(base_repo, dict)
and base_repo.get("full_name") == repository
and isinstance(head, dict)
and isinstance(head_repo, dict)
and head_repo.get("full_name") == repository
and isinstance(head_ref, str)
and HEAD_PATTERN.fullmatch(head_ref) is not None
and isinstance(head.get("sha"), str)
and COMMIT_PATTERN.fullmatch(head["sha"]) is not None
):
matches.append(pull)
if len(matches) != 1:
raise ValueError("exactly one trusted merged pull request must own the main commit")
selected = matches[0]
head = selected["head"]
return {
"number": selected["number"],
"head_sha": head["sha"],
"head_ref": head["ref"],
}
def select_successful_run(
payload: dict[str, Any], repository: str, head_sha: str, head_ref: str
) -> dict[str, int]:
require_identity(repository, {"head commit": head_sha})
if HEAD_PATTERN.fullmatch(head_ref) is None:
raise ValueError("head branch is not a managed development branch")
runs = payload.get("workflow_runs")
if not isinstance(runs, list):
raise ValueError("workflow run response is missing workflow_runs")
matches = []
for workflow_run in runs:
if not isinstance(workflow_run, dict):
continue
head_repository = workflow_run.get("head_repository")
if (
workflow_run.get("status") == "completed"
and workflow_run.get("conclusion") == "success"
and workflow_run.get("event") == "pull_request"
and workflow_run.get("head_sha") == head_sha
and workflow_run.get("head_branch") == head_ref
and workflow_run.get("path") == WORKFLOW_PATH
and isinstance(head_repository, dict)
and head_repository.get("full_name") == repository
and isinstance(workflow_run.get("id"), int)
and isinstance(workflow_run.get("run_attempt"), int)
):
matches.append(workflow_run)
if not matches:
raise ValueError("no successful trusted pull-request CI run exists")
selected = max(matches, key=lambda item: (item["id"], item["run_attempt"]))
return {"run_id": selected["id"], "run_attempt": selected["run_attempt"]}
def require_required_gate(payload: dict[str, Any]) -> None:
jobs = payload.get("jobs")
if not isinstance(jobs, list):
raise ValueError("workflow job response is missing jobs")
matches = [
job
for job in jobs
if isinstance(job, dict)
and job.get("name") == "Required CI"
and job.get("conclusion") == "success"
]
if len(matches) != 1:
raise ValueError("trusted PR run must contain one successful Required CI job")
def select_candidate_artifact(
payload: dict[str, Any], run_id: int
) -> dict[str, int | str]:
artifacts = payload.get("artifacts")
if not isinstance(artifacts, list):
raise ValueError("artifact response is missing artifacts")
matches: list[dict[str, Any]] = []
for artifact in artifacts:
if not isinstance(artifact, dict):
continue
workflow_run = artifact.get("workflow_run")
artifact_run_id = workflow_run.get("id") if isinstance(workflow_run, dict) else run_id
name = artifact.get("name")
if (
isinstance(name, str)
and ARTIFACT_PATTERN.fullmatch(name) is not None
and artifact.get("expired") is False
and artifact_run_id == run_id
and isinstance(artifact.get("id"), int)
and isinstance(artifact.get("size_in_bytes"), int)
and 0 < artifact["size_in_bytes"] <= 1024 * 1024
):
matches.append(artifact)
if len(matches) != 1:
raise ValueError("trusted PR run must contain exactly one live bounded candidate artifact")
selected = matches[0]
tested_commit = ARTIFACT_PATTERN.fullmatch(selected["name"]).group(1)
return {
"id": selected["id"],
"name": selected["name"],
"size_in_bytes": selected["size_in_bytes"],
"tested_commit": tested_commit,
}
def candidate_artifacts(payload: dict[str, Any], run_id: int) -> list[dict[str, Any]]:
artifacts = payload.get("artifacts")
if not isinstance(artifacts, list):
raise ValueError("artifact response is missing artifacts")
matches = []
for artifact in artifacts:
if not isinstance(artifact, dict):
continue
workflow_run = artifact.get("workflow_run")
artifact_run_id = workflow_run.get("id") if isinstance(workflow_run, dict) else run_id
name = artifact.get("name")
if (
isinstance(name, str)
and ARTIFACT_PATTERN.fullmatch(name) is not None
and artifact.get("expired") is False
and artifact_run_id == run_id
and isinstance(artifact.get("id"), int)
and isinstance(artifact.get("size_in_bytes"), int)
and 0 < artifact["size_in_bytes"] <= 1024 * 1024
):
matches.append(artifact)
return matches
def require_candidate_lane(
payload: dict[str, Any], run_id: int, base_ref: str
) -> dict[str, int | str] | None:
if base_ref == "main":
return select_candidate_artifact(payload, run_id)
if re.fullmatch(r"gd-ops/train/[A-Za-z0-9._-]+", base_ref) is None:
raise ValueError("merge base is not main or a managed train")
if candidate_artifacts(payload, run_id):
raise ValueError("task-to-train run must not contain a Release candidate artifact")
return None
def select_merge_ticket_artifact(
payload: dict[str, Any], run_id: int, run_attempt: int
) -> dict[str, int | str]:
artifacts = payload.get("artifacts")
if not isinstance(artifacts, list):
raise ValueError("artifact response is missing artifacts")
expected_name = f"ci-merge-ticket-{run_id}-{run_attempt}"
matches = []
for artifact in artifacts:
if not isinstance(artifact, dict):
continue
workflow_run = artifact.get("workflow_run")
artifact_run_id = workflow_run.get("id") if isinstance(workflow_run, dict) else run_id
if (
artifact.get("name") == expected_name
and artifact.get("expired") is False
and artifact_run_id == run_id
and isinstance(artifact.get("id"), int)
and isinstance(artifact.get("size_in_bytes"), int)
and 0 < artifact["size_in_bytes"] <= 256 * 1024
):
matches.append(artifact)
if len(matches) != 1:
raise ValueError("trusted PR run must contain exactly one current merge ticket")
selected = matches[0]
return {
"id": selected["id"],
"name": expected_name,
"size_in_bytes": selected["size_in_bytes"],
}
def create_merge_ticket(args: Namespace) -> None:
root = args.root.resolve()
require_identity(
args.repository,
{
"base commit": args.base_commit,
"head commit": args.head_commit,
"tested commit": args.tested_commit,
},
)
if args.pull_request_number <= 0 or args.run_id <= 0 or args.run_attempt <= 0:
raise ValueError("merge-ticket PR and run identities must be positive")
if HEAD_PATTERN.fullmatch(args.head_ref) is None:
raise ValueError("merge-ticket head is not a managed development branch")
expected_lane = (
"train-to-main"
if args.base_ref == "main" and args.head_ref.startswith("gd-ops/train/")
else "release-preparation-to-main"
if args.base_ref == "main" and args.head_ref.startswith("gd-ops/release/")
else "direct-to-main"
if args.base_ref == "main"
else "task-to-train"
if re.fullmatch(r"gd-ops/train/[A-Za-z0-9._-]+", args.base_ref)
else None
)
if expected_lane is None or args.lane != expected_lane:
raise ValueError("merge-ticket lane does not match its base and head")
if args.base_ref != "main" and args.full_candidate:
raise ValueError("task-to-train merge ticket cannot be a full candidate")
if run(root, "git", "rev-parse", "HEAD") != args.tested_commit:
raise ValueError("merge-ticket checkout does not match the tested commit")
payload = {
"schema_version": MERGE_TICKET_SCHEMA_VERSION,
"repository": args.repository,
"pull_request_number": args.pull_request_number,
"base_ref": args.base_ref,
"base_commit": args.base_commit,
"head_ref": args.head_ref,
"head_commit": args.head_commit,
"tested_commit": args.tested_commit,
"workflow_path": WORKFLOW_PATH,
"workflow_event": "pull_request",
"workflow_ref": f"refs/pull/{args.pull_request_number}/merge",
"run_id": args.run_id,
"run_attempt": args.run_attempt,
"lane": args.lane,
"full_candidate": args.full_candidate,
"ok": True,
}
atomic_write_json(args.output.resolve(), payload)
def validate_merge_ticket(args: Namespace) -> dict[str, Any]:
require_identity(
args.repository,
{"base commit": args.base_commit, "head commit": args.head_commit},
)
ticket = read_json_regular(args.ticket.resolve(), limit=256 * 1024)
if HEAD_PATTERN.fullmatch(args.head_ref) is None:
raise ValueError("merge-ticket head is not a managed development branch")
if args.base_ref != "main" and re.fullmatch(
r"gd-ops/train/[A-Za-z0-9._-]+", args.base_ref
) is None:
raise ValueError("merge-ticket base is not main or a managed train")
expected_keys = {
"schema_version", "repository", "pull_request_number", "base_ref",
"base_commit", "head_ref", "head_commit", "tested_commit",
"workflow_path", "workflow_event", "workflow_ref", "run_id",
"run_attempt", "lane", "full_candidate", "ok",
}
if not isinstance(ticket, dict) or set(ticket) != expected_keys:
raise ValueError("merge ticket field inventory is invalid")
expected_lane = (
"train-to-main"
if args.base_ref == "main" and args.head_ref.startswith("gd-ops/train/")
else "release-preparation-to-main"
if args.base_ref == "main" and args.head_ref.startswith("gd-ops/release/")
else "direct-to-main"
if args.base_ref == "main"
else "task-to-train"
)
checks = {
"schema_version": MERGE_TICKET_SCHEMA_VERSION,
"repository": args.repository,
"pull_request_number": args.pull_request_number,
"base_ref": args.base_ref,
"base_commit": args.base_commit,
"head_ref": args.head_ref,
"head_commit": args.head_commit,
"workflow_path": WORKFLOW_PATH,
"workflow_event": "pull_request",
"workflow_ref": f"refs/pull/{args.pull_request_number}/merge",
"run_id": args.run_id,
"run_attempt": args.run_attempt,
"lane": expected_lane,
"full_candidate": args.base_ref == "main",
"ok": True,
}
for key, expected in checks.items():
if ticket.get(key) != expected:
raise ValueError(f"merge ticket {key} does not match the current PR")
tested_commit = ticket.get("tested_commit")
if not isinstance(tested_commit, str):
raise ValueError("merge ticket tested commit is invalid")
require_commit(tested_commit, "merge-ticket tested commit")
return ticket
def create_candidate(args: Namespace) -> None:
root = args.root.resolve()
commits = {
"base commit": args.base_commit,
"head commit": args.head_commit,
"tested commit": args.tested_commit,
}
require_identity(args.repository, commits)
if args.pull_request_number <= 0 or args.run_id <= 0 or args.run_attempt <= 0:
raise ValueError("pull request and run identities must be positive")
if run(root, "git", "rev-parse", "HEAD") != args.tested_commit:
raise ValueError("candidate checkout does not match the tested commit")
parents = run(root, "git", "show", "-s", "--format=%P", "HEAD").split()
if parents != [args.base_commit, args.head_commit]:
raise ValueError("tested merge parents do not match PR base and head")
if run(root, "git", "status", "--porcelain", "--untracked-files=no"):
raise ValueError("candidate checkout contains tracked modifications")
attestation = args.attestation.resolve()
output = args.output.resolve()
if attestation.parent != output.parent:
raise ValueError("candidate proof files must share one artifact directory")
attestation_payload = validate_attestation(root, attestation, args.tested_commit)
payload: dict[str, Any] = {
"schema_version": SCHEMA_VERSION,
"repository": args.repository,
"pull_request_number": args.pull_request_number,
"base_commit": args.base_commit,
"head_commit": args.head_commit,
"tested_commit": args.tested_commit,
"source_tree": run(root, "git", "rev-parse", "HEAD^{tree}"),
"workflow_path": WORKFLOW_PATH,
"workflow_event": "pull_request",
"workflow_ref": f"refs/pull/{args.pull_request_number}/merge",
"run_id": args.run_id,
"run_attempt": args.run_attempt,
"gates": EXPECTED_GATES,
"toolchain_contract_digest": contract_digest(root),
"observed_toolchains": observed_toolchains(root),
"interaction_attestation_sha256": sha256(attestation),
"interaction_contract_digest": attestation_payload.get(
"interaction_contract_digest"
),
"ok": True,
}
atomic_write_json(output, payload)
inventory = sorted(child.name for child in output.parent.iterdir())
if inventory != ["candidate-proof.json", "interaction-attestation.json"]:
output.unlink(missing_ok=True)
raise ValueError("candidate proof artifact must contain exactly two files")
def validate_merge_candidate(args: Namespace) -> dict[str, str]:
require_identity(
args.repository,
{"base commit": args.base_commit, "head commit": args.head_commit},
)
proof_path = args.proof.resolve()
attestation_path = args.attestation.resolve()
if proof_path.parent != attestation_path.parent:
raise ValueError("candidate proof files must share one artifact directory")
inventory = []
for child in proof_path.parent.iterdir():
metadata = child.lstat()
if not stat.S_ISREG(metadata.st_mode) or child.is_symlink():
raise ValueError("candidate proof artifact contains a non-regular entry")
inventory.append(child.name)
if sorted(inventory) != ["candidate-proof.json", "interaction-attestation.json"]:
raise ValueError("candidate proof artifact must contain exactly two files")
proof = read_json_regular(proof_path)
expected_keys = {
"schema_version", "repository", "pull_request_number", "base_commit",
"head_commit", "tested_commit", "source_tree", "workflow_path",
"workflow_event", "workflow_ref", "run_id", "run_attempt", "gates",
"toolchain_contract_digest", "observed_toolchains",
"interaction_attestation_sha256", "interaction_contract_digest", "ok",
}
if not isinstance(proof, dict) or set(proof) != expected_keys:
raise ValueError("candidate proof field inventory is invalid")
checks = {
"schema_version": SCHEMA_VERSION,
"repository": args.repository,
"pull_request_number": args.pull_request_number,
"base_commit": args.base_commit,
"head_commit": args.head_commit,
"workflow_path": WORKFLOW_PATH,
"workflow_event": "pull_request",
"workflow_ref": f"refs/pull/{args.pull_request_number}/merge",
"run_id": args.run_id,
"run_attempt": args.run_attempt,
"gates": EXPECTED_GATES,
"ok": True,
}
for key, expected in checks.items():
if proof.get(key) != expected:
raise ValueError(f"candidate proof {key} does not match the merge request")
tested_commit = proof.get("tested_commit")
source_tree = proof.get("source_tree")
if not isinstance(tested_commit, str) or not isinstance(source_tree, str):
raise ValueError("candidate proof commit or tree is invalid")
require_commit(tested_commit, "candidate tested commit")
require_commit(source_tree, "candidate source tree")
tested_payload = args.tested_payload
if not isinstance(tested_payload, dict):
raise ValueError("tested commit API response must contain one object")
parents = tested_payload.get("parents")
parent_shas = [parent.get("sha") for parent in parents if isinstance(parent, dict)] \
if isinstance(parents, list) else []
tree = tested_payload.get("tree")
if tested_payload.get("sha") != tested_commit:
raise ValueError("tested merge commit does not match the candidate proof")
if parent_shas != [args.base_commit, args.head_commit]:
raise ValueError("tested merge parents do not match the current PR")
if not isinstance(tree, dict) or tree.get("sha") != source_tree:
raise ValueError("tested merge tree does not match the candidate proof")
if (
not isinstance(proof.get("toolchain_contract_digest"), str)
or DIGEST_PATTERN.fullmatch(proof["toolchain_contract_digest"]) is None
or not isinstance(proof.get("interaction_contract_digest"), str)
or DIGEST_PATTERN.fullmatch(proof["interaction_contract_digest"]) is None
):
raise ValueError("candidate proof contract digest is invalid")
observed = proof.get("observed_toolchains")
if not isinstance(observed, dict) or set(observed) != {"rustc", "swift", "python", "sdk"}:
raise ValueError("candidate proof observed toolchain inventory is invalid")
if any(not isinstance(value, str) or not value or len(value) > 4096 for value in observed.values()):
raise ValueError("candidate proof contains an invalid observed toolchain identity")
attestation = read_json_regular(attestation_path)
if not isinstance(attestation, dict):
raise ValueError("candidate interaction attestation is invalid")
if proof.get("interaction_attestation_sha256") != sha256(attestation_path):
raise ValueError("candidate interaction attestation digest is invalid")
if (
attestation.get("build_id") != f"source.{tested_commit}"
or attestation.get("interaction_contract_digest")
!= proof.get("interaction_contract_digest")
):
raise ValueError("candidate interaction attestation identity is invalid")
return {"tested_commit": tested_commit, "source_tree": source_tree}
def validate_candidate(args: Namespace) -> dict[str, int | str]:
root = args.root.resolve()
commits = {
"main commit": args.main_commit,
"main parent": args.main_parent,
"head commit": args.head_commit,
}
require_identity(args.repository, commits)
if args.pull_request_number <= 0 or args.run_id <= 0 or args.run_attempt <= 0:
raise ValueError("pull request and run identities must be positive")
if run(root, "git", "rev-parse", "HEAD") != args.main_commit:
raise ValueError("promotion checkout does not match the main commit")
main_parents = run(root, "git", "show", "-s", "--format=%P", "HEAD").split()
if main_parents != [args.main_parent]:
raise ValueError("main commit must be one squash commit over the push base")
require_unchanged_control_plane(root, args.main_parent, args.main_commit)
if run(root, "git", "status", "--porcelain", "--untracked-files=no"):
raise ValueError("promotion checkout contains tracked modifications")
main_tree = run(root, "git", "rev-parse", "HEAD^{tree}")
proof = read_json_regular(args.proof.resolve())
if not isinstance(proof, dict):
raise ValueError("candidate proof must contain one JSON object")
expected_keys = {
"schema_version", "repository", "pull_request_number", "base_commit",
"head_commit", "tested_commit", "source_tree", "workflow_path",
"workflow_event", "workflow_ref", "run_id", "run_attempt", "gates",
"toolchain_contract_digest", "observed_toolchains",
"interaction_attestation_sha256", "interaction_contract_digest", "ok",
}
if set(proof) != expected_keys:
raise ValueError("candidate proof field inventory is invalid")
tested_commit = proof.get("tested_commit")
if not isinstance(tested_commit, str):
raise ValueError("candidate proof tested commit is invalid")
require_commit(tested_commit, "tested commit")
checks = {
"schema_version": SCHEMA_VERSION,
"repository": args.repository,
"pull_request_number": args.pull_request_number,
"base_commit": args.main_parent,
"head_commit": args.head_commit,
"source_tree": main_tree,
"workflow_path": WORKFLOW_PATH,
"workflow_event": "pull_request",
"workflow_ref": f"refs/pull/{args.pull_request_number}/merge",
"run_id": args.run_id,
"run_attempt": args.run_attempt,
"gates": EXPECTED_GATES,
"toolchain_contract_digest": contract_digest(root),
"ok": True,
}
for key, expected in checks.items():
if proof.get(key) != expected:
raise ValueError(f"candidate proof {key} does not match main promotion")
tested_payload = read_json_regular(args.tested_commit_json.resolve(), limit=8 * 1024 * 1024)
if not isinstance(tested_payload, dict):
raise ValueError("tested commit API response must contain one object")
tree = tested_payload.get("tree")
parents = tested_payload.get("parents")
parent_shas = [parent.get("sha") for parent in parents if isinstance(parent, dict)] \
if isinstance(parents, list) else []
if tested_payload.get("sha") != tested_commit:
raise ValueError("tested merge commit does not match the candidate proof")
if parent_shas != [args.main_parent, args.head_commit]:
raise ValueError("tested merge parents do not match main parent and PR head")
if not isinstance(tree, dict) or tree.get("sha") != main_tree:
raise ValueError("tested merge tree does not match the main source tree")
observed = proof.get("observed_toolchains")
if not isinstance(observed, dict) or set(observed) != {"rustc", "swift", "python", "sdk"}:
raise ValueError("candidate proof observed toolchain inventory is invalid")
if any(not isinstance(value, str) or not value or len(value) > 4096 for value in observed.values()):
raise ValueError("candidate proof contains an invalid observed toolchain identity")
proof_path = args.proof.resolve()
attestation = args.attestation.resolve()
if proof_path.parent != attestation.parent:
raise ValueError("candidate proof files must share one artifact directory")
inventory = []
for child in proof_path.parent.iterdir():
metadata = child.lstat()
if not stat.S_ISREG(metadata.st_mode) or child.is_symlink():
raise ValueError("candidate proof artifact contains a non-regular entry")
inventory.append(child.name)
if sorted(inventory) != ["candidate-proof.json", "interaction-attestation.json"]:
raise ValueError("candidate proof artifact must contain exactly two files")
attestation_payload = validate_attestation(root, attestation, tested_commit)
if proof.get("interaction_attestation_sha256") != sha256(attestation):
raise ValueError("candidate proof interaction attestation digest is invalid")
if proof.get("interaction_contract_digest") != attestation_payload.get(
"interaction_contract_digest"
):
raise ValueError("candidate proof interaction contract digest is invalid")
return {
"validation_commit": tested_commit,
"validation_run_id": args.run_id,
"validation_run_attempt": args.run_attempt,
"validation_ref": f"refs/pull/{args.pull_request_number}/merge",
"candidate_proof_sha256": sha256(proof_path),
}
def api_json(endpoint: str, **fields: str) -> Any:
command = [
"gh", "api", "-X", "GET",
"-H", "Accept: application/vnd.github+json",
"-H", "X-GitHub-Api-Version: 2022-11-28",
endpoint,
]
for key, value in fields.items():
command.extend(["-f", f"{key}={value}"])
result = subprocess.run(command, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if len(result.stdout) > 8 * 1024 * 1024:
raise ValueError("GitHub API response exceeds the bounded input size")
return json.loads(result.stdout)
def api_bytes(endpoint: str, expected_size: int) -> bytes:
result = subprocess.run(
[
"gh", "api",
"-H", "Accept: application/vnd.github+json",
"-H", "X-GitHub-Api-Version: 2022-11-28",
endpoint,
],
check=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
if not result.stdout or len(result.stdout) > max(2 * 1024 * 1024, expected_size * 2):
raise ValueError("candidate artifact download is empty or unexpectedly large")
return result.stdout
def extract_archive(
data: bytes, destination: pathlib.Path, expected: set[str], limit: int
) -> None:
destination.mkdir(parents=True, exist_ok=False)
with zipfile.ZipFile(io.BytesIO(data)) as archive:
entries = archive.infolist()
if {entry.filename for entry in entries} != expected or len(entries) != len(expected):
raise ValueError("proof artifact archive inventory is invalid")
if sum(entry.file_size for entry in entries) > limit:
raise ValueError("proof artifact archive expands beyond its limit")
for entry in entries:
mode = entry.external_attr >> 16
if entry.is_dir() or (stat.S_IFMT(mode) not in (0, stat.S_IFREG)):
raise ValueError("candidate artifact archive contains a non-regular entry")
output = destination / entry.filename
output.write_bytes(archive.read(entry))
output.chmod(0o644)
def extract_candidate_archive(data: bytes, destination: pathlib.Path) -> None:
extract_archive(
data,
destination,
{"candidate-proof.json", "interaction-attestation.json"},
1024 * 1024,
)
def require_source_run(args: Namespace) -> None:
run_payload = api_json(f"repos/{args.repository}/actions/runs/{args.run_id}")
head_repository = run_payload.get("head_repository")
if not (
run_payload.get("id") == args.run_id
and run_payload.get("run_attempt") == args.run_attempt
and run_payload.get("status") == "completed"
and run_payload.get("conclusion") == "success"
and run_payload.get("event") == "pull_request"
and run_payload.get("head_sha") == args.head_commit
and run_payload.get("head_branch") == args.head_ref
and run_payload.get("path") == WORKFLOW_PATH
and isinstance(head_repository, dict)
and head_repository.get("full_name") == args.repository
):
raise ValueError("merge source is not the exact successful trusted PR CI run")
require_required_gate(
api_json(
f"repos/{args.repository}/actions/runs/{args.run_id}/jobs",
filter="latest",
per_page="100",
)
)
def require_no_control_plane_change(repository: str, pull_request_number: int) -> None:
if REPOSITORY_PATTERN.fullmatch(repository) is None or pull_request_number <= 0:
raise ValueError("control-plane PR identity is invalid")
if CONTROL_PLANE_FILES != sorted(set(CONTROL_PLANE_FILES)):
raise ValueError("CI proof control-plane inventory is invalid")
changed = []
for page in range(1, 11):
payload = api_json(
f"repos/{repository}/pulls/{pull_request_number}/files",
per_page="100",
page=str(page),
)
if not isinstance(payload, list):
raise ValueError("pull-request files response must contain one list")
for entry in payload:
if not isinstance(entry, dict):
continue
for key in ("filename", "previous_filename"):
filename = entry.get(key)
if isinstance(filename, str) and filename in CONTROL_PLANE_FILES:
changed.append(filename)
if len(payload) < 100:
break
else:
raise ValueError("pull request file inventory exceeds the trusted merge limit")
if changed:
raise ValueError(
"CI proof control plane changes require trusted manual merge: "
+ ", ".join(sorted(set(changed)))
)
def verify_merge_source(args: Namespace) -> dict[str, Any]:
require_identity(
args.repository,
{"base commit": args.base_commit, "head commit": args.head_commit},
)
if args.pull_request_number <= 0 or args.run_id <= 0 or args.run_attempt <= 0:
raise ValueError("merge source PR and run identities must be positive")
if HEAD_PATTERN.fullmatch(args.head_ref) is None:
raise ValueError("merge source head is not a managed development branch")
if args.base_ref != "main" and re.fullmatch(
r"gd-ops/train/[A-Za-z0-9._-]+", args.base_ref
) is None:
raise ValueError("merge source base is not main or a managed train")
require_no_control_plane_change(args.repository, args.pull_request_number)
require_source_run(args)
artifacts_payload = api_json(
f"repos/{args.repository}/actions/runs/{args.run_id}/artifacts",
per_page="100",
)
ticket_artifact = select_merge_ticket_artifact(
artifacts_payload, args.run_id, args.run_attempt
)
candidate_artifact = require_candidate_lane(
artifacts_payload, args.run_id, args.base_ref
)
with tempfile.TemporaryDirectory(prefix="apc-ci-merge-source-") as directory:
temporary = pathlib.Path(directory)
ticket_dir = temporary / "ticket"
extract_archive(
api_bytes(
f"repos/{args.repository}/actions/artifacts/{ticket_artifact['id']}/zip",
int(ticket_artifact["size_in_bytes"]),
),
ticket_dir,
{"merge-ticket.json"},
256 * 1024,
)
ticket = validate_merge_ticket(
Namespace(
repository=args.repository,
pull_request_number=args.pull_request_number,
base_ref=args.base_ref,
base_commit=args.base_commit,
head_ref=args.head_ref,
head_commit=args.head_commit,
run_id=args.run_id,
run_attempt=args.run_attempt,
ticket=ticket_dir / "merge-ticket.json",
)
)
ticket_tested_payload = api_json(
f"repos/{args.repository}/git/commits/{ticket['tested_commit']}"
)
ticket_parents = ticket_tested_payload.get("parents")
ticket_parent_shas = [
parent.get("sha") for parent in ticket_parents if isinstance(parent, dict)
] if isinstance(ticket_parents, list) else []
if (
ticket_tested_payload.get("sha") != ticket["tested_commit"]
or ticket_parent_shas != [args.base_commit, args.head_commit]
):
raise ValueError("merge-ticket tested commit does not bind current base and head")
if candidate_artifact is not None:
candidate_dir = temporary / "candidate"
extract_candidate_archive(
api_bytes(
f"repos/{args.repository}/actions/artifacts/{candidate_artifact['id']}/zip",
int(candidate_artifact["size_in_bytes"]),
),
candidate_dir,
)
tested_payload = api_json(
f"repos/{args.repository}/git/commits/{candidate_artifact['tested_commit']}"
)
candidate = validate_merge_candidate(
Namespace(
repository=args.repository,
pull_request_number=args.pull_request_number,
base_commit=args.base_commit,
head_commit=args.head_commit,
run_id=args.run_id,
run_attempt=args.run_attempt,
tested_payload=tested_payload,
attestation=candidate_dir / "interaction-attestation.json",
proof=candidate_dir / "candidate-proof.json",
)
)
if ticket["tested_commit"] != candidate["tested_commit"]:
raise ValueError("merge ticket and candidate proof tested commits differ")
return {
"lane": ticket["lane"],
"tested_commit": ticket["tested_commit"],
"full_candidate": ticket["full_candidate"],
}
def promote(args: Namespace) -> dict[str, int | str]:
root = args.root.resolve()
require_identity(args.repository, {"main commit": args.main_commit, "main parent": args.main_parent})
pull = select_merged_pull(
api_json(f"repos/{args.repository}/commits/{args.main_commit}/pulls", per_page="100"),
args.repository,
args.main_commit,
)
selected_run = select_successful_run(
api_json(
f"repos/{args.repository}/actions/workflows/ci.yml/runs",
event="pull_request",
head_sha=str(pull["head_sha"]),
per_page="100",
),
args.repository,
str(pull["head_sha"]),
str(pull["head_ref"]),
)
run_id = selected_run["run_id"]
require_required_gate(
api_json(f"repos/{args.repository}/actions/runs/{run_id}/jobs", filter="latest", per_page="100")
)
artifact = select_candidate_artifact(
api_json(f"repos/{args.repository}/actions/runs/{run_id}/artifacts", per_page="100"),
run_id,
)
tested_payload = api_json(
f"repos/{args.repository}/git/commits/{artifact['tested_commit']}"
)
with tempfile.TemporaryDirectory(prefix="apc-ci-promotion-") as directory:
temporary = pathlib.Path(directory)
artifact_dir = temporary / "candidate"
extract_candidate_archive(
api_bytes(
f"repos/{args.repository}/actions/artifacts/{artifact['id']}/zip",
int(artifact["size_in_bytes"]),
),
artifact_dir,
)
tested_commit_json = temporary / "tested-commit.json"
atomic_write_json(tested_commit_json, tested_payload)
metadata = validate_candidate(
Namespace(
root=root,
repository=args.repository,
main_commit=args.main_commit,
main_parent=args.main_parent,
pull_request_number=int(pull["number"]),
head_commit=str(pull["head_sha"]),
run_id=run_id,
run_attempt=selected_run["run_attempt"],
tested_commit_json=tested_commit_json,
attestation=artifact_dir / "interaction-attestation.json",
proof=artifact_dir / "candidate-proof.json",
)
)
candidate_attestation = args.candidate_attestation.resolve()
candidate_attestation.parent.mkdir(parents=True, exist_ok=True)
shutil.copyfile(artifact_dir / "interaction-attestation.json", candidate_attestation)
candidate_attestation.chmod(0o644)
atomic_write_json(args.metadata.resolve(), metadata)
return metadata
def promotion_failure_category(error: BaseException) -> str:
"""Map promotion failures to a closed, non-sensitive observability category."""
message = str(error).lower()
if "control plane changed" in message:
return "control-plane-change"
if "expired" in message:
return "expired"
if "ambiguous" in message or "exactly one" in message or "multiple" in message:
return "ambiguous"
if any(token in message for token in ("tree", "parents", "does not match", "mismatch")):
return "tree-mismatch"
if any(token in message for token in ("artifact", "proof", "attestation")):
return "missing-artifact"
return "unavailable"
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument(
"--root", type=pathlib.Path, default=pathlib.Path(__file__).resolve().parent.parent
)
subparsers = parser.add_subparsers(dest="command", required=True)
create_parser = subparsers.add_parser("create-candidate")
create_parser.add_argument("--repository", required=True)
create_parser.add_argument("--pull-request-number", required=True, type=int)
create_parser.add_argument("--base-commit", required=True)
create_parser.add_argument("--head-commit", required=True)
create_parser.add_argument("--tested-commit", required=True)
create_parser.add_argument("--run-id", required=True, type=int)
create_parser.add_argument("--run-attempt", required=True, type=int)
create_parser.add_argument("--attestation", required=True, type=pathlib.Path)
create_parser.add_argument("--output", required=True, type=pathlib.Path)
ticket_parser = subparsers.add_parser("create-merge-ticket")
ticket_parser.add_argument("--repository", required=True)
ticket_parser.add_argument("--pull-request-number", required=True, type=int)
ticket_parser.add_argument("--base-ref", required=True)
ticket_parser.add_argument("--base-commit", required=True)
ticket_parser.add_argument("--head-ref", required=True)
ticket_parser.add_argument("--head-commit", required=True)
ticket_parser.add_argument("--tested-commit", required=True)
ticket_parser.add_argument("--run-id", required=True, type=int)
ticket_parser.add_argument("--run-attempt", required=True, type=int)
ticket_parser.add_argument(
"--lane", required=True,
choices=(
"direct-to-main",
"task-to-train",
"train-to-main",
"release-preparation-to-main",
),
)
ticket_parser.add_argument("--full-candidate", required=True, choices=("0", "1"))
ticket_parser.add_argument("--output", required=True, type=pathlib.Path)
verify_parser = subparsers.add_parser("verify-merge-source")
verify_parser.add_argument("--repository", required=True)
verify_parser.add_argument("--pull-request-number", required=True, type=int)
verify_parser.add_argument("--base-ref", required=True)
verify_parser.add_argument("--base-commit", required=True)
verify_parser.add_argument("--head-ref", required=True)
verify_parser.add_argument("--head-commit", required=True)
verify_parser.add_argument("--run-id", required=True, type=int)
verify_parser.add_argument("--run-attempt", required=True, type=int)
cleanup_parser = subparsers.add_parser("delete-merged-head")
cleanup_parser.add_argument("--repository", required=True)
cleanup_parser.add_argument("--pull-request-number", required=True, type=int)
cleanup_parser.add_argument("--head-ref", required=True)
cleanup_parser.add_argument("--head-commit", required=True)
cleanup_parser.add_argument("--allow-delete", required=True, choices=("0", "1"))
promote_parser = subparsers.add_parser("promote")
promote_parser.add_argument("--repository", required=True)
promote_parser.add_argument("--main-commit", required=True)
promote_parser.add_argument("--main-parent", required=True)
promote_parser.add_argument("--candidate-attestation", required=True, type=pathlib.Path)
promote_parser.add_argument("--metadata", required=True, type=pathlib.Path)
promote_parser.add_argument("--failure-metadata", type=pathlib.Path)
args = parser.parse_args()
try:
if args.command == "create-candidate":
create_candidate(args)
elif args.command == "create-merge-ticket":
args.full_candidate = args.full_candidate == "1"
create_merge_ticket(args)
elif args.command == "verify-merge-source":
print(json.dumps(verify_merge_source(args), sort_keys=True))
elif args.command == "delete-merged-head":
args.allow_delete = args.allow_delete == "1"
print(json.dumps(delete_merged_head(args), sort_keys=True))
else:
promote(args)
except (
OSError,
ValueError,
json.JSONDecodeError,
subprocess.CalledProcessError,
zipfile.BadZipFile,
) as error:
if args.command == "promote" and args.failure_metadata is not None:
atomic_write_json(
args.failure_metadata.resolve(),
{"category": promotion_failure_category(error), "promoted": 0},
)
print(f"CI proof promotion unavailable: {error}", file=sys.stderr)
return 1
return 0
if __name__ == "__main__":
raise SystemExit(main())