#:property PublishAot=false using System.Diagnostics; using System.Buffers.Binary; using System.IO.Compression; using System.Runtime.InteropServices; using System.Security.Cryptography; using System.Text; using System.Text.Json; using System.Xml.Linq; // .NET 10 file-based CI diagnostic. See docs/macos-native-diagnostic.md. return await NativeDiagnostic.Execute(args); static class NativeDiagnostic { const string DockurCommit = "16a5b470cdd601bae8b05b02d748d7edfb36c12e"; const string Profile = "tcg-haswell-sonoma"; const string CpuModel = "Haswell-noTSX"; const int DiagnosticMinutes = 20; const string DiagnosticArguments = "-object iothread,id=io2 -no-reboot -no-shutdown -d int,cpu_reset,guest_errors,unimp"; const string CpuFlags = "Haswell-noTSX,l3-cache=on,+hypervisor,vendor=GenuineIntel,vmx=off,vmware-cpuid-freq=on,-pdpe1gb,-pcid,-invpcid,-tsc-deadline,-xsavec,-xsaves,+ssse3,+sse4.2,+popcnt,+avx,+avx2,+aes,+fma,+bmi1,+bmi2,+smep,+xsave,+xsaveopt,+xgetbv1,+movbe,+rdrand,enforce=on"; const string OpenCoreTemplateHash = "287328995d4198f1b05166f087d85bf7ef66bedafe150d17ad112ac8de60051d"; const string UdifChecksumBindingHash = "6109d04619e800c483fdac363d593cd1cd69f34131d2521417334e11d41c8bfa"; const string OwnerLabel = "org.meeting-assistant.native-diagnostic"; const long GuestDiskBytes = 64L * 1024 * 1024 * 1024; const long ContainerMemoryBytes = 6L * 1024 * 1024 * 1024; const int MaximumCapturedCharacters = 8 * 1024 * 1024; static readonly JsonSerializerOptions JsonOptions = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, WriteIndented = true }; const string OriginalBootstrap = "[ ! -e /tmp/m ]&&{ /sbin/mount_9p installstate >/dev/null 2>&1;exec /Volumes/installstate/launch.sh;};: >/tmp/m\n"; const string MountOnlyBootstrap = "[ ! -e /tmp/m ]&& /sbin/mount_9p installstate >/dev/null 2>&1; : >/tmp/m\n"; static readonly string OriginalDaemon = """ \tLabel \tcom.apple.recoveryosd \tOnDemand \t \tProcessType \tApp \tEnablePressuredExit \t \tProgramArguments \t \t\t/usr/libexec/recoveryosd \t """.Replace("\\t", "\t", StringComparison.Ordinal); static readonly string DiagnosticDaemon = (OriginalDaemon + "\n") .Replace("\n", "", StringComparison.Ordinal) .Replace("\t\t/usr/libexec/recoveryosd", "\t\t/bin/bash\n\t\t/Volumes/installstate/launch.sh", StringComparison.Ordinal); // Exact XML framing read from the Apple 13 comparison download, not an assertion // about the unretained bytes downloaded by run 4173. static readonly string OriginalDaemon13 = ReplaceOnce(OriginalDaemon + "\n", "App", "Interactive"); static readonly string DiagnosticDaemon13 = ReplaceOnce(DiagnosticDaemon, "App", "Interactive"); public static async Task Execute(string[] args) { if (args.Length == 0 || args.Contains("--help")) { Console.WriteLine("dotnet run --file tools/ci/MacOsNativeDiagnostic.cs -- --run|--cleanup|--validate [--output artifacts/native-macos] [--source existing-dockur-clone]"); return 0; } var output = Path.GetFullPath(Option(args, "--output") ?? "artifacts/native-macos"); if (args.Contains("--validate")) { ValidateContracts(); if (Option(args, "--source") is { } source) { await PrepareSource(Path.GetFullPath(source), output, "validation", false, CancellationToken.None); await ValidateResourceRetention(output); await ValidateRecoveryPatch(output); await ValidateTcgPreflight(output, CancellationToken.None); Save(Path.Combine(output, "validation.json"), new { success = true, profile = Profile, helperSha256 = Hash(File.ReadAllBytes(Path.Combine("tools", "ci", "MacOsNativeDiagnostic.cs"))), udifChecksumBindingSha256 = Hash(File.ReadAllBytes(Path.Combine("tools", "ci", "macos-native-udif-checksums.py"))), baselineReadinessNormalized = true, readinessDiagnosticBlocksExcluded = 7, productVersionParserBlockExcluded = true, productVersionSequenceRestored = true, productVersionMaximumBytes = 1024, nativeProductVersionCommandRemoved = true, diskReadinessAttemptLimit = 1, diskCommandLimitSeconds = 120, diskThreadObservationLimitSeconds = 60, stackSamplingUsed = false, resultNegativeCases = 6, containerNegativeCases = 11, recoveryPositiveCases = 4, recoveryNegativeCases = 12, independentFixtureCrc32Readback = true, resourceSnapshotRetention = true, cpuProfileSourceContractsVerified = true, preflightGateFixtureCases = 8, qemuRuntimePreflightExecuted = false, templateIsoDownloaded = false, sourceModified = false, dockerExecuted = false, guestExecuted = false, completedUtc = DateTimeOffset.UtcNow }); } Console.WriteLine("Source patch contracts and diagnostic result validation passed; no Docker or guest execution occurred."); return 0; } if (args.Contains("--cleanup")) return await Cleanup(output) ? 0 : 1; if (!args.Contains("--run")) throw new ArgumentException("Choose --run, --cleanup or --validate."); Directory.CreateDirectory(output); var statePath = Path.Combine(output, "owned-resources.json"); if (File.Exists(statePath)) throw new InvalidOperationException("Output already contains a run identity; choose a fresh directory or clean up its run first."); var token = Guid.NewGuid().ToString("N"); var work = Path.Combine(Environment.GetEnvironmentVariable("RUNNER_TEMP") ?? Path.GetTempPath(), "meeting-assistant-native-" + token); var state = new OwnedResources(token, "meeting-assistant-native-" + token, "meeting-assistant-native-diagnostic:" + token, work); Save(statePath, state); Directory.CreateDirectory(work); File.WriteAllText(Path.Combine(work, "run.owner"), token); using var deadline = new CancellationTokenSource(TimeSpan.FromMinutes(DiagnosticMinutes)); using var signal = OperatingSystem.IsLinux() ? PosixSignalRegistration.Create(PosixSignal.SIGTERM, context => { context.Cancel = true; deadline.Cancel(); }) : null; ConsoleCancelEventHandler cancelHandler = (_, context) => { context.Cancel = true; deadline.Cancel(); }; Console.CancelKeyPress += cancelHandler; var outcome = "failed"; string? error = null; try { if (!OperatingSystem.IsLinux() || RuntimeInformation.ProcessArchitecture != Architecture.X64) throw new InvalidOperationException("This diagnostic runs on the existing Linux/x64 runner only."); ValidateContracts(); var sourceCommit = (await Command("git", ["rev-parse", "HEAD"], output, "candidate-commit", deadline.Token)).Output.Trim(); Save(Path.Combine(output, "run-metadata.json"), new { token, startedUtc = DateTimeOffset.UtcNow, sourceCommit, dockurCommit = DockurCommit, profile = Profile, causalSingleVariableTest = false, kvm = false, cpuModel = CpuModel, recoveryMajor = 14, cpuFlags = CpuFlags, runId = Environment.GetEnvironmentVariable("GITHUB_RUN_ID"), server = Environment.GetEnvironmentVariable("GITHUB_SERVER_URL"), architecture = RuntimeInformation.ProcessArchitecture.ToString(), deadlineMinutes = DiagnosticMinutes }); var info = await Command("docker", ["info", "--format", "{{json .}}"], output, "docker-info", deadline.Token); using (var document = JsonDocument.Parse(info.Output)) { var data = document.RootElement; if (data.GetProperty("OSType").GetString() != "linux" || data.GetProperty("Architecture").GetString() is not ("x86_64" or "amd64")) throw new InvalidOperationException("The existing Docker daemon is not Linux/x64; this diagnostic does not reconfigure it."); if (data.GetProperty("NCPU").GetInt32() < 2 || data.GetProperty("MemTotal").GetInt64() < ContainerMemoryBytes) throw new InvalidOperationException("Existing Docker resources cannot fit this bounded 2-CPU/6-GiB diagnostic; no infrastructure change was requested."); } await Command("sh", ["-c", "cat /proc/meminfo; printf '\n[cgroup]\n'; cat /sys/fs/cgroup/memory.max /sys/fs/cgroup/cpu.max 2>/dev/null || true; printf '\n[workspace disk]\n'; df -Pk ."], output, "runner-resources", deadline.Token); var available = System.Text.RegularExpressions.Regex.Match(File.ReadAllText("/proc/meminfo"), @"(?m)^MemAvailable:\s+(\d+) kB$"); if (!available.Success || long.Parse(available.Groups[1].Value) < 5L * 1024 * 1024) throw new InvalidOperationException("Existing runner memory has less than the 5-GiB available diagnostic budget; no infrastructure change was requested."); var source = Path.Combine(work, "dockur"); await Command("git", ["clone", "--no-checkout", "https://github.com/dockur/macos.git", source], output, "dockur-clone", deadline.Token); await Command("git", ["-C", source, "checkout", "--detach", DockurCommit], output, "dockur-checkout", deadline.Token); var actualCommit = (await Command("git", ["-C", source, "rev-parse", "HEAD"], output, "dockur-commit", deadline.Token)).Output.Trim(); if (actualCommit != DockurCommit) throw new InvalidOperationException("Dockur source pin mismatch."); await PrepareSource(source, output, token, true, deadline.Token); await Command("docker", ["build", "--platform", "linux/amd64", "--label", OwnerLabel + "=" + token, "--tag", state.ImageTag, source], output, "docker-build", deadline.Token, echo: true); var imageInspect = await Command("docker", ["image", "inspect", state.ImageTag], output, "image-inspect", deadline.Token); using (var image = JsonDocument.Parse(imageInspect.Output)) state = state with { ImageId = image.RootElement[0].GetProperty("Id").GetString() }; Save(statePath, state); var create = await Command("docker", ["create", "--name", state.ContainerName, "--label", OwnerLabel + "=" + token, "--memory", "6g", "--memory-swap", "6g", "--cpus", "2", "--shm-size", "512m", "--log-opt", "max-size=8m", "--log-opt", "max-file=1", "--env", "KVM=N", "--env", "CPU_MODEL=" + CpuModel, "--env", "NETWORK=slirp", "--env", "DISPLAY=web", "--env", "MANUAL=N", "--env", "VERSION=14", "--env", "RAM_SIZE=4G", "--env", "CPU_CORES=2", "--env", "DISK_SIZE=64G", "--env", "DISK_TYPE=sata", "--env", "ARGUMENTS=" + DiagnosticArguments, state.ImageTag], output, "docker-create", deadline.Token); var id = create.Output.Trim(); if (!System.Text.RegularExpressions.Regex.IsMatch(id, "^[0-9a-f]{64}$")) throw new InvalidOperationException("Docker did not return a container identity."); state = state with { ContainerId = id }; Save(statePath, state); await Command("docker", ["inspect", id], output, "container-created", deadline.Token); AssertContainer(File.ReadAllText(Path.Combine(output, "container-created.stdout.log")), token); await Command("docker", ["start", id], output, "docker-start", deadline.Token); await CapturePressure(id, output, "before", deadline.Token); Console.WriteLine("The owned unprivileged TCG/Haswell macOS 14 guest is starting. Success requires native macOS 14+/x86_64 and a writable 64-GiB disk; no installer will run. This is not a single-variable causal test."); var recoveryStarted = Stopwatch.StartNew(); var heartbeat = Stopwatch.StartNew(); var diskPressureCaptured = false; while (true) { deadline.Token.ThrowIfCancellationRequested(); await CaptureGuest(id, output, deadline.Token); await CheckRecoveryBootProgress(id, output, deadline.Token); var proofPath = Path.Combine(output, "guest-proof.log"); if (!diskPressureCaptured && File.Exists(proofPath) && File.ReadAllText(proofPath).Contains("[proof-start] disks", StringComparison.Ordinal)) { diskPressureCaptured = true; await CapturePressure(id, output, "during", deadline.Token); } var resultPath = Path.Combine(output, "guest-result.json"); if (File.Exists(resultPath)) { var result = File.ReadAllText(resultPath); ValidateResult(result, token); Console.WriteLine("Native Recovery readiness passed. This run has not installed macOS, .NET, CLT, or run Meeting Assistant tests."); outcome = "readiness-passed"; break; } var running = await Command("docker", ["inspect", "--format", "{{.State.Running}}", id], output, "container-running", deadline.Token); if (running.Output.Trim() != "true") throw new InvalidOperationException("Guest container exited before a native readiness result."); if (heartbeat.Elapsed >= TimeSpan.FromSeconds(60)) { Console.WriteLine($"[native-diagnostic] phase=recovery; elapsed={recoveryStarted.Elapsed.TotalMinutes:F1} minutes; container=running; readiness=pending"); heartbeat.Restart(); } await Task.Delay(TimeSpan.FromSeconds(20), deadline.Token); } } catch (Exception exception) { error = exception is OperationCanceledException ? $"The explicit {DiagnosticMinutes}-minute diagnostic deadline or cancellation was reached." : exception.Message; Console.Error.WriteLine(error); } finally { Console.CancelKeyPress -= cancelHandler; using var captureDeadline = new CancellationTokenSource(TimeSpan.FromSeconds(45)); try { await CaptureGuest(state.ContainerId ?? state.ContainerName, output, captureDeadline.Token, true, state.Token); } catch (Exception exception) { Console.Error.WriteLine("Final evidence capture: " + exception.Message); } await CapturePressure(state.ContainerId ?? state.ContainerName, output, "after", captureDeadline.Token); try { PrintGuestProof(output, state.Token); } catch (Exception exception) { Console.Error.WriteLine("Native proof output: " + exception.Message); } var clean = await Cleanup(output); if (!clean) { outcome = "failed"; error = (error ?? "") + " Owned-resource cleanup failed; inspect cleanup evidence."; } Save(Path.Combine(output, "outcome.json"), new { token, outcome, error, completedUtc = DateTimeOffset.UtcNow }); } return outcome == "readiness-passed" ? 0 : 1; } static string? Option(string[] args, string name) { var index = Array.IndexOf(args, name); return index < 0 ? null : index + 1 < args.Length ? args[index + 1] : throw new ArgumentException("Missing value for " + name); } static void ValidateContracts() { var readiness = File.ReadAllText(Path.Combine("tools", "ci", "macos-native-readiness.sh")); var baseline = NormalizeReadinessDiagnostics(readiness); baseline = ReplaceOnce(baseline, "while (( attempt < 1 && SECONDS - readiness_start < 600 )); do", "while (( SECONDS - readiness_start < 600 )); do"); if (Hash(Encoding.UTF8.GetBytes(baseline)) != "4d428f594dac14eff64ed87b172c81ecf85ac91da8c5460cd6ec4b1d310800c3") throw new InvalidOperationException("Outside seven explicit diagnostic blocks, the successful sw_vers version parser/sequence and one-attempt limit, baseline identity/service/disk gates and watchdogs must remain identical."); if (Hash(File.ReadAllBytes(Path.Combine("tools", "ci", "macos-native-bootstrap.sh"))) != "94f069e116fdc7685a4d233cab6fa50df9f39274386bb82157674061e74fadb5") throw new InvalidOperationException("Compatibility profile must preserve the baseline Apple recoveryosd wrapper."); if (Hash(Encoding.UTF8.GetBytes(OriginalDaemon13)) != "af9d7f6c1948079bd4384d27b6882678d6fb4e338fcf6a8be8f84fceef174ad6") throw new InvalidOperationException("macOS 13 allowlist bytes differ from the independently read comparison plist."); foreach (var variant in new[] { (OriginalDaemon + "\n", DiagnosticDaemon, "App"), (OriginalDaemon13, DiagnosticDaemon13, "Interactive") }) { ValidateDaemon(variant.Item1, variant.Item3, false); ValidateDaemon(variant.Item2, variant.Item3, true); if (Encoding.UTF8.GetByteCount(variant.Item2) > Encoding.UTF8.GetByteCount(variant.Item1)) throw new InvalidOperationException("Daemon replacement exceeds original file."); } var good = JsonSerializer.Serialize(new { token = "validation", success = true, osVersion = "14.6.1", architecture = "x86_64", uid = 0, disk = "/dev/disk1", diskBytes = GuestDiskBytes, readOnly = false, systemExit = 0, diskArbitrationExit = 0, recoveryExit = 0, diskListExit = 0 }); ValidateResult(good, "validation"); ValidateBootProgress(); foreach (var invalid in new[] { good.Replace("14.6.1", "13.6.1"), good.Replace("x86_64", "arm64"), good.Replace("\"readOnly\":false", "\"readOnly\":true"), good.Replace("\"success\":true", "\"success\":false"), good.Replace("68719476736", "17179869184"), good.Replace("validation", "stale") }) { try { ValidateResult(invalid, "validation"); } catch (InvalidOperationException) { continue; } throw new InvalidOperationException("Diagnostic validator accepted an invalid/stale result."); } var boundary = """ [{"Config":{"Labels":{"org.meeting-assistant.native-diagnostic":"validation"},"Env":["KVM=N","CPU_MODEL=Haswell-noTSX","VERSION=14"]},"HostConfig":{"Privileged":false,"NetworkMode":"default","Memory":6442450944,"MemorySwap":6442450944,"NanoCpus":2000000000,"ShmSize":536870912,"CapAdd":null,"DeviceRequests":null,"Binds":null,"PortBindings":{},"DeviceCgroupRules":null,"Tmpfs":null,"Devices":[]},"Mounts":[{"Type":"volume","Destination":"/storage","RW":true}]}] """; AssertContainer(boundary, "validation"); foreach (var invalid in new[] { boundary.Replace("\"Privileged\":false", "\"Privileged\":true"), boundary.Replace("\"Devices\":[]", "\"Devices\":[{\"PathOnHost\":\"/dev/kvm\",\"PathInContainer\":\"/dev/kvm\",\"CgroupPermissions\":\"rw\"}]"), boundary.Replace("KVM=N", "KVM=Y"), boundary.Replace("CPU_MODEL=Haswell-noTSX", "CPU_MODEL=host"), boundary.Replace("VERSION=14", "VERSION=13"), boundary.Replace("6442450944", "8589934592"), boundary.Replace("\"NetworkMode\":\"default\"", "\"NetworkMode\":\"host\""), boundary.Replace("\"CapAdd\":null", "\"CapAdd\":[\"NET_ADMIN\"]"), boundary.Replace("\"Type\":\"volume\"", "\"Type\":\"bind\""), boundary.Replace("/storage", "/host"), boundary.Replace("\"NanoCpus\":2000000000", "\"NanoCpus\":4000000000") }) { try { AssertContainer(invalid, "validation"); } catch (InvalidOperationException) { continue; } throw new InvalidOperationException("Diagnostic validator accepted an excessive/wrong-profile container boundary."); } } static string NormalizeReadinessDiagnostics(string source) { const string start = "# BEGIN disk IPC diagnostic\n"; const string end = "# END disk IPC diagnostic\n"; var blocks = 0; while (source.IndexOf(start, StringComparison.Ordinal) is var from && from >= 0) { var to = source.IndexOf(end, from + start.Length, StringComparison.Ordinal); if (to < 0 || source.IndexOf(start, from + start.Length, to - from - start.Length, StringComparison.Ordinal) >= 0) throw new InvalidOperationException("Readiness diagnostic blocks are unbalanced or nested."); source = source.Remove(from, to + end.Length - from); blocks++; } if (blocks != 7 || source.Contains(end, StringComparison.Ordinal)) throw new InvalidOperationException("Readiness must contain exactly seven explicit disk IPC diagnostic blocks."); source = RestoreVersionBlock(source, "successful sw_vers version parser", ""); source = RestoreVersionBlock(source, "successful sw_vers version extraction", "run_command version /usr/bin/sw_vers -productVersion\n(( LAST_EXIT == 0 )) || fail_probe product_version_failed\nread_scalar || fail_probe product_version_invalid\n"); return source; } static string RestoreVersionBlock(string source, string name, string originalSequence) { var start = "# BEGIN " + name + "\n"; var end = "# END " + name + "\n"; if (source.Split(start, StringSplitOptions.None).Length != 2 || source.Split(end, StringSplitOptions.None).Length != 2) throw new InvalidOperationException("Readiness requires exactly one named version marker pair: " + name); var from = source.IndexOf(start, StringComparison.Ordinal); var to = source.IndexOf(end, StringComparison.Ordinal); if (to < from + start.Length) throw new InvalidOperationException("Readiness version markers are reversed: " + name); return source.Remove(from, to + end.Length - from).Insert(from, originalSequence); } static async Task PrepareSource(string source, string output, string token, bool writeSource, CancellationToken cancellation) { Directory.CreateDirectory(output); var patchPath = Path.Combine(source, "src/install/recovery/patch.py"); var originalPatch = File.ReadAllText(patchPath); if (Hash(Encoding.UTF8.GetBytes(originalPatch)) != "84f13db88c02edbf5ce21a39571fe58f12bebf5b0886c2d012f16ddbaed45323") throw new InvalidOperationException("Pinned Recovery patcher hash mismatch."); var daemon = OriginalDaemon + "\n"; var patch = PrepareRecoveryPatch(originalPatch); var checksumBinding = File.ReadAllText(Path.Combine("tools", "ci", "macos-native-udif-checksums.py")); if (Hash(Encoding.UTF8.GetBytes(checksumBinding)) != UdifChecksumBindingHash) throw new InvalidOperationException("Recovery UDIF checksum binding hash mismatch."); File.WriteAllText(Path.Combine(output, "udif_checksums.py"), checksumBinding, new UTF8Encoding(false)); var dockerPath = Path.Combine(source, "Dockerfile"); if (Hash(File.ReadAllBytes(dockerPath)) != "a0e804235967400eb70e755d63eff8a33a7761922ddd6e9723faa8e828fd8aa3") throw new InvalidOperationException("Pinned Dockerfile hash mismatch."); // The existing runner's BuildKit cannot checksum dangling manpage links during COPY /. // This pinned filesystem image has an empty Config; FROM preserves the same runtime defaults. var dockerfile = ReplaceOnce(File.ReadAllText(dockerPath), "FROM scratch AS base\nCOPY --from=qemux/qemu:7.50 --exclude=usr/bin/qemu-system-x86_64 / /\n", "FROM qemux/qemu:7.50@sha256:e7f6fda52503a546fd649670ba46e4bc23dc6dcef275bc3fac48877fbbc430df AS base\n"); dockerfile = ReplaceAllExact(dockerfile, "--from=qemux/qemu-macos:latest ", "--from=qemux/qemu-macos:latest@sha256:af64297171228f27d5f616249e18f6ad5e2fbc79c1cc517252521e8bcd8eadaa ", 2); dockerfile = ReplaceOnce(dockerfile, "ADD $REPO_KVM_OPENCORE/releases/download/v$VERSION_KVM_OPENCORE/LongQT-OpenCore-v$VERSION_KVM_OPENCORE.iso /opencore.iso", "ADD --checksum=sha256:" + OpenCoreTemplateHash + " $REPO_KVM_OPENCORE/releases/download/v$VERSION_KVM_OPENCORE/LongQT-OpenCore-v$VERSION_KVM_OPENCORE.iso /opencore.iso"); dockerfile = ReplaceOnce(dockerfile, " gzip \\\n", " gzip \\\n nasm \\\n"); dockerfile = ReplaceOnce(dockerfile, "COPY --chmod=755 ./assets /assets/\n", "COPY --chmod=755 ./assets /assets/\nRUN nasm -f bin /assets/ci-cpu-preflight.asm -o /assets/ci-cpu-preflight.bin && test \"$(stat -c%s /assets/ci-cpu-preflight.bin)\" = 65536\n"); var boot = PrepareTcgBoot(source); var cpuPath = Path.Combine(source, "src/cpu.sh"); var cpu = File.ReadAllText(cpuPath); if (Hash(Encoding.UTF8.GetBytes(cpu)) != "0f3e4b4e1c3e17743d3a8d27b77a76424ceebb576b269283d612c489bc70993e") throw new InvalidOperationException("Pinned CPU composition script hash mismatch."); cpu = ReplaceOnce(cpu, ",+movbe,+rdrand,check\"", ",+movbe,+rdrand,enforce=on\""); var preflight = File.ReadAllText(Path.Combine("tools", "ci", "macos-tcg-cpu-preflight.asm")); var entryPath = Path.Combine(source, "src/entry.sh"); var entry = ReplaceOnce(File.ReadAllText(entryPath), "set -Eeuo pipefail\n", "set -Eeuo pipefail\n\n# Diagnostic budget: inspect existing Docker storage before Recovery download/boot.\ndf -Pk /storage\nfree_kib=$(df -Pk /storage | awk 'NR==2 {print $4}')\n[[ \"$free_kib\" =~ ^[0-9]+$ ]] && (( free_kib >= 8 * 1024 * 1024 )) || { echo 'Existing Docker storage has less than the 8-GiB diagnostic budget.' >&2; exit 1; }\n"); entry = ReplaceOnce(entry, ". cpu.sh # Configure CPU model\n", ""); entry = ReplaceOnce(entry, ". proc.sh # Initialize processor\n", ""); entry = ReplaceOnce(entry, ". init.sh # Initialize system\n", ". init.sh # Initialize system\n. cpu.sh # Compose the exact guest CPU before any Apple download\n. proc.sh # Compose the actual accelerator/CPU_FLAGS once\n" + TcgPreflight + "\n"); entry = ReplaceOnce(entry, "trap - ERR\n", "[[ \"$KVM_OPTS\" == ' -accel tcg,thread=multi' && \"$CPU_FLAGS\" == '" + CpuFlags + "' && \"$CPU_OPTS\" == \"-cpu $CPU_FLAGS -smp $SMP\" ]] || { error 'Supported profile refuses a CPU/accelerator fallback.'; exit 1; }\ninfo '[supported-profile] accelerator=tcg cpu=Haswell-noTSX recovery=14; AVX/AVX2 preflight passed; native guest gates still pending'\n\ntrap - ERR\n"); entry = ReplaceOnce(entry, "\ntrap - ERR\n", "\nprintf '%s\\n' '[supported-profile] accelerator=tcg cpu=Haswell-noTSX recovery=14; AVX/AVX2 preflight passed; native guest gates still pending' >> \"$QEMU_DIR/native-stage.log\"\ntrap - ERR\n"); // Preserve sparse boot markers independently of the bounded, verbose Docker trace. entry = ReplaceOnce(entry, " -e 's/failed to load Boot/skipped Boot/g' \\\n", " -e 's/failed to load Boot/skipped Boot/g' \\\n -e '/^#\\[EB|LOG:HANDOFF TO XNU\\] /w /run/shm/kernel-handoffs.log' \\\n"); var hookPath = Path.Combine("tools", "ci", "macos-native-readiness.sh"); var hook = ReplaceOnce(File.ReadAllText(hookPath), "@@PROOF_TOKEN@@", token); var wrapper = File.ReadAllText(Path.Combine("tools", "ci", "macos-native-bootstrap.sh")); var imagePath = Path.Combine(source, "src", "image.sh"); var originalImage = File.ReadAllText(imagePath); if (Hash(Encoding.UTF8.GetBytes(originalImage)) != "c08bf9436fb8b72ea82fdf0e677641ab2fc42a0a59e2cf0309c00df519884c5c") throw new InvalidOperationException("Pinned Recovery staging script hash mismatch."); var image = ReplaceOnce(originalImage, " if ! cp -f \"$IMAGE_TOOLS/recovery/launch.sh\" \"$script\"; then\n", " if ! cp -f \"$IMAGE_TOOLS/recovery/launch.sh\" \"$script\" ||\n ! cp -f \"$IMAGE_TOOLS/recovery/readiness.sh\" \"${script%/*}/readiness.sh\"; then\n"); image = ReplaceOnce(image, " if ! cmp -s \"$IMAGE_TOOLS/recovery/launch.sh\" \"$script\" ||\n", " if ! cmp -s \"$IMAGE_TOOLS/recovery/launch.sh\" \"$script\" ||\n ! cmp -s \"$IMAGE_TOOLS/recovery/readiness.sh\" \"$state/readiness.sh\" ||\n"); image = ReplaceOnce(image, " if ! result=$(python3 \"$IMAGE_TOOLS/recovery/patch.py\" \"$image\"); then\n", " info \"[recovery-original] bytes=$(stat -c%s -- \"$image\") sha256=$(sha256sum \"$image\" | awk '{print $1}')\"\n if ! result=$(python3 \"$IMAGE_TOOLS/recovery/patch.py\" \"$image\"); then\n"); foreach (var pair in new[] { ("recovery-patch.py", patch), ("Dockerfile.patched", dockerfile), ("container-entry.sh", entry), ("guest-launch.sh", wrapper), ("guest-readiness.sh", hook), ("image.sh.patched", image), ("recoveryosd-original.plist", daemon), ("recoveryosd-diagnostic.plist", DiagnosticDaemon), ("recoveryosd-13-original.plist", OriginalDaemon13), ("recoveryosd-13-diagnostic.plist", DiagnosticDaemon13), ("early-bootstrap.sh", MountOnlyBootstrap), ("boot.sh.patched", boot), ("opencore-config.plist", File.ReadAllText(Path.Combine(source, "assets/config.plist"))), ("cpu.sh.patched", cpu), ("ci-cpu-preflight.asm", preflight) }) File.WriteAllText(Path.Combine(output, pair.Item1), pair.Item2, new UTF8Encoding(false)); Save(Path.Combine(output, "source-hashes.json"), Directory.GetFiles(output).Where(path => Path.GetFileName(path) is "recovery-patch.py" or "udif_checksums.py" or "Dockerfile.patched" or "container-entry.sh" or "guest-launch.sh" or "guest-readiness.sh" or "image.sh.patched" or "recoveryosd-original.plist" or "recoveryosd-diagnostic.plist" or "recoveryosd-13-original.plist" or "recoveryosd-13-diagnostic.plist" or "early-bootstrap.sh" or "boot.sh.patched" or "opencore-config.plist" or "cpu.sh.patched" or "ci-cpu-preflight.asm").ToDictionary(path => Path.GetFileName(path)!, path => Hash(File.ReadAllBytes(path)))); Save(Path.Combine(output, "cpu-preflight-source.json"), new { profile = Profile, cpuModel = CpuModel, cpuFlags = CpuFlags, expectedExitCode = 33, instructionProbeExecuted = false, qemuBinaryExecuted = false, sourceSha256 = Hash(Encoding.UTF8.GetBytes(preflight)) }); await Command("bash", ["-n", Path.Combine(output, "guest-launch.sh")], output, "guest-hook-syntax", cancellation); await Command("bash", ["-n", Path.Combine(output, "guest-readiness.sh")], output, "guest-readiness-syntax", cancellation); await Command("bash", ["-n", Path.Combine(output, "image.sh.patched")], output, "guest-staging-syntax", cancellation); await Command("bash", ["-n", Path.Combine(output, "container-entry.sh")], output, "entry-syntax", cancellation); await Command("bash", ["-n", Path.Combine(output, "boot.sh.patched")], output, "boot-staging-syntax", cancellation); await Command("bash", ["-n", Path.Combine(output, "cpu.sh.patched")], output, "cpu-composition-syntax", cancellation); if (!writeSource) return; File.WriteAllText(patchPath, patch, new UTF8Encoding(false)); File.WriteAllText(Path.Combine(source, "src/install/recovery/udif_checksums.py"), checksumBinding, new UTF8Encoding(false)); File.WriteAllText(dockerPath, dockerfile, new UTF8Encoding(false)); File.WriteAllText(entryPath, entry, new UTF8Encoding(false)); File.WriteAllText(imagePath, image, new UTF8Encoding(false)); File.WriteAllText(Path.Combine(source, "src/install/recovery/launch.sh"), wrapper, new UTF8Encoding(false)); File.WriteAllText(Path.Combine(source, "src/install/recovery/readiness.sh"), hook, new UTF8Encoding(false)); File.WriteAllText(Path.Combine(source, "src/boot.sh"), boot, new UTF8Encoding(false)); File.WriteAllText(cpuPath, cpu, new UTF8Encoding(false)); File.WriteAllText(Path.Combine(source, "assets/ci-cpu-preflight.asm"), preflight, new UTF8Encoding(false)); } static void ValidateDaemon(string xml, string processType, bool patched) { var pairs = XDocument.Parse(xml).Root!.Element("dict")!.Elements().ToArray(); if (pairs.Length != 10 || !pairs.Where((_, index) => index % 2 == 0).Select(element => element.Value).SequenceEqual(new[] { "Label", "OnDemand", "ProcessType", "EnablePressuredExit", "ProgramArguments" })) throw new InvalidOperationException("Recovery daemon fields changed."); if (pairs[1].Value != "com.apple.recoveryosd" || pairs[3].Name != "false" || pairs[5].Value != processType || pairs[7].Name != "false" || pairs[9].Name != "array" || !pairs[9].Elements().Select(element => element.Value).SequenceEqual(patched ? new[] { "/bin/bash", "/Volumes/installstate/launch.sh" } : new[] { "/usr/libexec/recoveryosd" })) throw new InvalidOperationException("Recovery daemon identity/arguments changed."); } static string PrepareRecoveryPatch(string original) { var patch = ReplaceOnce(original, OriginalBootstrap, MountOnlyBootstrap); patch = ReplaceOnce(patch, "import zlib\n", "import zlib\nfrom udif_checksums import ChecksumPlan\n"); var constants = "RECOVERY_13_ORIGINAL = b'''" + OriginalDaemon13 + "'''\nRECOVERY_13_REPLACEMENT = b'''" + DiagnosticDaemon13 + "'''.ljust(len(RECOVERY_13_ORIGINAL), b\" \")\nRECOVERY_14_ORIGINAL = b'''" + OriginalDaemon + "\n'''\nRECOVERY_14_REPLACEMENT = b'''" + DiagnosticDaemon + "'''.ljust(len(RECOVERY_14_ORIGINAL), b\" \")\nRECOVERY_LABEL = b'com.apple.recoveryosd'"; patch = ReplaceOnce(patch, "RECOVERY_ORIGINAL = b\"/usr/libexec/recoveryosd\"\nRECOVERY_REPLACEMENT = b\"/private/etc/rc.cdrom.sh\"", constants); patch = ReplaceOnce(patch, " if len(RECOVERY_REPLACEMENT) != len(RECOVERY_ORIGINAL):\n raise RuntimeError(\"recoveryosd launch-path replacement length mismatch\")", " if len(RECOVERY_13_REPLACEMENT) != len(RECOVERY_13_ORIGINAL) or len(RECOVERY_14_REPLACEMENT) != len(RECOVERY_14_ORIGINAL):\n raise RuntimeError(\"recoveryosd launch-path replacement length mismatch\")"); patch = ReplaceOnce(patch, " (\"recoveryosd launch path\", RECOVERY_ORIGINAL, RECOVERY_REPLACEMENT),", " (\"recoveryosd macOS 13 launch path\", RECOVERY_13_ORIGINAL, RECOVERY_13_REPLACEMENT),\n (\"recoveryosd macOS 14 launch path\", RECOVERY_14_ORIGINAL, RECOVERY_14_REPLACEMENT),"); patch = ReplaceOnce(patch, " chunks = {}\n", " chunks = {}\n recovery_label_count = 0\n"); patch = ReplaceOnce(patch, " plist = plistlib.loads(image.read(xml_length))\n", " plist = plistlib.loads(image.read(xml_length))\n checksums = ChecksumPlan(image, koly, plist, xml_offset, xml_length, size)\n"); patch = ReplaceOnce(patch, " key = (blkx_index, run_index)\n", " recovery_label_count += decoded.count(RECOVERY_LABEL)\n key = (blkx_index, run_index)\n"); var variantValidation = """ if len(matches[patches[0][0]]) != 1: raise RuntimeError("Expected exactly one rc.cdrom.sh bootstrap") variants = [item for item in patches[1:] if matches[item[0]]] if recovery_label_count != 1 or len(variants) != 1 or len(matches[variants[0][0]]) != 1: raise RuntimeError("Expected exactly one known recoveryosd plist and launch path") patches = (patches[0], variants[0]) print("[recovery-daemon] " + variants[0][0]) """; patch = ReplaceOnce(patch, " for name, _, _ in patches:\n count = len(matches[name])\n if count != 1:\n raise RuntimeError(f\"Expected exactly one {name}, found {count}\")", IndentPython(variantValidation, 8)); // Plan all recompressed chunks before the first image write. A later // compression failure must not leave an earlier chunk patched. patch = ReplaceOnce(patch, " for key, chunk in chunks.items():\n patched = bytearray", " planned = []\n for key, chunk in chunks.items():\n patched = bytearray"); patch = ReplaceOnce(patch, " image.seek(chunk[\"physical_offset\"])\n image.write(stored)", " planned.append((chunk[\"physical_offset\"], stored))\n\n checksum_xml, checksum_koly = checksums.prepare(planned)\n for physical_offset, stored in planned:\n image.seek(physical_offset)\n image.write(stored)\n image.seek(xml_offset)\n image.write(checksum_xml)\n image.seek(size - 512)\n image.write(checksum_koly)"); patch = ReplaceOnce(patch, " image.flush()\n", " image.flush()\n checksums.verify()\n"); return patch; } static string IndentPython(string text, int spaces) { var lines = text.Split('\n'); var common = lines.Where(line => line.Length > 0).Min(line => line.TakeWhile(character => character == ' ').Count()); return string.Join("\n", lines.Select(line => new string(' ', spaces) + (line.Length > 0 ? line[common..] : ""))); } static string PrepareTcgBoot(string source) { var boot = File.ReadAllText(Path.Combine(source, "src", "boot.sh")); var config = File.ReadAllText(Path.Combine(source, "assets", "config.plist")); if (Hash(Encoding.UTF8.GetBytes(boot)) != "82b56525707a8f586e040f56108b5034c02e7fecfea071f1857e596cba10cbed" || Hash(Encoding.UTF8.GetBytes(config)) != "3b0ec58b693cfa0fadf3e3f952486e87af8c27d504f9545d1e90ae2dc3777096") throw new InvalidOperationException("Pinned OpenCore staging/config hashes mismatch."); var document = XDocument.Parse(config, LoadOptions.PreserveWhitespace); var add = PlistValue(PlistValue(document.Root!.Element("dict")!, "Kernel"), "Add"); var expected = new[] { "Lilu.kext", "VMHide.kext", "VirtualSMC.kext", "WhateverGreen.kext", "VoodooPS2Controller.kext", "VoodooPS2Controller.kext/Contents/PlugIns/VoodooPS2Keyboard.kext", "AppleMCEReporterDisabler.kext" }; if (!add.Elements("dict").Select(dict => PlistValue(dict, "BundlePath").Value).SequenceEqual(expected) || add.Elements("dict").Any(dict => PlistValue(dict, "Enabled").Name != "true")) throw new InvalidOperationException("Pinned Kernel.Add order/enabled contract mismatch."); var nvram = PlistValue(PlistValue(PlistValue(document.Root!.Element("dict")!, "NVRAM"), "Add"), "7C436110-AB2A-4BBB-A880-FE41995C9F82"); if (PlistValue(nvram, "boot-args").Value != "keepsyms=1 debug=0x100 -lilubeta -wegbeta vmhState=enabled") throw new InvalidOperationException("Pinned kernel diagnostic arguments differ."); const string diagnosticBoot = """ local diagnostic_boot='-v keepsyms=1 debug=0x108 serial=5 msgbuf=1048576 -lilubeta -wegbeta vmhState=enabled' local boot_args="/plist/dict/key[.='NVRAM']/following-sibling::dict[1]/key[.='Add']/following-sibling::dict[1]/key[.='7C436110-AB2A-4BBB-A880-FE41995C9F82']/following-sibling::dict[1]/key[.='boot-args']/following-sibling::string[1]" xmlstarlet ed -P -L -u "$boot_args" -v "$diagnostic_boot" "$CFG" || exit 12 [ "$(xmlstarlet sel -t -v "$boot_args" "$CFG")" = "$diagnostic_boot" ] || { error 'Kernel diagnostic arguments were not installed.'; exit 12; } """; boot = ReplaceOnce(boot, " # DEBUG logging goes only to the OpenCore log file on the EFI partition.\n", diagnosticBoot + " # DEBUG logging goes only to the OpenCore log file on the EFI partition.\n"); boot = ReplaceOnce(boot, " PLIST=\"/assets/config.plist\"\n", " [ ! -e /custom.plist ] || { error 'Supported profile refuses an unverified custom OpenCore config!'; exit 12; }\n PLIST=\"/assets/config.plist\"\n"); boot = ReplaceOnce(boot, " if [ -s \"$target\" ] && [ \"$previous\" = \"$current\" ]; then\n IMG=\"$target\"\n return 0\n fi\n", " # This owned compatibility probe always rebuilds; never trust a cached boot.img.\n"); boot = ReplaceOnce(boot, " echo \"VMHIDE=$vmhide\"\n", " echo \"VMHIDE=$vmhide\"\n echo \"PROFILE=tcg-haswell-sonoma\"\n"); return boot; } static XElement PlistValue(XElement dictionary, string key) { var keys = dictionary.Elements("key").Where(element => element.Value == key).ToArray(); if (keys.Length != 1 || keys[0].ElementsAfterSelf().FirstOrDefault() is not { } value) throw new InvalidOperationException("Missing/duplicate plist key: " + key); return value; } static readonly string TcgPreflight = """ # Realize this exact TCG model and execute AVX/AVX2 before Apple downloads. disabled "$KVM" && [[ "$ARCH" == amd64 && "$CPU_MODEL" == Haswell-noTSX && "$VERSION" == 14 && "$CPU_FLAGS" == '@@CPU_FLAGS@@' ]] || { error 'Supported probe requires the exact TCG/Haswell/macOS 14 profile.'; exit 1; } [[ "$(qemu-system-x86_64 --version | head -n 1)" == 'QEMU emulator version 11.1.1 (Reims 11.1.3)' ]] || { error 'Pinned QEMU runtime version mismatch.'; exit 1; } printf '%s %s\n' c32746122cc68f3ed642aa46c21b677f803c58f0d4ff665841723fcc5625f549 /assets/ci-cpu-preflight.bin | sha256sum -c - || { error 'Compiled AVX/AVX2 preflight ROM hash mismatch.'; exit 1; } probeTcgInstructions() { /usr/bin/timeout --signal=TERM --kill-after=2 10 qemu-system-x86_64 \ -machine q35 -accel tcg,thread=multi -cpu "$1" -smp 2 -m 64 -bios /assets/ci-cpu-preflight.bin \ -nodefaults -display none -serial none -monitor none -nographic -no-reboot \ -device isa-debug-exit,iobase=0xf4,iosize=0x04 } if probeTcgInstructions "$CPU_FLAGS" > "$QEMU_DIR/cpu-preflight-positive.log" 2>&1; then positive=0; else positive=$?; fi cat "$QEMU_DIR/cpu-preflight-positive.log" (( positive == 33 )) || { error "Actual TCG AVX/AVX2 instruction preflight failed: exit=$positive"; exit 1; } if probeTcgInstructions "$CPU_FLAGS,-avx2" > "$QEMU_DIR/cpu-preflight-negative.log" 2>&1; then negative=0; else negative=$?; fi cat "$QEMU_DIR/cpu-preflight-negative.log" (( negative != 33 )) || { error 'AVX2-disabled negative control unexpectedly passed.'; exit 1; } info "[cpu-preflight] positive=$positive negative=$negative cpu=$CPU_FLAGS; actual AVX/AVX2 executed before Apple download" printf '[cpu-preflight] positive=%s negative=%s cpu=%s; actual AVX/AVX2 executed before Apple download\n' "$positive" "$negative" "$CPU_FLAGS" > "$QEMU_DIR/native-stage.log" """.Replace("@@CPU_FLAGS@@", CpuFlags, StringComparison.Ordinal); static async Task ValidateTcgPreflight(string output, CancellationToken cancellation) { var fixture = Path.Combine(output, "validation-cpu-preflight-gate"); Directory.CreateDirectory(fixture); var entry = File.ReadAllText(Path.Combine(output, "container-entry.sh")); if (entry.IndexOf(TcgPreflight, StringComparison.Ordinal) >= entry.IndexOf(". download.sh", StringComparison.Ordinal) || entry.Split(". cpu.sh", StringSplitOptions.None).Length != 2 || entry.Split(". proc.sh", StringSplitOptions.None).Length != 2) throw new InvalidOperationException("Actual composed CPU preflight must execute once before any Apple download."); var cases = new[] { ("positive-negative-exit", 33, 0, "14", CpuFlags, true, true), ("positive-negative-timeout", 33, 124, "14", CpuFlags, true, true), ("positive-normal-exit", 0, 0, "14", CpuFlags, true, false), ("positive-timeout", 124, 0, "14", CpuFlags, true, false), ("negative-passed", 33, 33, "14", CpuFlags, true, false), ("wrong-recovery", 33, 0, "13", CpuFlags, true, false), ("wrong-cpu-flags", 33, 0, "14", CpuFlags.Replace("enforce=on", "check"), true, false), ("wrong-rom-hash", 33, 0, "14", CpuFlags, false, false) }; foreach (var item in cases) { var work = Path.Combine(fixture, item.Item1); Directory.CreateDirectory(work); var script = """ set -euo pipefail disabled() { [ "$1" = N ]; } error() { printf '%s\n' "$*" >&2; } info() { printf '%s\n' "$*"; } qemu-system-x86_64() { printf '%s\n' 'QEMU emulator version 11.1.1 (Reims 11.1.3)'; } sha256sum() { cat >/dev/null; return "@@HASH_EXIT@@"; } mock_timeout() { printf '[fixture-command] %s\n' "$*" case "$*" in *,-avx2*) return @@NEGATIVE@@ ;; *) return @@POSITIVE@@ ;; esac } KVM=N; ARCH=amd64; CPU_MODEL=Haswell-noTSX; VERSION='@@VERSION@@' CPU_FLAGS='@@FLAGS@@'; QEMU_DIR='@@WORK@@' """.Replace("@@HASH_EXIT@@", item.Item6 ? "0" : "1", StringComparison.Ordinal) .Replace("@@NEGATIVE@@", item.Item3.ToString(), StringComparison.Ordinal) .Replace("@@POSITIVE@@", item.Item2.ToString(), StringComparison.Ordinal) .Replace("@@VERSION@@", item.Item4, StringComparison.Ordinal) .Replace("@@FLAGS@@", item.Item5, StringComparison.Ordinal) .Replace("@@WORK@@", work.Replace("'", "'\\''", StringComparison.Ordinal), StringComparison.Ordinal) + "\n" + TcgPreflight.Replace("/usr/bin/timeout", "mock_timeout", StringComparison.Ordinal) + "\nprintf '[fixture] Apple download reached after gate\\n'\n"; var path = Path.Combine(work, "fixture.sh"); File.WriteAllText(path, script, new UTF8Encoding(false)); var result = await Command("bash", [path], work, "gate", cancellation, requireSuccess: false); var reached = result.Output.Contains("Apple download reached after gate", StringComparison.Ordinal); Save(Path.Combine(work, "receipt.json"), new { success = (result.ExitCode == 0) == item.Item7 && reached == item.Item7, result.ExitCode, reachedAppleDownloadSeam = reached, qemuExecuted = false }); if ((result.ExitCode == 0) != item.Item7 || reached != item.Item7) throw new InvalidOperationException("Actual TCG preflight gate fixture failed: " + item.Item1); } } static string ReplaceOnce(string text, string oldValue, string newValue) => ReplaceAllExact(text, oldValue, newValue, 1); static string ReplaceAllExact(string text, string oldValue, string newValue, int expected) { var count = text.Split(oldValue, StringSplitOptions.None).Length - 1; if (count != expected) throw new InvalidOperationException($"Pinned source contract expected {expected} match(es), found {count}: {oldValue.Split('\n')[0]}"); return text.Replace(oldValue, newValue, StringComparison.Ordinal); } static void ValidateResult(string json, string token) { using var document = JsonDocument.Parse(json); var result = document.RootElement; if (result.GetProperty("token").GetString() != token || !result.GetProperty("success").GetBoolean() || !Version.TryParse(result.GetProperty("osVersion").GetString(), out var version) || version.Major < 14 || result.GetProperty("architecture").GetString() != "x86_64" || result.GetProperty("uid").GetInt32() != 0 || !System.Text.RegularExpressions.Regex.IsMatch(result.GetProperty("disk").GetString() ?? "", "^/dev/disk[0-9]+$") || result.GetProperty("diskBytes").GetInt64() != GuestDiskBytes || result.GetProperty("readOnly").GetBoolean() || new[] { "systemExit", "diskArbitrationExit", "recoveryExit", "diskListExit" }.Any(key => result.GetProperty(key).GetInt32() != 0)) throw new InvalidOperationException("The fresh guest receipt did not prove native macOS 14+/x86_64, service readiness and the writable 64-GiB disk."); } static void AssertContainer(string json, string token) { using var document = JsonDocument.Parse(json); var container = document.RootElement[0]; var config = container.GetProperty("HostConfig"); var devices = config.GetProperty("Devices"); var mounts = container.GetProperty("Mounts"); var environment = container.GetProperty("Config").GetProperty("Env").EnumerateArray().Select(value => value.GetString()).ToArray(); if (container.GetProperty("Config").GetProperty("Labels").GetProperty(OwnerLabel).GetString() != token || config.GetProperty("Privileged").GetBoolean() || config.GetProperty("NetworkMode").GetString() is not ("default" or "bridge") || config.GetProperty("Memory").GetInt64() != ContainerMemoryBytes || config.GetProperty("MemorySwap").GetInt64() != ContainerMemoryBytes || config.GetProperty("NanoCpus").GetInt64() != 2000000000 || config.GetProperty("ShmSize").GetInt64() != 536870912 || new[] { "CapAdd", "DeviceRequests", "Binds", "PortBindings", "DeviceCgroupRules", "Tmpfs" }.Any(key => config.TryGetProperty(key, out var value) && value.ValueKind != JsonValueKind.Null && (value.ValueKind == JsonValueKind.Array ? value.GetArrayLength() != 0 : value.EnumerateObject().Any())) || devices.GetArrayLength() != 0 || mounts.GetArrayLength() != 1 || mounts[0].GetProperty("Type").GetString() != "volume" || mounts[0].GetProperty("Destination").GetString() != "/storage" || !mounts[0].GetProperty("RW").GetBoolean() || new[] { "KVM=N", "CPU_MODEL=" + CpuModel, "VERSION=14" }.Any(expected => environment.Count(value => value is not null && value.StartsWith(expected.Split('=')[0] + "=", StringComparison.Ordinal)) != 1 || !environment.Contains(expected))) throw new InvalidOperationException("Created container exceeds the owned unprivileged TCG/Haswell/macOS 14 boundary."); } static async Task CaptureGuest(string id, string output, CancellationToken cancellation, bool final = false, string? token = null) { if (final && token is not null) await CaptureMonitor(id, output, token, cancellation); var logs = await Command("docker", ["logs", "--tail", "3000", id], output, "container", cancellation, requireSuccess: false); var stage = await Command("docker", ["exec", id, "cat", "/run/shm/native-stage.log"], output, "capture-native-stage", cancellation, requireSuccess: false); ReportCpuPreflight(output, stage.ExitCode == 0 ? stage.Output : logs.Output); await Command("docker", ["exec", id, "head", "-c", "4096", "/run/shm/kernel-handoffs.log"], output, "capture-kernel-handoffs", cancellation, requireSuccess: false, retainSuccessful: true); foreach (var file in new[] { ("proof.log", "guest-proof.log"), ("result.json", "guest-result.json") }) { var result = await Command("docker", ["exec", id, "cat", "/dev/shm/installstate/" + file.Item1], output, "capture-" + file.Item1, cancellation, requireSuccess: false); if (result.ExitCode == 0 && !string.IsNullOrWhiteSpace(result.Output)) File.WriteAllText(Path.Combine(output, file.Item2), result.Output); } // The immutable Recovery image is complete only after this staging marker. // Hash it once instead of rereading the image on every twenty-second poll. if ((logs.Output + stage.Output).Contains("[supported-profile] accelerator=tcg", StringComparison.Ordinal) && !File.Exists(Path.Combine(output, "guest-container-resources.last-success.json"))) await Command("docker", ["exec", id, "sh", "-c", "printf '[qemu]\n'; qemu-system-x86_64 --version | head -n 1; printf '[Recovery hash]\n'; test -f /storage/14/setup.dmg && sha256sum /storage/14/setup.dmg || exit 1; printf '[resources]\n'; df -Pk /storage; cat /sys/fs/cgroup/memory.max /sys/fs/cgroup/cpu.max 2>/dev/null || true"], output, "guest-container-resources", cancellation, requireSuccess: false, retainSuccessful: true); } static void ReportCpuPreflight(string output, string logs) { var receipt = Path.Combine(output, "cpu-preflight-runtime.json"); if (File.Exists(receipt)) return; var expectedSuffix = " cpu=" + CpuFlags + "; actual AVX/AVX2 executed before Apple download"; foreach (var line in logs.Split('\n')) { var match = System.Text.RegularExpressions.Regex.Match(line, @"\[cpu-preflight\] positive=33 negative=([0-9]{1,3})"); if (!match.Success || match.Groups[1].Value == "33" || !line[(match.Index + match.Length)..].StartsWith(expectedSuffix, StringComparison.Ordinal)) continue; var sourceMarker = match.Value + expectedSuffix; var marker = "[cpu-preflight] positive=33 negative=" + match.Groups[1].Value + " accelerator=tcg cpu=" + CpuModel + " instructions=AVX/AVX2"; Console.WriteLine(marker); Save(receipt, new { marker, markerSha256 = Hash(Encoding.UTF8.GetBytes(sourceMarker)), capturedUtc = DateTimeOffset.UtcNow, readinessGateSatisfied = false }); return; } } static int KernelHandoffs(string logs) => logs.Split('\n').Count(line => line.Trim().StartsWith("#[EB|LOG:HANDOFF TO XNU] ", StringComparison.Ordinal)); static void ValidateBootProgress() { const string handoff = "#[EB|LOG:HANDOFF TO XNU] _\r\n"; foreach (var (logs, count) in new[] { ("", 0), ("BdsDxe: starting Boot0002\n", 0), (handoff, 1), (handoff + handoff, 2), ("source says \"" + handoff, 0), ("#[EB|LOG:HANDOFF TO XNU-ish] _\n", 0) }) if (KernelHandoffs(logs) != count) throw new InvalidOperationException("Recovery boot-progress parser accepted missing, quoted or malformed markers."); } static async Task CheckRecoveryBootProgress(string id, string output, CancellationToken cancellation) { var retained = Path.Combine(output, "capture-kernel-handoffs.last-success.stdout.log"); var count = KernelHandoffs(File.ReadAllText(File.Exists(retained) ? retained : Path.Combine(output, "container.stdout.log"))); Save(Path.Combine(output, "recovery-boot-progress.json"), new { kernelHandoffs = count, unexpectedRepeat = count >= 2, capturedUtc = DateTimeOffset.UtcNow }); if (count >= 2) throw new InvalidOperationException("Recovery returned to kernel boot before readiness; repeated handoff detected. See serial/exception logs; this does not identify the reset cause."); if (!File.ReadAllText(Path.Combine(output, "capture-native-stage.stdout.log")).Contains("[supported-profile] accelerator=tcg", StringComparison.Ordinal)) return; using var deadline = CancellationTokenSource.CreateLinkedTokenSource(cancellation); deadline.CancelAfter(TimeSpan.FromSeconds(8)); var monitor = await Command("docker", ["exec", id, "sh", "-c", "test -S /run/shm/monitor.sock || exit 1; printf 'info status\\n' | /usr/bin/timeout -s KILL 5 /usr/bin/nc.openbsd -q 1 -w 2 -U /run/shm/monitor.sock"], output, "recovery-vm-status", deadline.Token, requireSuccess: false); if (monitor.ExitCode == 0 && System.Text.RegularExpressions.Regex.IsMatch(monitor.Output, @"(?m)^VM status: (shutdown|paused|internal-error|guest-panicked)(?:\s+\([^\r\n]*\))?\r?$")) throw new InvalidOperationException("Recovery VM halted before readiness. The first reset was retained for exception/monitor evidence."); } static async Task CapturePressure(string id, string output, string phase, CancellationToken cancellation) { using var snapshotDeadline = CancellationTokenSource.CreateLinkedTokenSource(cancellation); snapshotDeadline.CancelAfter(TimeSpan.FromSeconds(20)); const string snapshot = """ printf '[snapshot UTC]\n'; date -u '+%Y-%m-%dT%H:%M:%SZ' for path in /proc/meminfo /proc/pressure/cpu /proc/pressure/memory /proc/pressure/io \ /sys/fs/cgroup/cpu.max /sys/fs/cgroup/cpu.stat /sys/fs/cgroup/cpu.pressure \ /sys/fs/cgroup/memory.max /sys/fs/cgroup/memory.current /sys/fs/cgroup/memory.peak \ /sys/fs/cgroup/memory.events /sys/fs/cgroup/memory.stat /sys/fs/cgroup/memory.pressure \ /sys/fs/cgroup/memory.swap.current; do printf '\n[%s]\n' "$path" if [ -r "$path" ]; then cat "$path"; else printf 'unavailable\n'; fi done printf '\n[host paging counters]\n' awk '/^(pgmajfault|pswpin|pswpout) / {print}' /proc/vmstat """; try { await Command("docker", ["exec", id, "sh", "-c", snapshot], output, "capture-pressure-" + phase, snapshotDeadline.Token, requireSuccess: false, retainSuccessful: true); } catch (Exception exception) { // Optional evidence must not replace the guest outcome or prevent cleanup. try { Save(Path.Combine(output, "capture-pressure-" + phase + ".unavailable.json"), new { phase, error = exception.Message, capturedUtc = DateTimeOffset.UtcNow }); } catch (Exception evidenceError) { Console.Error.WriteLine("Optional pressure evidence: " + evidenceError.Message); } } } static async Task CaptureMonitor(string id, string output, string token, CancellationToken cancellation) { using var deadline = CancellationTokenSource.CreateLinkedTokenSource(cancellation); deadline.CancelAfter(TimeSpan.FromSeconds(10)); int? monitorExit = null, copyExit = null; string? error = null; try { if (!System.Text.RegularExpressions.Regex.IsMatch(id, "^[0-9a-f]{64}$") || !System.Text.RegularExpressions.Regex.IsMatch(token, "^[0-9a-f]{32}$")) throw new InvalidOperationException("No saved owned container identity for the optional monitor capture."); var inspection = await Command("docker", ["inspect", id], output, "capture-monitor-container", deadline.Token); AssertContainer(inspection.Output, token); using (var document = JsonDocument.Parse(inspection.Output)) if (document.RootElement[0].GetProperty("Id").GetString() != id || !document.RootElement[0].GetProperty("State").GetProperty("Running").GetBoolean()) throw new InvalidOperationException("Owned guest container is no longer running for the optional monitor capture."); var screen = "/tmp/native-diagnostic-screen-" + token + ".ppm"; var monitor = await Command("docker", ["exec", id, "sh", "-c", """ test -S /run/shm/monitor.sock || exit 1 rm -f -- "$1" || exit 1 printf 'info kvm\ninfo status\nscreendump %s\n' "$1" | /usr/bin/timeout -s KILL 5 /usr/bin/nc.openbsd -q 1 -w 2 -U /run/shm/monitor.sock monitor_exit=$? printf '\n[monitor-exit] %s\n' "$monitor_exit" [ "$monitor_exit" -eq 0 ] || exit "$monitor_exit" bytes=$(stat -c%s "$1") || exit 1 [ "$bytes" -gt 0 ] && [ "$bytes" -le 8388608 ] || exit 1 printf '[screen-bytes] %s\n' "$bytes" """, "native-monitor", screen], output, "capture-monitor", deadline.Token, requireSuccess: false); monitorExit = monitor.ExitCode; if (monitorExit != 0) throw new InvalidOperationException("Optional monitor status/screenshot command exited " + monitorExit + "."); var copy = await Command("docker", ["cp", id + ":" + screen, Path.Combine(output, "guest-screen-" + token + ".ppm")], output, "capture-monitor-screen", deadline.Token, requireSuccess: false); copyExit = copy.ExitCode; if (copyExit != 0) throw new InvalidOperationException("Optional monitor screenshot copy exited " + copyExit + "."); } catch (Exception exception) { error = exception.Message; Console.Error.WriteLine("Optional final monitor capture: " + error); } finally { Save(Path.Combine(output, "monitor-capture.json"), new { token, monitorExit, copyExit, success = error is null, error, capturedUtc = DateTimeOffset.UtcNow }); } } static async Task Cleanup(string output) { var path = Path.Combine(output, "owned-resources.json"); if (!File.Exists(path)) return true; var state = JsonSerializer.Deserialize(File.ReadAllText(path), JsonOptions) ?? throw new InvalidOperationException("Invalid owned-resource receipt."); if (!System.Text.RegularExpressions.Regex.IsMatch(state.Token, "^[0-9a-f]{32}$") || state.ContainerName != "meeting-assistant-native-" + state.Token || state.ImageTag != "meeting-assistant-native-diagnostic:" + state.Token) throw new InvalidOperationException("Invalid cleanup ownership identity."); using var deadline = new CancellationTokenSource(TimeSpan.FromSeconds(90)); try { foreach (var kind in new[] { "container", "image" }) { var name = kind == "container" ? state.ContainerName : state.ImageTag; var inspect = await Command("docker", [kind, "inspect", name], output, "cleanup-" + kind + "-inspect", deadline.Token, requireSuccess: false); if (inspect.ExitCode != 0) { if (inspect.Error.Contains("No such object", StringComparison.Ordinal) || inspect.Error.Contains("No such container", StringComparison.Ordinal) || inspect.Error.Contains("No such image", StringComparison.Ordinal)) continue; throw new InvalidOperationException("Cannot establish owned " + kind + " absence: " + inspect.Error); } using var document = JsonDocument.Parse(inspect.Output); var resource = document.RootElement[0]; if (resource.GetProperty("Config").GetProperty("Labels").GetProperty(OwnerLabel).GetString() != state.Token) throw new InvalidOperationException("Cleanup refuses a resource without this run's exact ownership label."); var id = resource.GetProperty("Id").GetString()!; var expectedId = kind == "container" ? state.ContainerId : state.ImageId; if (expectedId is not null && expectedId != id) throw new InvalidOperationException("Cleanup refuses a resource whose ID changed after creation."); await Command("docker", kind == "container" ? ["rm", "--force", "--volumes", id] : ["image", "rm", id], output, "cleanup-" + kind + "-remove", deadline.Token); } if (Path.GetFileName(state.WorkDirectory) == "meeting-assistant-native-" + state.Token && File.Exists(Path.Combine(state.WorkDirectory, "run.owner")) && File.ReadAllText(Path.Combine(state.WorkDirectory, "run.owner")) == state.Token) Directory.Delete(state.WorkDirectory, true); Save(Path.Combine(output, "cleanup.json"), new { state.Token, success = true, completedUtc = DateTimeOffset.UtcNow }); return true; } catch (Exception exception) { Save(Path.Combine(output, "cleanup.json"), new { state.Token, success = false, error = exception.Message, completedUtc = DateTimeOffset.UtcNow }); Console.Error.WriteLine("Owned diagnostic cleanup failed: " + exception.Message); return false; } } static async Task ValidateRecoveryPatch(string output) { if (Crc32(Encoding.ASCII.GetBytes("123456789")) != 0xcbf43926) throw new InvalidOperationException("Independent C# CRC32 known vector failed."); var fixture = Path.Combine(output, "validation-recovery-patch"); Directory.CreateDirectory(fixture); var patch = File.ReadAllText(Path.Combine(output, "recovery-patch.py")); const string marker = "SCRIPT_ORIGINAL = b'''"; var start = patch.IndexOf(marker, StringComparison.Ordinal) + marker.Length; var end = patch.IndexOf("'''", start, StringComparison.Ordinal); var bootstrap = patch[start..end]; var cases = new[] { ("13-zlib", OriginalDaemon13, true, true), ("14-zlib", OriginalDaemon + "\n", true, true), ("13-raw", OriginalDaemon13, false, true), ("14-raw", OriginalDaemon + "\n", false, true), ("unknown", OriginalDaemon13.Replace("Interactive", "Unknown"), true, false), ("duplicate", OriginalDaemon13 + OriginalDaemon + "\n", true, false), ("duplicate-unknown", OriginalDaemon13 + OriginalDaemon13.Replace("Interactive", "Unknown"), true, false), ("malformed", OriginalDaemon13.Replace("", ""), true, false), ("wrong-arguments", OriginalDaemon13.Replace("/usr/libexec/recoveryosd", "/usr/libexec/wrongdaemon"), true, false), ("duplicate-arguments", OriginalDaemon13.Replace("", "/usr/libexec/recoveryosd"), true, false), ("corrupt-data-crc", OriginalDaemon13, true, false), ("unsupported-crc", OriginalDaemon13, true, false), ("xml-boundary", OriginalDaemon13, true, false), ("physical-boundary", OriginalDaemon13, true, false), ("unknown-zero-run", OriginalDaemon13, true, false), ("logical-boundary", OriginalDaemon13, false, false) }; foreach (var item in cases) { var path = Path.Combine(fixture, item.Item1 + ".dmg"); CreateRecoveryFixture(path, bootstrap, item.Item2, item.Item3); if (item.Item1 is "corrupt-data-crc" or "unsupported-crc" or "xml-boundary" or "physical-boundary" or "unknown-zero-run" or "logical-boundary") { var corrupt = File.ReadAllBytes(path); var trailer = corrupt.Length - 512; if (item.Item1 == "corrupt-data-crc") corrupt[trailer + 88] ^= 1; else if (item.Item1 == "unsupported-crc") BinaryPrimitives.WriteUInt32BigEndian(corrupt.AsSpan(trailer + 80), 3); else if (item.Item1 == "xml-boundary") BinaryPrimitives.WriteUInt64BigEndian(corrupt.AsSpan(trailer + 224), (ulong)corrupt.Length); else if (item.Item1 == "logical-boundary") BinaryPrimitives.WriteUInt64BigEndian(corrupt.AsSpan(trailer + 492), 1); else { var xmlOffset = checked((int)BinaryPrimitives.ReadUInt64BigEndian(corrupt.AsSpan(trailer + 216))); var xmlLength = checked((int)BinaryPrimitives.ReadUInt64BigEndian(corrupt.AsSpan(trailer + 224))); var xmlText = Encoding.UTF8.GetString(corrupt, xmlOffset, xmlLength); var data = XDocument.Parse(xmlText).Descendants("data").Single().Value; var mish = Convert.FromBase64String(data); if (item.Item1 == "physical-boundary") BinaryPrimitives.WriteUInt64BigEndian(mish.AsSpan(236), (ulong)corrupt.Length); else BinaryPrimitives.WriteUInt32BigEndian(mish.AsSpan(204), 0); var replacement = Encoding.UTF8.GetBytes(ReplaceOnce(xmlText, data, Convert.ToBase64String(mish))); replacement.CopyTo(corrupt, xmlOffset); } File.WriteAllBytes(path, corrupt); } var before = File.ReadAllBytes(path); var result = await Command("python3", ["-B", Path.Combine(output, "recovery-patch.py"), path], fixture, item.Item1, CancellationToken.None, requireSuccess: false); var after = File.ReadAllBytes(path); if ((result.ExitCode == 0) != item.Item4) throw new InvalidOperationException("Recovery fixture result mismatch: " + item.Item1 + ": " + result.Error); if (!item.Item4 && !before.SequenceEqual(after)) throw new InvalidOperationException("Rejected Recovery fixture was modified: " + item.Item1); if (item.Item4) { var decoded = DecodeRecoveryFixture(after, item.Item3); var original = Encoding.UTF8.GetBytes(item.Item2); var expectedText = item.Item1.StartsWith("13", StringComparison.Ordinal) ? DiagnosticDaemon13 : DiagnosticDaemon; var expected = Encoding.UTF8.GetBytes(expectedText.PadRight(item.Item2.Length, ' ')); if (before.Length != after.Length || !decoded.AsSpan(4096, original.Length).SequenceEqual(expected)) throw new InvalidOperationException("Recovery fixture changed byte extent or daemon fields: " + item.Item1); ValidateDaemon(expectedText, item.Item1.StartsWith("13", StringComparison.Ordinal) ? "Interactive" : "App", true); VerifyRecoveryFixtureChecksums(after, decoded); } } Save(Path.Combine(fixture, "receipt.json"), new { success = true, positiveCases = 4, negativeCases = 12, rejectedImagesUnmodified = true, knownDaemonFieldsPreserved = true, readBackCrc32IndependentlyVerified = true, syntheticUdifFixtures = true, guestExecuted = false }); } static uint Crc32(ReadOnlySpan bytes) { var crc = uint.MaxValue; foreach (var value in bytes) { crc ^= value; for (var bit = 0; bit < 8; bit++) crc = (crc >> 1) ^ ((crc & 1) != 0 ? 0xedb88320u : 0); } return ~crc; } static void CreateRecoveryFixture(string path, string bootstrap, string daemon, bool compressed) { var decoded = new byte[16384]; Encoding.UTF8.GetBytes(bootstrap).CopyTo(decoded, 64); Encoding.UTF8.GetBytes(daemon).CopyTo(decoded, 4096); byte[] stored; if (compressed) { using var memory = new MemoryStream(); using (var zipper = new ZLibStream(memory, CompressionLevel.Fastest, true)) zipper.Write(decoded); stored = memory.ToArray(); } else stored = decoded; var mish = new byte[284]; Encoding.ASCII.GetBytes("mish").CopyTo(mish, 0); BinaryPrimitives.WriteUInt32BigEndian(mish.AsSpan(4), 1); BinaryPrimitives.WriteUInt64BigEndian(mish.AsSpan(16), 32); BinaryPrimitives.WriteUInt32BigEndian(mish.AsSpan(64), 2); BinaryPrimitives.WriteUInt32BigEndian(mish.AsSpan(68), 32); BinaryPrimitives.WriteUInt32BigEndian(mish.AsSpan(72), Crc32(decoded)); BinaryPrimitives.WriteUInt32BigEndian(mish.AsSpan(200), 2); BinaryPrimitives.WriteUInt32BigEndian(mish.AsSpan(204), compressed ? 0x80000005u : 1u); BinaryPrimitives.WriteUInt64BigEndian(mish.AsSpan(220), 32); BinaryPrimitives.WriteUInt64BigEndian(mish.AsSpan(236), (ulong)stored.Length); BinaryPrimitives.WriteUInt32BigEndian(mish.AsSpan(244), 0xffffffff); var xml = Encoding.UTF8.GetBytes("\nresource-forkblkxData" + Convert.ToBase64String(mish) + "\n"); var koly = new byte[512]; Encoding.ASCII.GetBytes("koly").CopyTo(koly, 0); BinaryPrimitives.WriteUInt32BigEndian(koly.AsSpan(4), 4); BinaryPrimitives.WriteUInt32BigEndian(koly.AsSpan(8), 512); BinaryPrimitives.WriteUInt32BigEndian(koly.AsSpan(12), 1); BinaryPrimitives.WriteUInt64BigEndian(koly.AsSpan(32), (ulong)stored.Length); BinaryPrimitives.WriteUInt32BigEndian(koly.AsSpan(80), 2); BinaryPrimitives.WriteUInt32BigEndian(koly.AsSpan(84), 32); BinaryPrimitives.WriteUInt32BigEndian(koly.AsSpan(88), Crc32(stored)); BinaryPrimitives.WriteUInt64BigEndian(koly.AsSpan(216), (ulong)stored.Length); BinaryPrimitives.WriteUInt64BigEndian(koly.AsSpan(224), (ulong)xml.Length); BinaryPrimitives.WriteUInt32BigEndian(koly.AsSpan(352), 2); BinaryPrimitives.WriteUInt32BigEndian(koly.AsSpan(356), 32); BinaryPrimitives.WriteUInt32BigEndian(koly.AsSpan(360), Crc32(mish.AsSpan(72, 4))); BinaryPrimitives.WriteUInt64BigEndian(koly.AsSpan(492), 32); File.WriteAllBytes(path, stored.Concat(xml).Concat(koly).ToArray()); } static byte[] DecodeRecoveryFixture(byte[] image, bool compressed) { var length = checked((int)BinaryPrimitives.ReadUInt64BigEndian(image.AsSpan(image.Length - 512 + 32))); if (!compressed) return image[..length]; using var input = new MemoryStream(image, 0, length); using var decoder = new ZLibStream(input, CompressionMode.Decompress); using var output = new MemoryStream(); decoder.CopyTo(output); return output.ToArray(); } static void VerifyRecoveryFixtureChecksums(byte[] image, byte[] decoded) { var trailer = image.Length - 512; var length = checked((int)BinaryPrimitives.ReadUInt64BigEndian(image.AsSpan(trailer + 32))); var xmlLength = checked((int)BinaryPrimitives.ReadUInt64BigEndian(image.AsSpan(trailer + 224))); var xml = XDocument.Parse(Encoding.UTF8.GetString(image, length, xmlLength)); var mish = Convert.FromBase64String(xml.Descendants("data").Single().Value); if (Crc32(image.AsSpan(0, length)) != BinaryPrimitives.ReadUInt32BigEndian(image.AsSpan(trailer + 88)) || Crc32(decoded) != BinaryPrimitives.ReadUInt32BigEndian(mish.AsSpan(72)) || Crc32(mish.AsSpan(72, 4)) != BinaryPrimitives.ReadUInt32BigEndian(image.AsSpan(trailer + 360))) throw new InvalidOperationException("Independent C# fixture CRC32 readback failed."); } static async Task ValidateResourceRetention(string output) { var fixture = Path.Combine(output, "validation-resource-retention"); Directory.CreateDirectory(fixture); const string label = "capture-resource-fixture"; const string successful = "Successful snapshot before stopped-container capture.\n"; await Command("bash", ["-c", "printf '%s\\n' 'Successful snapshot before stopped-container capture.'"], fixture, label, CancellationToken.None, retainSuccessful: true); await Command("bash", ["-c", "printf '%s\\n' 'Container is not running.' >&2; exit 1"], fixture, label, CancellationToken.None, requireSuccess: false, retainSuccessful: true); var retained = Path.Combine(fixture, label + ".last-success.stdout.log"); if (!File.Exists(retained) || File.ReadAllText(retained) != successful || File.ReadAllText(Path.Combine(fixture, label + ".stdout.log")) != "" || !File.ReadAllText(Path.Combine(fixture, label + ".stderr.log")).Contains("Container is not running.")) throw new InvalidOperationException("A failed final capture lost the last successful resource snapshot."); using var receipt = JsonDocument.Parse(File.ReadAllText(Path.Combine(fixture, label + ".last-success.json"))); if (receipt.RootElement.GetProperty("stdoutSha256").GetString() != Hash(Encoding.UTF8.GetBytes(successful)) || receipt.RootElement.GetProperty("exitCode").GetInt32() != 0) throw new InvalidOperationException("Last successful snapshot receipt does not identify the retained bytes."); } static async Task Command(string executable, string[] arguments, string output, string label, CancellationToken cancellation, bool requireSuccess = true, bool echo = false, bool retainSuccessful = false) { if (!label.StartsWith("capture-", StringComparison.Ordinal) && label is not "container" and not "container-running" and not "guest-container-resources") Console.WriteLine("[native-diagnostic] " + label); using var commandCancellation = CancellationTokenSource.CreateLinkedTokenSource(cancellation); var commandToken = commandCancellation.Token; var start = new ProcessStartInfo(executable) { RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false }; foreach (var argument in arguments) start.ArgumentList.Add(argument); start.Environment["GIT_TERMINAL_PROMPT"] = "0"; using var process = Process.Start(start) ?? throw new InvalidOperationException("Cannot start " + executable); async Task Read(StreamReader reader, string stream) { var captured = new StringBuilder(); var buffer = new char[8192]; using var log = new StreamWriter(Path.Combine(output, label + "." + stream + ".log"), false, new UTF8Encoding(false)); while (true) { var count = await reader.ReadAsync(buffer.AsMemory(), commandToken); if (count == 0) break; if (captured.Length + count > MaximumCapturedCharacters) { commandCancellation.Cancel(); throw new InvalidOperationException(label + " exceeded its bounded diagnostic log size."); } captured.Append(buffer, 0, count); await log.WriteAsync(buffer.AsMemory(0, count), commandToken); await log.FlushAsync(commandToken); if (echo) Console.Write(new string(buffer, 0, count)); } return captured.ToString(); } var stdout = Read(process.StandardOutput, "stdout"); var stderr = Read(process.StandardError, "stderr"); try { await Task.WhenAll(stdout, stderr, process.WaitForExitAsync(commandToken)); var result = new CommandResult(process.ExitCode, await stdout, await stderr); if (retainSuccessful && result.ExitCode == 0 && !string.IsNullOrWhiteSpace(result.Output)) { File.WriteAllText(Path.Combine(output, label + ".last-success.stdout.log"), result.Output, new UTF8Encoding(false)); Save(Path.Combine(output, label + ".last-success.json"), new { exitCode = result.ExitCode, stdoutSha256 = Hash(Encoding.UTF8.GetBytes(result.Output)), capturedUtc = DateTimeOffset.UtcNow }); } if (requireSuccess && result.ExitCode != 0) throw new InvalidOperationException($"{label} exited {result.ExitCode}: {result.Error[..Math.Min(result.Error.Length, 1500)]}"); return result; } catch { try { if (!process.HasExited) process.Kill(entireProcessTree: true); } catch (InvalidOperationException) { } throw; } } static string Hash(byte[] bytes) => Convert.ToHexStringLower(SHA256.HashData(bytes)); static void PrintGuestProof(string output, string token) { var path = Path.Combine(output, "guest-proof.log"); if (!File.Exists(path)) { Console.WriteLine("[native-diagnostic] No native guest proof was captured."); return; } var proof = File.ReadAllText(path).Replace(token, "", StringComparison.Ordinal); const int budget = 512 * 1024; if (proof.Length > budget) proof = proof[..(64 * 1024)] + "\n[native-diagnostic] Middle of proof omitted from CI stdout; complete bounded proof is retained in the artifact.\n" + proof[^((budget - 64 * 1024))..]; Console.WriteLine("[native-diagnostic] Final native guest proof:"); Console.Write(proof); } static void Save(string path, object value) { var temporary = path + ".tmp"; File.WriteAllText(temporary, JsonSerializer.Serialize(value, JsonOptions), new UTF8Encoding(false)); File.Move(temporary, path, overwrite: true); } sealed record OwnedResources(string Token, string ContainerName, string ImageTag, string WorkDirectory, string? ContainerId = null, string? ImageId = null); sealed record CommandResult(int ExitCode, string Output, string Error); }