This commit is contained in:
2026-08-18 09:20:44 +02:00
commit b826cd721a
522 changed files with 93730 additions and 0 deletions
+845
View File
@@ -0,0 +1,845 @@
#!/bin/sh
set -eu
umask 022
gate_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd -P)
root=$(CDPATH= cd -- "$gate_dir/../../../.." && pwd -P)
input=$gate_dir/P15-027-input.json
freebsd_src=${FREEBSD_SRC:-/work/build/freebsd-src}
base=
output=
deadline=120
while test "$#" -gt 0; do
case "$1" in
--base)
test "$#" -ge 2 || { printf '%s\n' '--base requires a commit' >&2; exit 20; }
base=$2
shift 2
;;
--freebsd-src)
test "$#" -ge 2 || { printf '%s\n' '--freebsd-src requires a directory' >&2; exit 20; }
freebsd_src=$2
shift 2
;;
--output)
test "$#" -ge 2 || { printf '%s\n' '--output requires a directory' >&2; exit 20; }
output=$2
shift 2
;;
*)
printf 'unknown argument: %s\n' "$1" >&2
exit 20
;;
esac
done
test -n "$base" || { printf '%s\n' '--base is required' >&2; exit 20; }
test -n "$output" || { printf '%s\n' '--output is required' >&2; exit 20; }
test -f "$input" || { printf 'missing input: %s\n' "$input" >&2; exit 20; }
for tool in date git mktemp patch python3 sha256sum timeout; do
command -v "$tool" >/dev/null 2>&1 || {
printf 'missing required host tool: %s\n' "$tool" >&2
exit 21
}
done
case "$output" in
/*) ;;
*) output=$PWD/$output ;;
esac
case "$freebsd_src" in
/*) ;;
*) freebsd_src=$PWD/$freebsd_src ;;
esac
test ! -e "$output" || { printf 'refusing existing output: %s\n' "$output" >&2; exit 20; }
mkdir -p "$output"
work=$(mktemp -d "${TMPDIR:-/tmp}/P15-027.XXXXXX")
cleanup_trap()
{
rm -rf -- "$work"
}
trap cleanup_trap EXIT HUP INT TERM
python3 -B - "$output/command-argv.json" "$0" --base "$base" \
--freebsd-src "$freebsd_src" --output "$output" <<'PY'
import json
from pathlib import Path
import sys
Path(sys.argv[1]).write_text(
json.dumps(sys.argv[2:], ensure_ascii=True, separators=(",", ":")) + "\n",
encoding="ascii",
)
PY
python3 -B - "$output/ownership.json" "$work" "$output" <<'PY'
import json
from pathlib import Path
import sys
Path(sys.argv[1]).write_text(
json.dumps(
{
"owned_temporary_paths": [sys.argv[2]],
"persistent_output": sys.argv[3],
"owned_processes": [],
"owned_ports": [],
"qemu": "NOT_RUN",
"protected_resources_addressed": False,
},
ensure_ascii=True,
indent=2,
sort_keys=True,
) + "\n",
encoding="ascii",
)
PY
set +e
timeout -k 5 "$deadline" python3 -B - \
"$root" "$input" "$base" "$freebsd_src" "$output" "$work" "$deadline" <<'PY' \
>"$output/stdout.log" 2>"$output/stderr.log"
from __future__ import annotations
import hashlib
import json
import os
from pathlib import Path
import platform
import re
import shutil
import subprocess
import sys
import tarfile
from typing import Any
ROOT = Path(sys.argv[1])
INPUT = Path(sys.argv[2])
REQUESTED_BASE = sys.argv[3]
FREEBSD_SRC = Path(sys.argv[4])
OUTPUT = Path(sys.argv[5])
WORK = Path(sys.argv[6])
DEADLINE = int(sys.argv[7])
SPEC = json.loads(INPUT.read_text(encoding="utf-8"))
class GateFailure(RuntimeError):
def __init__(self, status: str, reason: str):
super().__init__(reason)
self.status = status
self.reason = reason
def sha256_bytes(data: bytes) -> str:
return hashlib.sha256(data).hexdigest()
def sha256_path(path: Path) -> str:
return sha256_bytes(path.read_bytes())
def write_json(path: Path, value: Any) -> None:
path.write_text(
json.dumps(value, ensure_ascii=True, indent=2, sort_keys=True) + "\n",
encoding="ascii",
)
def run(
argv: list[str],
*,
cwd: Path | None = None,
input_bytes: bytes | None = None,
allowed: set[int] | None = None,
timeout_seconds: int = 30,
) -> subprocess.CompletedProcess[bytes]:
try:
completed = subprocess.run(
argv,
cwd=cwd,
check=False,
input=input_bytes,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
timeout=timeout_seconds,
)
except subprocess.TimeoutExpired as error:
raise GateFailure(
"INFRA_BLOCKED", f"command timed out: {' '.join(argv)}"
) from error
accepted = {0} if allowed is None else allowed
if completed.returncode not in accepted:
detail = completed.stderr.decode("utf-8", errors="replace").strip()
raise GateFailure(
"RUNNER_FAIL",
f"command failed ({completed.returncode}): {' '.join(argv)}: {detail}",
)
return completed
def git_text(repository: Path, *args: str) -> str:
return run(["git", "-C", str(repository), *args]).stdout.decode(
"utf-8", errors="strict"
).strip()
def source_at(commit: str, relative: str) -> bytes:
return run(
["git", "-C", str(ROOT), "show", f"{commit}:{relative}"]
).stdout
def safe_relative_path(value: str) -> Path:
path = Path(value)
if path.is_absolute() or ".." in path.parts:
raise GateFailure("RUNNER_FAIL", f"unsafe declared path: {value}")
if path.name == "introduction.md":
raise GateFailure("RUNNER_FAIL", "prohibited path declaration")
return path
def validate_hash(value: Any, label: str) -> str:
if not isinstance(value, str) or re.fullmatch(r"[0-9a-f]{64}", value) is None:
raise GateFailure("RUNNER_FAIL", f"invalid SHA-256 for {label}")
return value
def validate_runtime_item(item: Any, item_id: str) -> None:
if not isinstance(item, dict):
raise GateFailure("RUNNER_FAIL", f"runtime item is not an object: {item_id}")
expected = {
"status": "PASS",
"exit_code": 0,
"target_marker": "reached",
"cleanup": "PASS",
}
for key, value in expected.items():
if item.get(key) != value:
raise GateFailure("RUNNER_FAIL", f"runtime item {item_id} has invalid {key}")
argv = item.get("command_argv")
if not isinstance(argv, list) or not argv or not all(isinstance(v, str) for v in argv):
raise GateFailure("RUNNER_FAIL", f"runtime item {item_id} lacks exact argv")
if not isinstance(item.get("deadline_seconds"), int) or item["deadline_seconds"] <= 0:
raise GateFailure("RUNNER_FAIL", f"runtime item {item_id} lacks deadline")
for stream in ("stdout", "stderr"):
relative = safe_relative_path(item.get(stream, ""))
evidence_path = OUTPUT / relative
if not evidence_path.is_file():
raise GateFailure("RUNNER_FAIL", f"runtime item {item_id} lacks {stream}")
expected_hash = validate_hash(item.get(f"{stream}_sha256"), f"{item_id} {stream}")
if sha256_path(evidence_path) != expected_hash:
raise GateFailure("RUNNER_FAIL", f"runtime item {item_id} {stream} hash mismatch")
def validate_runtime_record(
path: Path,
architecture: dict[str, Any],
modules: dict[str, dict[str, Any]],
resolved_base: str,
patch_sha256: str,
) -> dict[str, Any]:
record = json.loads(path.read_text(encoding="utf-8"))
expected_identity = {
"schema": 1,
"architecture": architecture["id"],
"uname_s": "FreeBSD",
"uname_m": architecture["expected_uname_m"],
"uname_p": architecture["expected_uname_p"],
"dut_base": resolved_base,
"temporary_patch_sha256": patch_sha256,
"freebsd_source_head": SPEC["freebsd_source"]["head"],
}
for key, value in expected_identity.items():
if record.get(key) != value:
raise GateFailure("RUNNER_FAIL", f"native record identity mismatch: {key}")
if record.get("status") not in {"PASS", "DUT_FAIL"}:
raise GateFailure("RUNNER_FAIL", "native record status is not authoritative")
if record.get("cleanup") != "PASS" or record.get("target_marker") != "reached":
raise GateFailure("RUNNER_FAIL", "native record did not reach target with cleanup")
if record.get("module_sha256") != {
name: value["sha256"] for name, value in modules.items()
}:
raise GateFailure("RUNNER_FAIL", "native module hashes differ from cross artifacts")
fixtures = record.get("fixture_sha256")
if not isinstance(fixtures, list) or len(fixtures) < 4:
raise GateFailure("RUNNER_FAIL", "native record lacks four fixture hashes")
for index, value in enumerate(fixtures):
validate_hash(value, f"native fixture {index}")
capability = record.get("kernel_zstdio")
validate_runtime_item(capability, "kernel-zstdio-capability")
if capability.get("options_zstdio") is not True:
raise GateFailure("RUNNER_FAIL", "native ZSTDIO capability is not enabled")
operations = record.get("operations")
if not isinstance(operations, dict):
raise GateFailure("RUNNER_FAIL", "native operations are absent")
required = SPEC["native_runtime_contract"]["required_operations"]
if set(operations) != set(required):
raise GateFailure("RUNNER_FAIL", "native operation set is not exact")
for item_id in required:
validate_runtime_item(operations[item_id], item_id)
disabled = operations["zstdio0-zstd-read"]
if disabled.get("errno") != "EOPNOTSUPP":
raise GateFailure("RUNNER_FAIL", "disabled native Zstd errno is not EOPNOTSUPP")
return record
def extract_repo_source(resolved_base: str, destination: Path) -> None:
archive = run(
[
"git", "-C", str(ROOT), "archive", "--format=tar", resolved_base,
"repo-pre-15/src", "repo-pre-15/tests/pre15/probes/ondisk_layout.c",
],
timeout_seconds=60,
).stdout
destination.mkdir(parents=True)
archive_path = WORK / "repo-source.tar"
archive_path.write_bytes(archive)
with tarfile.open(archive_path, mode="r:") as tar:
tar.extractall(destination, filter="data")
def compile_architecture(
architecture: dict[str, Any],
resolved_base: str,
patch_bytes: bytes,
compiler: Path,
) -> dict[str, Any]:
arch_id = architecture["id"]
arch_root = WORK / "cross" / arch_id
source_root = arch_root / "source"
extract_repo_source(resolved_base, source_root)
run(["patch", "-p1"], cwd=source_root, input_bytes=patch_bytes)
src = source_root / "repo-pre-15/src"
sys_root = FREEBSD_SRC / "sys"
resource_include = Path(
run([str(compiler), "-print-resource-dir"]).stdout.decode("ascii").strip()
) / "include"
common_flags = [
"-O2", "-pipe", "-fno-common", "-fno-strict-aliasing", "-D_KERNEL",
"-DKLD_MODULE", "-nostdinc", "-ffreestanding", "-fwrapv",
"-fno-asynchronous-unwind-tables", "-fno-omit-frame-pointer",
"-fstack-protector", "-Wall", "-Wstrict-prototypes",
"-Wmissing-prototypes", "-Wpointer-arith", "-Wcast-qual", "-Wundef",
"-Wno-pointer-sign", "-Wmissing-include-dirs", "-Wno-unknown-pragmas",
"-Wno-address-of-packed-member", "-Wno-format-zero-length", "-std=gnu17",
"-D__printf__=__freebsd_kprintf__", f"--target={architecture['target_triple']}",
*architecture["kernel_cflags"],
]
modules: dict[str, dict[str, Any]] = {}
for zstdio in (0, 1):
build = arch_root / f"zstdio{zstdio}"
build.mkdir(parents=True)
(build / "opt_global.h").write_bytes(b"")
(build / "machine").symlink_to(sys_root / architecture["machine_header_dir"] / "include")
for alias, relative in architecture["header_aliases"].items():
(build / alias).symlink_to(sys_root / relative)
for mode in ("-p", "-q", "-h"):
generated = run(
["awk", "-f", str(sys_root / "tools/vnode_if.awk"),
str(sys_root / "kern/vnode_if.src"), mode],
cwd=build,
).stdout
suffix = {"-p": "vnode_if_newproto.h", "-q": "vnode_if_typedef.h", "-h": "vnode_if.h"}[mode]
(build / suffix).write_bytes(generated)
include_flags = [
"-include", str(build / "opt_global.h"), "-I", str(build),
"-I", str(sys_root), "-I", str(sys_root / "contrib/ck/include"),
]
objects = []
stdout_parts = []
stderr_parts = []
for source_name in SPEC["cross_build_contract"]["module_sources"]:
obj = build / f"{Path(source_name).stem}.o"
argv = [str(compiler), *common_flags, *include_flags]
if source_name == "decompressor_zstd.c":
argv.extend(["-I", str(sys_root / "contrib/zstd/lib/freebsd")])
if zstdio == 1:
argv.append("-DZSTDIO")
argv.extend(["-c", str(src / source_name), "-o", str(obj)])
completed = run(argv, cwd=build, timeout_seconds=60)
stdout_parts.append(completed.stdout)
stderr_parts.append(completed.stderr)
objects.append(obj)
module = build / "erofs.ko"
linked = run(
[str(compiler), f"--target={architecture['target_triple']}",
"-r", "-nostdlib", *map(str, objects), "-o", str(module)],
cwd=build,
timeout_seconds=60,
)
stdout_parts.append(linked.stdout)
stderr_parts.append(linked.stderr)
nm_output = run(["nm", "-u", str(module)]).stdout
(build / "build.stdout").write_bytes(b"".join(stdout_parts))
(build / "build.stderr").write_bytes(b"".join(stderr_parts))
(build / "nm-u.txt").write_bytes(nm_output)
modules[f"zstdio{zstdio}"] = {
"path": str(module),
"sha256": sha256_path(module),
"size_bytes": module.stat().st_size,
"nm_u_sha256": sha256_bytes(nm_output),
}
probe_root = arch_root / "probes"
probe_root.mkdir()
include_root = probe_root / "include"
include_root.mkdir()
(include_root / "machine").symlink_to(
sys_root / architecture["machine_header_dir"] / "include"
)
for alias, relative in architecture["header_aliases"].items():
(include_root / alias).symlink_to(sys_root / relative)
probe_flags = [
f"--target={architecture['target_triple']}", "-std=gnu17", "-nostdinc",
"-isystem", str(resource_include), "-isystem", str(FREEBSD_SRC / "include"),
"-isystem", str(include_root), "-isystem", str(sys_root),
]
layout = source_root / "repo-pre-15/tests/pre15/probes/ondisk_layout.c"
layout_result = run(
[str(compiler), *probe_flags, "-Wall", "-Wextra", "-Werror",
"-fsyntax-only", "-Xclang", "-fdump-record-layouts", str(layout)],
timeout_seconds=60,
)
(probe_root / "layout.stdout").write_bytes(layout_result.stdout)
(probe_root / "layout.stderr").write_bytes(layout_result.stderr)
unaligned = probe_root / "unaligned-endian.c"
unaligned.write_text(
SPEC["cross_build_contract"]["unaligned_endian_probe_source"],
encoding="ascii",
)
assembly = probe_root / "unaligned-endian.s"
endian_result = run(
[str(compiler), *probe_flags, *architecture["kernel_cflags"],
"-O2", "-S", str(unaligned), "-o", str(assembly)],
timeout_seconds=60,
)
(probe_root / "unaligned-endian.stdout").write_bytes(endian_result.stdout)
(probe_root / "unaligned-endian.stderr").write_bytes(endian_result.stderr)
if assembly.stat().st_size == 0:
raise GateFailure("RUNNER_FAIL", f"empty unaligned/endian probe for {arch_id}")
return {
"status": "PASS",
"temporary_source": str(source_root),
"modules": modules,
"layout_probe_sha256": sha256_path(layout),
"layout_output_sha256": sha256_bytes(layout_result.stdout),
"unaligned_endian_probe_sha256": sha256_path(unaligned),
"unaligned_endian_assembly_sha256": sha256_path(assembly),
}
def render_argv(values: list[str], substitutions: dict[str, str]) -> list[str]:
rendered = []
for value in values:
for key, replacement in substitutions.items():
value = value.replace("{" + key + "}", replacement)
rendered.append(value)
return rendered
def run_native(
architecture: dict[str, Any],
declaration: dict[str, Any],
modules: dict[str, dict[str, Any]],
resolved_base: str,
patch_sha256: str,
) -> dict[str, Any]:
runner_relative = safe_relative_path(declaration.get("runner_path", ""))
runner = ROOT / runner_relative
if not runner.is_file():
raise GateFailure("INFRA_BLOCKED", f"declared native runner is absent: {runner_relative}")
if sha256_path(runner) != validate_hash(
declaration.get("runner_sha256"), f"{architecture['id']} runner"
):
raise GateFailure("INFRA_BLOCKED", "declared native runner identity changed")
native_output = OUTPUT / "native" / architecture["id"]
native_output.mkdir(parents=True)
substitutions = {
"runner": str(runner),
"architecture": architecture["id"],
"module_zstdio0": modules["zstdio0"]["path"],
"module_zstdio1": modules["zstdio1"]["path"],
"output": str(native_output),
}
preflight_argv = render_argv(declaration["preflight_argv"], substitutions)
preflight = run(
preflight_argv,
cwd=ROOT,
timeout_seconds=declaration["preflight_deadline_seconds"],
)
(native_output / "preflight.runner.stdout").write_bytes(preflight.stdout)
(native_output / "preflight.runner.stderr").write_bytes(preflight.stderr)
preflight_record = json.loads(
(native_output / "preflight.json").read_text(encoding="utf-8")
)
for key, value in {
"status": "PASS", "exit_code": 0, "target_marker": "reached",
"cleanup": "PASS", "uname_s": "FreeBSD",
"uname_m": architecture["expected_uname_m"],
"uname_p": architecture["expected_uname_p"],
}.items():
if preflight_record.get(key) != value:
raise GateFailure("INFRA_BLOCKED", f"native preflight mismatch: {key}")
runtime_argv = render_argv(declaration["runtime_argv"], substitutions)
runtime = run(
runtime_argv,
cwd=ROOT,
allowed={0, 10},
timeout_seconds=declaration["runtime_deadline_seconds"],
)
(native_output / "runner.stdout").write_bytes(runtime.stdout)
(native_output / "runner.stderr").write_bytes(runtime.stderr)
return validate_runtime_record(
native_output / "runtime-result.json",
architecture,
modules,
resolved_base,
patch_sha256,
)
def main() -> int:
if SPEC.get("schema") != 1 or SPEC.get("candidate") != "P15-027":
raise GateFailure("RUNNER_FAIL", "invalid P15-027 input identity")
if SPEC.get("gate") != "G07" or SPEC.get("batch") != "B36":
raise GateFailure("RUNNER_FAIL", "invalid G07/B36 input identity")
if SPEC.get("prohibited_paths") != ["introduction.md"]:
raise GateFailure("RUNNER_FAIL", "prohibited-path contract changed")
resolved = git_text(ROOT, "rev-parse", f"{REQUESTED_BASE}^{{commit}}")
if resolved != SPEC["required_base"]:
raise GateFailure(
"INFRA_BLOCKED", f"P15-027 must replay {SPEC['required_base']}, got {resolved}"
)
source_tree = git_text(ROOT, "rev-parse", f"{resolved}:repo-pre-15/src")
if source_tree != SPEC["repo_source_tree_oid"]:
raise GateFailure("INFRA_BLOCKED", "frozen EROFS source tree changed")
source_hashes = {
path: sha256_bytes(source_at(resolved, path))
for path in SPEC["source_sha256"]
}
if source_hashes != SPEC["source_sha256"]:
raise GateFailure("INFRA_BLOCKED", "frozen gate source identity changed")
write_json(OUTPUT / "source-sha256.json", source_hashes)
addendum_paths = (
"repo-pre-15/tests/pre15/gates/P15-027.sh",
"repo-pre-15/tests/pre15/gates/P15-027-input.json",
"repo-pre-15/docs/pre15-stage0/P15-027.md",
)
addendum_hashes = {
path: sha256_path(ROOT / path) for path in addendum_paths
}
write_json(OUTPUT / "gate-addendum-sha256.json", addendum_hashes)
if sha256_path(ROOT / "repo-pre-15/src/Makefile") != SPEC["source_sha256"]["repo-pre-15/src/Makefile"]:
raise GateFailure("RUNNER_FAIL", "production Makefile differs from frozen BASE")
patch_spec = SPEC["temporary_makefile_relaxation"]
patch_bytes = patch_spec["unified_diff"].encode("ascii")
if sha256_bytes(patch_bytes) != patch_spec["sha256"]:
raise GateFailure("RUNNER_FAIL", "input-recorded temporary patch hash mismatch")
patch_check = WORK / "patch-check"
makefile_copy = patch_check / "repo-pre-15/src/Makefile"
makefile_copy.parent.mkdir(parents=True)
makefile_copy.write_bytes(source_at(resolved, patch_spec["path"]))
patch_result = run(["patch", "-p1"], cwd=patch_check, input_bytes=patch_bytes)
(OUTPUT / "makefile-relaxation.patch").write_bytes(patch_bytes)
(OUTPUT / "patch.stdout").write_bytes(patch_result.stdout)
(OUTPUT / "patch.stderr").write_bytes(patch_result.stderr)
if sha256_path(makefile_copy) != patch_spec["patched_makefile_sha256"]:
raise GateFailure("RUNNER_FAIL", "temporary Makefile relaxation result changed")
patch_record = {
"path": patch_spec["path"],
"sha256": patch_spec["sha256"],
"patched_makefile_sha256": sha256_path(makefile_copy),
"production_makefile_changed": False,
"temporary_apply": "PASS",
}
write_json(OUTPUT / "temporary-patch.json", patch_record)
if not FREEBSD_SRC.is_dir():
raise GateFailure("INFRA_BLOCKED", f"FreeBSD source is absent: {FREEBSD_SRC}")
freebsd = SPEC["freebsd_source"]
freebsd_head = git_text(FREEBSD_SRC, "rev-parse", "HEAD")
freebsd_prefix = git_text(FREEBSD_SRC, "rev-parse", "--show-prefix")
if freebsd_head != freebsd["head"] or freebsd_prefix != freebsd["git_prefix"]:
raise GateFailure("INFRA_BLOCKED", "FreeBSD source identity changed")
git_root = Path(git_text(FREEBSD_SRC, "rev-parse", "--show-toplevel"))
freebsd_source_tree = git_text(
git_root, "rev-parse", f"{freebsd_head}:{freebsd['git_tree_path']}"
)
freebsd_sys_tree = git_text(
git_root, "rev-parse", f"{freebsd_head}:{freebsd['git_tree_path']}/sys"
)
if freebsd_source_tree != freebsd["source_tree_oid"] or freebsd_sys_tree != freebsd["sys_tree_oid"]:
raise GateFailure("INFRA_BLOCKED", "FreeBSD source tree object changed")
freebsd_hashes = {
path: sha256_path(FREEBSD_SRC / path) for path in freebsd["sha256"]
}
if freebsd_hashes != freebsd["sha256"]:
raise GateFailure("INFRA_BLOCKED", "selected FreeBSD source hashes changed")
compiler_path = Path(shutil.which("clang") or "").resolve()
if not compiler_path.is_file():
raise GateFailure("INFRA_BLOCKED", "clang is unavailable")
compiler = SPEC["toolchain"]["compiler"]
compiler_version = run([str(compiler_path), "--version"]).stdout.decode(
"utf-8", errors="strict"
).splitlines()[0]
if (
str(compiler_path) != compiler["realpath"]
or sha256_path(compiler_path) != compiler["sha256"]
or compiler_version != compiler["version"]
):
raise GateFailure("INFRA_BLOCKED", "cross compiler identity changed")
compiler_targets = run([str(compiler_path), "--print-targets"]).stdout.decode(
"utf-8", errors="strict"
)
architectures = SPEC["architectures"]
if [item.get("id") for item in architectures] != ["arm64", "riscv64", "i386"]:
raise GateFailure("RUNNER_FAIL", "architecture audit set is not exact")
if sum(item.get("pointer_bits") == 32 for item in architectures) < 1:
raise GateFailure("RUNNER_FAIL", "architecture audit lacks a 32-bit target")
source_support = {}
for architecture in architectures:
arch_id = architecture["id"]
header = FREEBSD_SRC / "sys" / architecture["machine_header_dir"] / "include/param.h"
if not header.is_file():
raise GateFailure("INFRA_BLOCKED", f"FreeBSD source lacks {arch_id}")
if sha256_path(header) != architecture["param_h_sha256"]:
raise GateFailure("INFRA_BLOCKED", f"FreeBSD {arch_id} source identity changed")
target_pattern = rf"^\s*{re.escape(architecture['compiler_backend'])}\s+-"
if re.search(target_pattern, compiler_targets, re.MULTILINE) is None:
raise GateFailure("INFRA_BLOCKED", f"clang lacks {arch_id} backend")
source_support[arch_id] = {
"status": "PASS",
"freebsd_machine_headers": str(header),
"param_h_sha256": sha256_path(header),
"compiler_backend": architecture["compiler_backend"],
"target_triple": architecture["target_triple"],
"pointer_bits": architecture["pointer_bits"],
}
probe_source = SPEC["cross_build_contract"]["unaligned_endian_probe_source"].encode("ascii")
if sha256_bytes(probe_source) != SPEC["cross_build_contract"]["unaligned_endian_probe_sha256"]:
raise GateFailure("RUNNER_FAIL", "input-recorded unaligned/endian probe changed")
inventory = {
"schema": 1,
"host": {"system": platform.system(), "machine": platform.machine()},
"local_host_is_qualifying_native_freebsd": False,
"local_host_reason": "host is not FreeBSD and is not any candidate architecture",
"declared_native_environments": {
item["id"]: item["native_environment"] is not None for item in architectures
},
"emulator_tools": {
item["id"]: shutil.which(item["emulator_tool"]) for item in architectures
},
"emulator_binary_is_native_runtime_evidence": False,
"source_toolchain_support": source_support,
"protected_resources_addressed": False,
"inventory_rule": "only an explicit, validated same-architecture FreeBSD runner declaration can start cross work",
}
write_json(OUTPUT / "runtime-environment-inventory.json", inventory)
write_json(
OUTPUT / "freebsd-source-identity.json",
{
"path": str(FREEBSD_SRC),
"git_root": str(git_root),
"git_prefix": freebsd_prefix,
"git_tree_path": freebsd["git_tree_path"],
"head": freebsd_head,
"source_tree_oid": freebsd_source_tree,
"sys_tree_oid": freebsd_sys_tree,
"sha256": freebsd_hashes,
},
)
write_json(
OUTPUT / "toolchain-identity.json",
{
"compiler_realpath": str(compiler_path),
"compiler_sha256": sha256_path(compiler_path),
"compiler_version": compiler_version,
"print_targets_sha256": sha256_bytes(compiler_targets.encode("utf-8")),
},
)
results = []
go_architectures = []
for architecture in architectures:
declaration = architecture["native_environment"]
record: dict[str, Any] = {
"architecture": architecture["id"],
"machine_arch": architecture["machine_arch"],
"pointer_bits": architecture["pointer_bits"],
"source_toolchain": source_support[architecture["id"]],
}
if declaration is None:
record.update(
{
"native_environment": {
"status": "STOP",
"reason": "no declared same-architecture FreeBSD runtime environment",
},
"cross_build_and_probes": {
"status": "NOT_RUN",
"reason": "cross-only evidence cannot authorize allowlisting",
},
"native_runtime": {
"status": "NOT_RUN",
"reason": "same-architecture FreeBSD runtime is absent",
},
"decision": "STOP",
}
)
results.append(record)
continue
for key in (
"runner_path", "runner_sha256", "preflight_argv", "runtime_argv",
"preflight_deadline_seconds", "runtime_deadline_seconds",
):
if key not in declaration:
raise GateFailure("RUNNER_FAIL", f"incomplete native declaration: {key}")
cross = compile_architecture(
architecture, resolved, patch_bytes, compiler_path
)
native = run_native(
architecture,
declaration,
cross["modules"],
resolved,
patch_spec["sha256"],
)
native_pass = native["status"] == "PASS"
record.update(
{
"native_environment": {"status": "PASS", "declaration": declaration},
"cross_build_and_probes": cross,
"native_runtime": native,
"decision": "GO" if native_pass else "STOP",
}
)
if native_pass:
go_architectures.append(architecture["id"])
results.append(record)
overall_status = "GO" if go_architectures else "STOP"
result = {
"schema": 1,
"gate": "G07",
"candidate": "P15-027",
"batch": "B36",
"status": overall_status,
"reason": (
"at least one architecture completed its own cross and native requirements"
if go_architectures
else "no architecture has a declared same-architecture FreeBSD runtime"
),
"requested_base": REQUESTED_BASE,
"resolved_base": resolved,
"repo_source_tree_oid": source_tree,
"deadline_seconds": DEADLINE,
"expected_exit_code": 0 if go_architectures else 22,
"architectures": results,
"go_architectures": go_architectures,
"allowlist_authorization": go_architectures,
"false_go_guard": "each authorized architecture must independently have cross_build_and_probes=PASS and native_runtime=PASS",
"b36": "AUTHORIZED" if go_architectures else "STOP-NO-SOURCE",
"production_makefile_guard_preserved": True,
"production_source_changed": False,
"qemu": "NOT_RUN" if not go_architectures else "runner-defined",
"full_feature_suite": "NOT_RUN",
"smoke_suite": "NOT_RUN",
"protected_resources_addressed": False,
}
write_json(OUTPUT / "result.json", result)
print(json.dumps(result, ensure_ascii=True, sort_keys=True))
return 0 if go_architectures else 22
try:
raise SystemExit(main())
except GateFailure as error:
failure = {
"schema": 1,
"gate": "G07",
"candidate": "P15-027",
"status": error.status,
"reason": error.reason,
"requested_base": REQUESTED_BASE,
"deadline_seconds": DEADLINE,
"b36": "NOT_RUN",
"target_marker": "not_reached",
"production_source_changed": False,
"protected_resources_addressed": False,
}
write_json(OUTPUT / "result.json", failure)
print(json.dumps(failure, ensure_ascii=True, sort_keys=True))
raise SystemExit({"RUNNER_FAIL": 20, "INFRA_BLOCKED": 21}.get(error.status, 20))
PY
gate_rc=$?
set -e
cleanup_status=PASS
if ! rm -rf -- "$work"; then
cleanup_status=FAIL
gate_rc=20
fi
trap - EXIT HUP INT TERM
printf 'owned temporary path removed: %s\ncleanup=%s\n' \
"$work" "$cleanup_status" >"$output/cleanup.log"
python3 -B - "$output" "$gate_rc" "$cleanup_status" <<'PY'
from __future__ import annotations
import hashlib
import json
from pathlib import Path
import sys
output = Path(sys.argv[1])
exit_code = int(sys.argv[2])
cleanup = sys.argv[3]
if cleanup != "PASS":
status = "RUNNER_FAIL"
origin = "runner"
elif exit_code == 0:
status = "PASS"
origin = "gate"
elif exit_code == 22:
status = "STOP"
origin = "gate"
elif exit_code in (124, 137):
status = "INFRA_BLOCKED"
origin = "infrastructure"
else:
status = "RUNNER_FAIL"
origin = "runner"
(output / "attempt.json").write_text(
json.dumps(
{
"schema": 1,
"exit_code": exit_code,
"status": status,
"failure_origin": origin,
"cleanup": cleanup,
"target_marker": "reached" if status in {"PASS", "STOP"} else "not_reached",
},
ensure_ascii=True,
indent=2,
sort_keys=True,
) + "\n",
encoding="ascii",
)
lines = []
for path in sorted(output.iterdir(), key=lambda item: item.name):
if path.is_file() and path.name != "SHA256SUMS":
digest = hashlib.sha256(path.read_bytes()).hexdigest()
lines.append(f"{digest} {path.name}")
(output / "SHA256SUMS").write_text("\n".join(lines) + "\n", encoding="ascii")
PY
printf 'P15-027 gate exit=%s cleanup=%s output=%s\n' \
"$gate_rc" "$cleanup_status" "$output"
exit "$gate_rc"