lib/machine/src/checkpoint/test.zig

daab053ee43316e1809a84551d573ddd1e5bf3d2

   1 const admission = @import("../admission/root.zig");
   2 const checkpoint = @import("root.zig");
   3 const checkpoint_owner = @import("owner/root.zig");
   4 const core = @import("machine_instance_core");
   5 const fixture = @import("../instance/fixture/root.zig").fixture;
   6 const instance = @import("../instance/root.zig");
   7 const os = @import("os");
   8 const profile = @import("../profile/root.zig");
   9 const std = @import("std");
  10 
  11 const real_k0_elf = @embedFile("machine-k0-elf");
  12 const real_k0_manifest = @embedFile("machine-k0-manifest");
  13 const layout = core.layout;
  14 
  15 test {
  16     _ = @import("roots/test.zig");
  17 }
  18 
  19 var first_ram: [checkpoint.ram_bytes]u8 align(checkpoint.ram_alignment) = undefined;
  20 var second_ram: [checkpoint.ram_bytes]u8 align(checkpoint.ram_alignment) = undefined;
  21 var third_ram: [checkpoint.ram_bytes]u8 align(checkpoint.ram_alignment) = undefined;
  22 var checkpoint_stream: [checkpoint.stream.stream_bytes + 1]u8 = undefined;
  23 
  24 const Captured = struct {
  25     value: checkpoint.Checkpoint,
  26     receipt: instance.QuiescenceReceipt,
  27 };
  28 
  29 const Turn = struct {
  30     delivery: admission.Delivery,
  31     events: instance.EventBatch,
  32     receipt: instance.QuiescenceReceipt,
  33 };
  34 
  35 const PageTableCorruption = struct {
  36     address: u64,
  37     index: usize,
  38     mask: u64,
  39 };
  40 
  41 const FragmentedReader = struct {
  42     source: []const u8,
  43     chunk_bytes: usize,
  44     offset: usize = 0,
  45     failure_offset: ?usize = null,
  46     claim_probe: ?*checkpoint.Storage = null,
  47     claim_checked: bool = false,
  48     claim_observed: bool = false,
  49     claim_missing: bool = false,
  50     buffer: [31]u8 = undefined,
  51     reader: std.Io.Reader = .{
  52         .vtable = &vtable,
  53         .buffer = undefined,
  54         .seek = 0,
  55         .end = 0,
  56     },
  57 
  58     fn init(source: []const u8, chunk_bytes: usize) FragmentedReader {
  59         std.debug.assert(chunk_bytes > 0);
  60         return .{ .source = source, .chunk_bytes = chunk_bytes };
  61     }
  62 
  63     fn attachUnbuffered(self: *FragmentedReader) void {
  64         self.reader.buffer = self.buffer[0..0];
  65     }
  66 
  67     const vtable: std.Io.Reader.VTable = .{
  68         .stream = stream,
  69         .discard = discard,
  70         .readVec = readVec,
  71     };
  72 
  73     fn stream(
  74         reader: *std.Io.Reader,
  75         writer: *std.Io.Writer,
  76         limit: std.Io.Limit,
  77     ) std.Io.Reader.StreamError!usize {
  78         const self: *FragmentedReader = @alignCast(
  79             @fieldParentPtr("reader", reader),
  80         );
  81         var scratch: [4096]u8 = undefined;
  82         const destination = limit.slice(&scratch);
  83         if (destination.len == 0) return 0;
  84         const length = try self.readInto(destination);
  85         if (length == 0) return error.EndOfStream;
  86         writer.writeAll(destination[0..length]) catch
  87             return error.WriteFailed;
  88         return length;
  89     }
  90 
  91     fn discard(
  92         reader: *std.Io.Reader,
  93         limit: std.Io.Limit,
  94     ) std.Io.Reader.Error!usize {
  95         const self: *FragmentedReader = @alignCast(
  96             @fieldParentPtr("reader", reader),
  97         );
  98         const destination = limit.slice(reader.buffer);
  99         if (destination.len == 0) return 0;
 100         const length = try self.readInto(destination);
 101         if (length == 0) return error.EndOfStream;
 102         return length;
 103     }
 104 
 105     fn readVec(
 106         reader: *std.Io.Reader,
 107         data: [][]u8,
 108     ) std.Io.Reader.Error!usize {
 109         const self: *FragmentedReader = @alignCast(
 110             @fieldParentPtr("reader", reader),
 111         );
 112         for (data) |destination| {
 113             if (destination.len == 0) continue;
 114             const length = try self.readInto(destination);
 115             if (length == 0) return error.EndOfStream;
 116             return length;
 117         }
 118         const destination = reader.buffer[reader.end..];
 119         if (destination.len == 0) return 0;
 120         const length = try self.readInto(destination);
 121         if (length == 0) return error.EndOfStream;
 122         reader.end += length;
 123         return 0;
 124     }
 125 
 126     fn readInto(
 127         self: *FragmentedReader,
 128         destination: []u8,
 129     ) std.Io.Reader.Error!usize {
 130         if (!self.claim_checked and
 131             self.offset >= checkpoint.stream.header_bytes)
 132         {
 133             if (self.claim_probe) |storage| {
 134                 self.claim_checked = true;
 135                 if (checkpoint_owner.ensureAvailable(storage)) |_| {
 136                     self.claim_missing = true;
 137                 } else |failure| switch (failure) {
 138                     error.CheckpointStorageInUse => {
 139                         self.claim_observed = true;
 140                     },
 141                     else => return error.ReadFailed,
 142                 }
 143             }
 144         }
 145         if (self.failure_offset) |offset| {
 146             if (self.offset >= offset) return error.ReadFailed;
 147         }
 148         const remaining = self.source.len - self.offset;
 149         const length = @min(destination.len, self.chunk_bytes, remaining);
 150         @memcpy(destination[0..length], self.source[self.offset..][0..length]);
 151         self.offset += length;
 152         return length;
 153     }
 154 };
 155 
 156 const ComparingWriter = struct {
 157     expected: []const u8,
 158     chunk_bytes: usize,
 159     offset: usize = 0,
 160     mismatch: bool = false,
 161     buffer: [0]u8 = .{},
 162     writer: std.Io.Writer = .{
 163         .vtable = &vtable,
 164         .buffer = undefined,
 165     },
 166 
 167     fn init(expected: []const u8, chunk_bytes: usize) ComparingWriter {
 168         std.debug.assert(chunk_bytes > 0);
 169         return .{ .expected = expected, .chunk_bytes = chunk_bytes };
 170     }
 171 
 172     fn attach(self: *ComparingWriter) void {
 173         self.writer.buffer = &self.buffer;
 174     }
 175 
 176     const vtable: std.Io.Writer.VTable = .{ .drain = drain };
 177 
 178     fn drain(
 179         writer: *std.Io.Writer,
 180         data: []const []const u8,
 181         splat: usize,
 182     ) std.Io.Writer.Error!usize {
 183         const self: *ComparingWriter = @alignCast(
 184             @fieldParentPtr("writer", writer),
 185         );
 186         std.debug.assert(writer.end == 0);
 187         var budget = self.chunk_bytes;
 188         var consumed: usize = 0;
 189         for (data[0 .. data.len - 1]) |bytes| {
 190             const length = self.compare(bytes, budget);
 191             consumed += length;
 192             budget -= length;
 193             if (length != bytes.len or budget == 0) return consumed;
 194         }
 195         const pattern = data[data.len - 1];
 196         var repetition: usize = 0;
 197         while (repetition < splat and budget > 0) : (repetition += 1) {
 198             const length = self.compare(pattern, budget);
 199             consumed += length;
 200             budget -= length;
 201             if (length != pattern.len) return consumed;
 202         }
 203         return consumed;
 204     }
 205 
 206     fn compare(self: *ComparingWriter, bytes: []const u8, limit: usize) usize {
 207         const length = @min(bytes.len, limit);
 208         const available = if (self.offset < self.expected.len)
 209             self.expected.len - self.offset
 210         else
 211             0;
 212         const compared = @min(length, available);
 213         if (!std.mem.eql(
 214             u8,
 215             bytes[0..compared],
 216             self.expected[self.offset..][0..compared],
 217         ) or compared != length) {
 218             self.mismatch = true;
 219         }
 220         self.offset += length;
 221         return length;
 222     }
 223 };
 224 
 225 test "canonical checkpoint root is neutral to activation fences" {
 226     var first_storage = checkpoint.Storage.init();
 227     const first = try captureAt(
 228         7,
 229         0x71,
 230         &first_storage,
 231         &first_ram,
 232     );
 233     try first.value.verify();
 234     const first_root = try first.value.root();
 235 
 236     var second_storage = checkpoint.Storage.init();
 237     const second = try captureAt(
 238         11,
 239         0x91,
 240         &second_storage,
 241         &second_ram,
 242     );
 243     try second.value.verify();
 244     const second_root = try second.value.root();
 245 
 246     try std.testing.expect(!std.mem.eql(
 247         u8,
 248         &first.receipt.fenced_digest,
 249         &second.receipt.fenced_digest,
 250     ));
 251     try std.testing.expectEqualDeep(first_root.state, second_root.state);
 252     try std.testing.expectEqualDeep(first_root, second_root);
 253     try std.testing.expectEqualSlices(u8, &first_ram, &second_ram);
 254 
 255     const reopened = try checkpoint.open(&first_storage, &first_ram, first_root);
 256     try std.testing.expectEqualDeep(first_root, try reopened.root());
 257     var wrong_root = first_root;
 258     wrong_root.digest[0] ^= 1;
 259     try std.testing.expectError(
 260         error.CheckpointRootMismatch,
 261         checkpoint.open(&first_storage, &first_ram, wrong_root),
 262     );
 263     try std.testing.expectError(
 264         error.CheckpointRootMismatch,
 265         checkpoint.recoverAfterCrash(&first_storage, &first_ram, null),
 266     );
 267     @memcpy(&third_ram, &first_ram);
 268     const relocated = try checkpoint.open(&first_storage, &third_ram, first_root);
 269     try std.testing.expectEqualDeep(first_root, try relocated.root());
 270     switch (try checkpoint.recoverAfterCrash(
 271         &first_storage,
 272         &first_ram,
 273         first_root,
 274     )) {
 275         .published => |recovered| {
 276             try std.testing.expectEqualDeep(first_root, try recovered.root());
 277         },
 278         .empty => return error.TestExpectedPublishedCheckpoint,
 279     }
 280 }
 281 
 282 test "canonical checkpoint stream is fence-neutral and round trips exactly" {
 283     var first_storage = checkpoint.Storage.init();
 284     const first = try captureAt(7, 0x71, &first_storage, &first_ram);
 285     const expected_root = try first.value.root();
 286     try encodeCheckpointStream(&first.value);
 287     const first_digest = streamDigest();
 288     try std.testing.expectEqualSlices(u8, &[_]u8{
 289         'M', 'C', 'H', 'C', 'K', 'P', '1', 0,
 290         1,   0,   0,   16,  0,   0,   1,   0,
 291         0,   16,  0,   4,   0,   0,   0,   0,
 292         0,   0,   0,   4,   0,   0,   0,   0,
 293         0,   16,  0,   0,   1,   0,   2,   0,
 294         4,   0,   32,  0,   32,  0,   96,  0,
 295         56,  1,   72,  0,   168, 0,
 296     }, checkpoint_stream[0..54]);
 297     try expectZero(checkpoint_stream[54..64]);
 298 
 299     var second_storage = checkpoint.Storage.init();
 300     const second = try captureAt(11, 0x91, &second_storage, &second_ram);
 301     try std.testing.expectEqualDeep(expected_root, try second.value.root());
 302     try expectExactCheckpointStream(&second.value);
 303 
 304     var reopened_storage = checkpoint.Storage.init();
 305     var source_reader = FragmentedReader.init(
 306         checkpoint_stream[0..checkpoint.stream.stream_bytes],
 307         4093,
 308     );
 309     source_reader.claim_probe = &reopened_storage;
 310     source_reader.attachUnbuffered();
 311     const reopened = try checkpoint.stream.decodeDisjoint(
 312         &source_reader.reader,
 313         expected_root,
 314         &reopened_storage,
 315         &third_ram,
 316     );
 317     try std.testing.expect(source_reader.claim_checked);
 318     try std.testing.expect(source_reader.claim_observed);
 319     try std.testing.expect(!source_reader.claim_missing);
 320     try reopened.verify();
 321     try std.testing.expectEqualDeep(expected_root, try reopened.root());
 322     try expectExactCheckpointStream(&reopened);
 323     try std.testing.expectEqualSlices(u8, &first_digest, &streamDigest());
 324 }
 325 
 326 test "checkpoint stream rejects bad framing corruption and aliases unpublished" {
 327     const execution = try os.boot.kernel.manifest.parse(real_k0_manifest);
 328     var source_storage = checkpoint.Storage.init();
 329     const source = try captureAt(47, 0xb1, &source_storage, &first_ram);
 330     const expected_root = try source.value.root();
 331 
 332     var short_writer = std.Io.Writer.fixed(
 333         checkpoint_stream[0 .. checkpoint.stream.stream_bytes - 1],
 334     );
 335     try std.testing.expectError(
 336         error.WriteFailed,
 337         checkpoint.stream.encodeDisjoint(&source.value, &short_writer),
 338     );
 339     try encodeCheckpointStream(&source.value);
 340 
 341     var destination_storage = checkpoint.Storage.init();
 342     try expectStreamDecodeFailure(
 343         error.TruncatedStream,
 344         checkpoint_stream[0 .. checkpoint.stream.header_bytes - 1],
 345         expected_root,
 346         &destination_storage,
 347         &second_ram,
 348     );
 349     try expectStreamDecodeFailure(
 350         error.TruncatedStream,
 351         checkpoint_stream[0 .. checkpoint.stream.stream_bytes - 1],
 352         expected_root,
 353         &destination_storage,
 354         &second_ram,
 355     );
 356     try expectStreamReadFailure(
 357         checkpoint.stream.header_bytes / 2,
 358         expected_root,
 359         &destination_storage,
 360         &second_ram,
 361     );
 362     try expectStreamReadFailure(
 363         checkpoint.stream.header_bytes + 8192,
 364         expected_root,
 365         &destination_storage,
 366         &second_ram,
 367     );
 368     try expectStreamReadFailure(
 369         checkpoint.stream.stream_bytes,
 370         expected_root,
 371         &destination_storage,
 372         &second_ram,
 373     );
 374 
 375     checkpoint_stream[checkpoint.stream.stream_bytes] = 0xa5;
 376     try expectStreamDecodeFailure(
 377         error.TrailingData,
 378         &checkpoint_stream,
 379         expected_root,
 380         &destination_storage,
 381         &second_ram,
 382     );
 383 
 384     const header_mutations = [_]struct {
 385         offset: usize,
 386         expected: anyerror,
 387     }{
 388         .{ .offset = 0, .expected = error.BadMagic },
 389         .{ .offset = 8, .expected = error.UnsupportedVersion },
 390         .{ .offset = 10, .expected = error.HeaderBytesMismatch },
 391         .{ .offset = 12, .expected = error.UnsupportedFlags },
 392         .{ .offset = 14, .expected = error.CheckpointFormatMismatch },
 393         .{ .offset = 16, .expected = error.StreamBytesMismatch },
 394         .{ .offset = 24, .expected = error.StreamBytesMismatch },
 395         .{ .offset = 32, .expected = error.PageBytesMismatch },
 396         .{ .offset = 36, .expected = error.AbiVersionMismatch },
 397         .{ .offset = 38, .expected = error.AbiVersionMismatch },
 398         .{ .offset = 40, .expected = error.MetadataShapeMismatch },
 399         .{ .offset = 54, .expected = error.ReservedNonzero },
 400         .{ .offset = 465, .expected = error.ReservedNonzero },
 401         .{ .offset = 572, .expected = error.ReservedNonzero },
 402         .{ .offset = 644, .expected = error.ReservedNonzero },
 403         .{ .offset = 676, .expected = error.ReservedNonzero },
 404         .{ .offset = 708, .expected = error.ReservedNonzero },
 405         .{ .offset = 740, .expected = error.ReservedNonzero },
 406         .{ .offset = 744, .expected = error.ReservedNonzero },
 407     };
 408     for (header_mutations) |mutation| {
 409         checkpoint_stream[mutation.offset] ^= 1;
 410         try expectStreamDecodeFailure(
 411             mutation.expected,
 412             checkpoint_stream[0..checkpoint.stream.stream_bytes],
 413             expected_root,
 414             &destination_storage,
 415             &second_ram,
 416         );
 417         checkpoint_stream[mutation.offset] ^= 1;
 418     }
 419 
 420     var wrong_expected = expected_root;
 421     wrong_expected.digest[0] ^= 1;
 422     try expectStreamDecodeFailure(
 423         error.CheckpointRootMismatch,
 424         checkpoint_stream[0..checkpoint.stream.stream_bytes],
 425         wrong_expected,
 426         &destination_storage,
 427         &second_ram,
 428     );
 429 
 430     checkpoint_stream[128] ^= 1;
 431     try expectStreamDecodeFailure(
 432         error.CheckpointRootMismatch,
 433         checkpoint_stream[0..checkpoint.stream.stream_bytes],
 434         expected_root,
 435         &destination_storage,
 436         &second_ram,
 437     );
 438     checkpoint_stream[128] ^= 1;
 439 
 440     checkpoint_stream[192] ^= 1;
 441     try expectStreamDecodeFailure(
 442         error.CheckpointRootMismatch,
 443         checkpoint_stream[0..checkpoint.stream.stream_bytes],
 444         expected_root,
 445         &destination_storage,
 446         &second_ram,
 447     );
 448     checkpoint_stream[192] ^= 1;
 449 
 450     const mutable = try firstWritableAddress(execution);
 451     checkpoint_stream[checkpoint.stream.header_bytes + mutable] ^= 1;
 452     try expectStreamDecodeFailure(
 453         error.MemoryDigestMismatch,
 454         checkpoint_stream[0..checkpoint.stream.stream_bytes],
 455         expected_root,
 456         &destination_storage,
 457         &second_ram,
 458     );
 459     checkpoint_stream[checkpoint.stream.header_bytes + mutable] ^= 1;
 460 
 461     var valid_reader = std.Io.Reader.fixed(
 462         checkpoint_stream[0..checkpoint.stream.stream_bytes],
 463     );
 464     const reopened = try checkpoint.stream.decodeDisjoint(
 465         &valid_reader,
 466         expected_root,
 467         &destination_storage,
 468         &second_ram,
 469     );
 470     try reopened.verify();
 471 
 472     var aliased_reader = std.Io.Reader.fixed(&third_ram);
 473     var alias_storage = checkpoint.Storage.init();
 474     try std.testing.expectError(
 475         error.SourceAliasesDestination,
 476         checkpoint.stream.decodeDisjoint(
 477             &aliased_reader,
 478             expected_root,
 479             &alias_storage,
 480             &third_ram,
 481         ),
 482     );
 483     var aliased_writer = std.Io.Writer.fixed(&first_ram);
 484     try std.testing.expectError(
 485         error.SinkAliasesCheckpoint,
 486         checkpoint.stream.encodeDisjoint(&source.value, &aliased_writer),
 487     );
 488 }
 489 
 490 test "every publication crash cut exposes only empty or authenticated state" {
 491     var source_storage = checkpoint.Storage.init();
 492     const source = try captureAt(12, 0x81, &source_storage, &first_ram);
 493     const expected = try source.value.root();
 494 
 495     inline for (std.meta.tags(checkpoint_owner.publication_audit.Cut)) |cut| {
 496         var storage = checkpoint.Storage.init();
 497         const outcome = try checkpoint_owner.publication_audit.replay(
 498             &source.value,
 499             &storage,
 500             &second_ram,
 501             cut,
 502         );
 503         if (cut == .published) {
 504             const published = switch (outcome) {
 505                 .published => |value| value,
 506                 .interrupted => return error.TestExpectedPublishedCheckpoint,
 507             };
 508             try std.testing.expectEqualDeep(expected, try published.root());
 509             switch (try checkpoint.recoverAfterCrash(
 510                 &storage,
 511                 &second_ram,
 512                 expected,
 513             )) {
 514                 .published => |recovered| {
 515                     try std.testing.expectEqualDeep(
 516                         expected,
 517                         try recovered.root(),
 518                     );
 519                 },
 520                 .empty => return error.TestExpectedPublishedCheckpoint,
 521             }
 522         } else {
 523             switch (outcome) {
 524                 .interrupted => {},
 525                 .published => return error.TestExpectedInterruptedCheckpoint,
 526             }
 527             try std.testing.expectError(
 528                 error.CheckpointClosed,
 529                 checkpoint.open(&storage, &second_ram, expected),
 530             );
 531             switch (try checkpoint.recoverAfterCrash(
 532                 &storage,
 533                 &second_ram,
 534                 null,
 535             )) {
 536                 .empty => {},
 537                 .published => return error.TestExpectedEmptyCheckpoint,
 538             }
 539             try std.testing.expectError(
 540                 error.CheckpointClosed,
 541                 checkpoint.open(&storage, &second_ram, expected),
 542             );
 543         }
 544     }
 545 }
 546 
 547 test "checkpoint normalization is exact and corruption fails closed" {
 548     var storage = checkpoint.Storage.init();
 549     const captured = try captureAt(13, 0xa1, &storage, &first_ram);
 550     const regions = [_]struct { address: usize, bytes: usize }{
 551         .{ .address = @intCast(layout.boot_frame_address), .bytes = layout.page_bytes },
 552         .{ .address = @intCast(layout.request_ring_address), .bytes = layout.page_bytes },
 553         .{ .address = @intCast(layout.event_ring_address), .bytes = layout.page_bytes },
 554         .{
 555             .address = @intCast(layout.stack_base),
 556             .bytes = @intCast(layout.stack_end - layout.stack_base),
 557         },
 558     };
 559     for (regions) |region| {
 560         try expectZero(first_ram[region.address..][0..region.bytes]);
 561         first_ram[region.address + region.bytes - 1] = 1;
 562         try std.testing.expectError(
 563             error.MemoryNotNormalized,
 564             captured.value.verify(),
 565         );
 566         first_ram[region.address + region.bytes - 1] = 0;
 567         try captured.value.verify();
 568     }
 569 
 570     const preserved: usize = @intCast(layout.event_ring_address + layout.page_bytes);
 571     first_ram[preserved] ^= 1;
 572     try std.testing.expectError(
 573         error.MemoryDigestMismatch,
 574         captured.value.verify(),
 575     );
 576     first_ram[preserved] ^= 1;
 577     try captured.value.verify();
 578 }
 579 
 580 test "immutable checkpoint storage cannot be overwritten" {
 581     var storage = checkpoint.Storage.init();
 582     const captured = try captureAt(17, 0xb1, &storage, &first_ram);
 583     try captured.value.verify();
 584 
 585     const execution = try os.boot.kernel.manifest.parse(real_k0_manifest);
 586     const selected = input(execution, 19, 0xb2);
 587     var live_storage = instance.Storage.init();
 588     var machine = try start(&live_storage, selected);
 589     defer machine.deinit();
 590     _ = try driveToReceipt(&machine, selected.fence);
 591     try std.testing.expectError(
 592         error.CheckpointStorageInUse,
 593         machine.captureCheckpoint(&storage, &second_ram),
 594     );
 595     try std.testing.expectError(
 596         error.CheckpointStorageInUse,
 597         machine.captureCheckpoint(&storage, &first_ram),
 598     );
 599     try captured.value.verify();
 600 }
 601 
 602 test "checkpoint capture rejects every changed launch mapping" {
 603     const execution = try os.boot.kernel.manifest.parse(real_k0_manifest);
 604     const selected = input(execution, 31, 0xe1);
 605     var live_storage = instance.Storage.init();
 606     var machine = try start(&live_storage, selected);
 607     defer machine.deinit();
 608     _ = try driveToReceipt(&machine, selected.fence);
 609     markTranslationActivity(machine.ram);
 610 
 611     var accepted_storage = checkpoint.Storage.init();
 612     const accepted = try machine.captureCheckpoint(&accepted_storage, &first_ram);
 613     try accepted.verify();
 614 
 615     const protection_plan = try core.protection.Plan.init(execution);
 616     const executable = protection_plan.sealedSpans()[0].ram_offset;
 617     const executable_table = (executable - os.boot.kernel.physical_base) /
 618         layout.large_page_bytes;
 619     const executable_index = executable % layout.large_page_bytes / layout.page_bytes;
 620     const corruptions = [_]PageTableCorruption{
 621         .{ .address = layout.pml4_address, .index = 0, .mask = 1 << 1 },
 622         .{ .address = layout.pml4_address, .index = 1, .mask = 1 },
 623         .{ .address = layout.pdpt_address, .index = 0, .mask = 1 << 12 },
 624         .{ .address = layout.page_directory_address, .index = 7, .mask = 1 << 7 },
 625         .{ .address = layout.page_directory_address, .index = 32, .mask = 1 },
 626         .{ .address = layout.low_page_table_address, .index = 1, .mask = 1 },
 627         .{
 628             .address = layout.kernel_page_table_base +
 629                 executable_table * layout.page_bytes,
 630             .index = @intCast(executable_index),
 631             .mask = 1 << 1,
 632         },
 633         .{
 634             .address = layout.kernel_page_table_base +
 635                 executable_table * layout.page_bytes,
 636             .index = @intCast(executable_index),
 637             .mask = 1 << 6,
 638         },
 639     };
 640     var rejected_storage = checkpoint.Storage.init();
 641     for (corruptions) |corruption| {
 642         toggleEntryBits(
 643             machine.ram,
 644             corruption.address,
 645             corruption.index,
 646             corruption.mask,
 647         );
 648         try std.testing.expectError(
 649             error.MemoryNotNormalized,
 650             machine.captureCheckpoint(&rejected_storage, &second_ram),
 651         );
 652         switch (try checkpoint.recoverAfterCrash(
 653             &rejected_storage,
 654             &second_ram,
 655             null,
 656         )) {
 657             .empty => {},
 658             .published => return error.TestExpectedEmptyCheckpoint,
 659         }
 660         toggleEntryBits(
 661             machine.ram,
 662             corruption.address,
 663             corruption.index,
 664             corruption.mask,
 665         );
 666     }
 667 }
 668 
 669 test "checkpoint capture binds every immutable load and preserves writable state" {
 670     const execution = try os.boot.kernel.manifest.parse(real_k0_manifest);
 671     const selected = input(execution, 37, 0xf1);
 672     var live_storage = instance.Storage.init();
 673     var machine = try start(&live_storage, selected);
 674     defer machine.deinit();
 675     _ = try driveToReceipt(&machine, selected.fence);
 676 
 677     var rejected_storage = checkpoint.Storage.init();
 678     var immutable_count: u16 = 0;
 679     var writable_address: ?usize = null;
 680     var index: u16 = 0;
 681     while (index < execution.header.load_count) : (index += 1) {
 682         const load = execution.load(index);
 683         const address: usize = @intCast(
 684             execution.header.facts.physical_base + load.physical_offset,
 685         );
 686         if (load.flags & os.boot.kernel.manifest.load_flag_write != 0) {
 687             if (writable_address == null) writable_address = address;
 688             continue;
 689         }
 690         immutable_count += 1;
 691         machine.ram[address] ^= 1;
 692         try std.testing.expectError(
 693             error.ImmutableImageMismatch,
 694             machine.captureCheckpoint(&rejected_storage, &first_ram),
 695         );
 696         switch (try checkpoint.recoverAfterCrash(
 697             &rejected_storage,
 698             &first_ram,
 699             null,
 700         )) {
 701             .empty => {},
 702             .published => return error.TestExpectedEmptyCheckpoint,
 703         }
 704         machine.ram[address] ^= 1;
 705     }
 706     try std.testing.expect(immutable_count > 0);
 707 
 708     const mutable = writable_address orelse return error.TestExpectedWritableLoad;
 709     machine.ram[mutable] ^= 1;
 710     var accepted_storage = checkpoint.Storage.init();
 711     const accepted = try machine.captureCheckpoint(&accepted_storage, &second_ram);
 712     try accepted.verify();
 713 }
 714 
 715 test "checkpoint root corruption is distinguished from a closed handle" {
 716     var storage = checkpoint.Storage.init();
 717     const captured = try captureAt(41, 0xa3, &storage, &first_ram);
 718     const root_value = try captured.value.root();
 719     const offset = std.mem.indexOf(u8, &storage.bytes, &root_value.digest) orelse
 720         return error.TestExpectedStoredRoot;
 721     storage.bytes[offset] ^= 1;
 722     try std.testing.expectError(
 723         error.CheckpointCorrupt,
 724         captured.value.verify(),
 725     );
 726     storage.bytes[offset] ^= 1;
 727     try captured.value.verify();
 728 }
 729 
 730 test "adjacent checkpoints preserve the prior root and advance logical state" {
 731     const execution = try os.boot.kernel.manifest.parse(real_k0_manifest);
 732     const selected = input(execution, 23, 0xc1);
 733     var live_storage = instance.Storage.init();
 734     var machine = try start(&live_storage, selected);
 735     defer machine.deinit();
 736 
 737     _ = try driveTerminalToReceipt(&machine, selected.fence, 0);
 738     var first_storage = checkpoint.Storage.init();
 739     const first = try machine.captureCheckpoint(&first_storage, &first_ram);
 740     const first_root = try first.root();
 741 
 742     var next = selected.fence;
 743     next.generation += 1;
 744     next.token = @splat(0xc2);
 745     try machine.reactivate(next);
 746     _ = try driveTerminalToReceipt(
 747         &machine,
 748         next,
 749         os.k0.request_bytes.len,
 750     );
 751     var second_storage = checkpoint.Storage.init();
 752     const second = try machine.captureCheckpoint(&second_storage, &second_ram);
 753     const second_root = try second.root();
 754 
 755     try std.testing.expect(!std.meta.eql(first_root, second_root));
 756     try std.testing.expect(!std.meta.eql(first_root.state, second_root.state));
 757     try std.testing.expectEqualSlices(u8, &first_ram, &second_ram);
 758     try std.testing.expectEqualDeep(first_root, try first.root());
 759 }
 760 
 761 test "one authenticated root restores twice under distinct supplied authority" {
 762     const execution = try os.boot.kernel.manifest.parse(real_k0_manifest);
 763     const selected = input(execution, 53, 0xa5);
 764     var source_storage = instance.Storage.init();
 765     var source = try start(&source_storage, selected);
 766     _ = try activate(&source);
 767     const source_basis = try source.admissionBasis();
 768     const source_admission = try admission.prepare(
 769         source_basis,
 770         try admission.terminal(
 771             source_basis.frontiers.terminal_input_offset,
 772             os.k0.request_bytes,
 773         ),
 774     );
 775     const source_turn = try completeTurn(
 776         &source,
 777         source_admission,
 778         @splat(0x81),
 779         selected.fence,
 780     );
 781     var source_checkpoint_storage = checkpoint.Storage.init();
 782     const source_checkpoint = try source.captureCheckpoint(
 783         &source_checkpoint_storage,
 784         &first_ram,
 785     );
 786     const source_root = try source_checkpoint.root();
 787     const source_session = source.session_identity;
 788     source.deinit();
 789 
 790     const first_fence: os.abi.ActivationFence = .{
 791         .world = @splat(0xb1),
 792         .generation = 1,
 793         .token = @splat(0xb2),
 794     };
 795     const second_fence: os.abi.ActivationFence = .{
 796         .world = @splat(0xc1),
 797         .generation = 1,
 798         .token = @splat(0xc2),
 799     };
 800     var first_storage = instance.Storage.init();
 801     var first_branch = try restore(
 802         &first_storage,
 803         &second_ram,
 804         source_checkpoint,
 805         source_root,
 806         first_fence,
 807     );
 808     defer first_branch.deinit();
 809     var second_storage = instance.Storage.init();
 810     var second_branch = try restore(
 811         &second_storage,
 812         &third_ram,
 813         source_checkpoint,
 814         source_root,
 815         second_fence,
 816     );
 817     defer second_branch.deinit();
 818 
 819     try std.testing.expect(first_branch.session_identity != source_session);
 820     try std.testing.expect(second_branch.session_identity != source_session);
 821     try std.testing.expect(
 822         first_branch.session_identity != second_branch.session_identity,
 823     );
 824     try expectRestartFrame(&first_branch, source_turn.receipt, first_fence);
 825     try expectRestartFrame(&second_branch, source_turn.receipt, second_fence);
 826 
 827     const first_activation = try activate(&first_branch);
 828     const second_activation = try activate(&second_branch);
 829     const comparison_fence: os.abi.ActivationFence = .{
 830         .world = @splat(0xd1),
 831         .generation = 7,
 832         .token = @splat(0xd2),
 833     };
 834     try expectEquivalentEvents(
 835         first_activation,
 836         second_activation,
 837         comparison_fence,
 838     );
 839     try std.testing.expectError(
 840         error.DeliveryFenceMismatch,
 841         first_branch.deliverAdmitted(&source_turn.delivery),
 842     );
 843     try std.testing.expectError(
 844         error.DeliveryFenceMismatch,
 845         second_branch.deliverAdmitted(&source_turn.delivery),
 846     );
 847     try std.testing.expectError(
 848         error.InvalidQuiescenceReceipt,
 849         instance.verifyQuiescenceReceipt(source_turn.receipt, first_fence),
 850     );
 851     try std.testing.expectError(
 852         error.InvalidQuiescenceReceipt,
 853         instance.verifyQuiescenceReceipt(source_turn.receipt, second_fence),
 854     );
 855     try std.testing.expectError(
 856         error.StaleActivation,
 857         os.abi.EventRing.push(
 858             layout.eventRing(first_branch.ram),
 859             first_fence,
 860             &source_turn.events.storage[0],
 861         ),
 862     );
 863 
 864     const first_basis = try first_branch.admissionBasis();
 865     const second_basis = try second_branch.admissionBasis();
 866     try std.testing.expectEqualDeep(first_basis, second_basis);
 867     const shared_admission = try admission.prepare(
 868         first_basis,
 869         try admission.terminal(
 870             first_basis.frontiers.terminal_input_offset,
 871             os.k0.request_bytes,
 872         ),
 873     );
 874     const cross_delivery = try admission.bindDelivery(
 875         shared_admission,
 876         @splat(0x91),
 877         second_fence,
 878     );
 879     try std.testing.expectError(
 880         error.DeliveryFenceMismatch,
 881         first_branch.deliverAdmitted(&cross_delivery),
 882     );
 883     const first_turn = try completeTurn(
 884         &first_branch,
 885         shared_admission,
 886         @splat(0x91),
 887         first_fence,
 888     );
 889     const second_turn = try completeTurn(
 890         &second_branch,
 891         shared_admission,
 892         @splat(0x91),
 893         second_fence,
 894     );
 895     try expectEquivalentEvents(
 896         first_turn.events,
 897         second_turn.events,
 898         comparison_fence,
 899     );
 900     try std.testing.expect(!std.mem.eql(
 901         u8,
 902         &first_turn.receipt.fenced_digest,
 903         &second_turn.receipt.fenced_digest,
 904     ));
 905     try std.testing.expectEqualDeep(
 906         first_turn.receipt.basis,
 907         second_turn.receipt.basis,
 908     );
 909     try std.testing.expectEqualDeep(
 910         first_turn.receipt.block_root,
 911         second_turn.receipt.block_root,
 912     );
 913     try std.testing.expectEqual(
 914         first_fence.generation,
 915         first_turn.receipt.boundary.capability_generation,
 916     );
 917     try std.testing.expectEqual(
 918         second_fence.generation,
 919         second_turn.receipt.boundary.capability_generation,
 920     );
 921 
 922     var equal_checkpoint_storage = checkpoint.Storage.init();
 923     const equal_checkpoint = try first_branch.captureCheckpoint(
 924         &equal_checkpoint_storage,
 925         &fixture.ram,
 926     );
 927     const equal_root = try equal_checkpoint.root();
 928     const second_storage_before = storageDigest(&second_storage);
 929     const second_ram_before = ramDigest(second_branch.ram);
 930     const second_receipt_before = try second_branch.quiescenceReceipt();
 931 
 932     var next_first_fence = first_fence;
 933     next_first_fence.generation += 1;
 934     next_first_fence.token = @splat(0xb3);
 935     try first_branch.reactivate(next_first_fence);
 936     _ = try activate(&first_branch);
 937     const divergent_basis = try first_branch.admissionBasis();
 938     const divergent_admission = try admission.prepare(
 939         divergent_basis,
 940         try admission.virtualTime(
 941             divergent_basis.frontiers.virtual_time_tick,
 942             divergent_basis.frontiers.virtual_time_tick + 1,
 943         ),
 944     );
 945     const divergent = try completeTurn(
 946         &first_branch,
 947         divergent_admission,
 948         @splat(0xa1),
 949         next_first_fence,
 950     );
 951     try std.testing.expectEqual(
 952         second_turn.receipt.block_root.generation + 1,
 953         divergent.receipt.block_root.generation,
 954     );
 955     try std.testing.expectEqual(
 956         second_turn.receipt.basis.frontiers.virtual_time_tick + 1,
 957         divergent.receipt.basis.frontiers.virtual_time_tick,
 958     );
 959     const second_storage_after = storageDigest(&second_storage);
 960     const second_ram_after = ramDigest(second_branch.ram);
 961     try std.testing.expectEqualSlices(
 962         u8,
 963         &second_storage_before,
 964         &second_storage_after,
 965     );
 966     try std.testing.expectEqualSlices(u8, &second_ram_before, &second_ram_after);
 967     try std.testing.expectEqualDeep(
 968         second_receipt_before,
 969         try second_branch.quiescenceReceipt(),
 970     );
 971     try source_checkpoint.verify();
 972 
 973     first_branch.deinit();
 974     var second_checkpoint_storage = checkpoint.Storage.init();
 975     const second_checkpoint = try second_branch.captureCheckpoint(
 976         &second_checkpoint_storage,
 977         &second_ram,
 978     );
 979     try std.testing.expectEqualDeep(equal_root, try second_checkpoint.root());
 980     try equal_checkpoint.verify();
 981     try std.testing.expect(!std.meta.eql(source_root, equal_root));
 982 }
 983 
 984 test "authenticated settled prefix restores into branch-private divergent states" {
 985     const execution = try os.boot.kernel.manifest.parse(real_k0_manifest);
 986     const effect_request: admission.EffectRequest = .{
 987         .receipt = .{ .digest = @splat(0x71) },
 988         .correlation = 1,
 989     };
 990     var selected = input(execution, 59, 0xd1);
 991     selected.outstanding_effect = effect_request;
 992     var source_storage = instance.Storage.init();
 993     var source = try start(&source_storage, selected);
 994     var source_closed = false;
 995     defer if (!source_closed) source.deinit();
 996     _ = try activate(&source);
 997     const source_basis = try source.admissionBasis();
 998     try std.testing.expectEqualDeep(
 999         effect_request,
1000         source_basis.outstanding_effect.?,
1001     );
1002     const settled_record = try admission.effectResult(
1003         effect_request.receipt.digest,
1004         effect_request.correlation,
1005         .ok,
1006         @splat(0x72),
1007         "settled-prefix",
1008     );
1009     const settled_admission = try admission.prepare(
1010         source_basis,
1011         settled_record,
1012     );
1013     const source_turn = try completeTurn(
1014         &source,
1015         settled_admission,
1016         @splat(0x73),
1017         selected.fence,
1018     );
1019     try std.testing.expectEqual(
1020         @as(u64, 1),
1021         source_turn.receipt.basis.frontiers.effect,
1022     );
1023     try std.testing.expectEqual(
1024         @as(u64, 1),
1025         source_turn.receipt.boundary.effect_frontier,
1026     );
1027     try std.testing.expect(source_turn.receipt.basis.outstanding_effect == null);
1028 
1029     var source_checkpoint_storage = checkpoint.Storage.init();
1030     const source_checkpoint = try source.captureCheckpoint(
1031         &source_checkpoint_storage,
1032         &first_ram,
1033     );
1034     const source_root = try source_checkpoint.root();
1035     try encodeCheckpointStream(&source_checkpoint);
1036     source.deinit();
1037     source_closed = true;
1038     source_storage = instance.Storage.init();
1039     source_checkpoint_storage = checkpoint.Storage.init();
1040     @memset(&fixture.ram, 0x5a);
1041     @memset(&first_ram, 0xa5);
1042     try std.testing.expect(!source_checkpoint.active());
1043 
1044     var reopened_storage = checkpoint.Storage.init();
1045     var source_reader = std.Io.Reader.fixed(
1046         checkpoint_stream[0..checkpoint.stream.stream_bytes],
1047     );
1048     const reopened_checkpoint = try checkpoint.stream.decodeDisjoint(
1049         &source_reader,
1050         source_root,
1051         &reopened_storage,
1052         &second_ram,
1053     );
1054     try std.testing.expectEqualDeep(source_root, try reopened_checkpoint.root());
1055     const reopened_storage_before = ramDigest(&reopened_storage.bytes);
1056     const reopened_ram_before = ramDigest(&second_ram);
1057 
1058     const first_fence: os.abi.ActivationFence = .{
1059         .world = @splat(0x81),
1060         .generation = 1,
1061         .token = @splat(0x82),
1062     };
1063     const second_fence: os.abi.ActivationFence = .{
1064         .world = @splat(0x91),
1065         .generation = 1,
1066         .token = @splat(0x92),
1067     };
1068     var first_storage = instance.Storage.init();
1069     var first_branch = try restore(
1070         &first_storage,
1071         &first_ram,
1072         reopened_checkpoint,
1073         source_root,
1074         first_fence,
1075     );
1076     var first_closed = false;
1077     defer if (!first_closed) first_branch.deinit();
1078     var second_storage = instance.Storage.init();
1079     var second_branch = try restore(
1080         &second_storage,
1081         &third_ram,
1082         reopened_checkpoint,
1083         source_root,
1084         second_fence,
1085     );
1086     var second_closed = false;
1087     defer if (!second_closed) second_branch.deinit();
1088 
1089     try expectRestartFrame(&first_branch, source_turn.receipt, first_fence);
1090     try expectRestartFrame(&second_branch, source_turn.receipt, second_fence);
1091     const first_activation = try activate(&first_branch);
1092     const second_activation = try activate(&second_branch);
1093     try expectEquivalentEvents(first_activation, second_activation, first_fence);
1094     const first_basis = try first_branch.admissionBasis();
1095     const second_basis = try second_branch.admissionBasis();
1096     try std.testing.expectEqualDeep(source_turn.receipt.basis, first_basis);
1097     try std.testing.expectEqualDeep(first_basis, second_basis);
1098 
1099     const second_storage_before_first = storageDigest(&second_storage);
1100     const second_ram_before_first = ramDigest(second_branch.ram);
1101     const first_admission = try admission.prepare(
1102         first_basis,
1103         try admission.virtualTime(
1104             first_basis.frontiers.virtual_time_tick,
1105             first_basis.frontiers.virtual_time_tick + 1,
1106         ),
1107     );
1108     const first_turn = try completeTurn(
1109         &first_branch,
1110         first_admission,
1111         @splat(0xa1),
1112         first_fence,
1113     );
1114     try std.testing.expectEqualSlices(
1115         u8,
1116         &second_storage_before_first,
1117         &storageDigest(&second_storage),
1118     );
1119     try std.testing.expectEqualSlices(
1120         u8,
1121         &second_ram_before_first,
1122         &ramDigest(second_branch.ram),
1123     );
1124 
1125     const first_storage_before_second = storageDigest(&first_storage);
1126     const first_ram_before_second = ramDigest(first_branch.ram);
1127     const first_receipt_before_second = try first_branch.quiescenceReceipt();
1128     const second_admission = try admission.prepare(
1129         second_basis,
1130         try admission.entropy(
1131             second_basis.frontiers.entropy_generation + 1,
1132             "branch-B",
1133         ),
1134     );
1135     const second_turn = try completeTurn(
1136         &second_branch,
1137         second_admission,
1138         @splat(0xb1),
1139         second_fence,
1140     );
1141     try std.testing.expectEqualSlices(
1142         u8,
1143         &first_storage_before_second,
1144         &storageDigest(&first_storage),
1145     );
1146     try std.testing.expectEqualSlices(
1147         u8,
1148         &first_ram_before_second,
1149         &ramDigest(first_branch.ram),
1150     );
1151     try std.testing.expectEqualDeep(
1152         first_receipt_before_second,
1153         try first_branch.quiescenceReceipt(),
1154     );
1155 
1156     try std.testing.expect(!std.mem.eql(
1157         u8,
1158         &first_turn.receipt.delivery.digest,
1159         &second_turn.receipt.delivery.digest,
1160     ));
1161     try std.testing.expect(!std.mem.eql(
1162         u8,
1163         &first_turn.receipt.admission_receipt.digest,
1164         &second_turn.receipt.admission_receipt.digest,
1165     ));
1166     try std.testing.expectEqualSlices(
1167         u8,
1168         &first_turn.delivery.next_source_root,
1169         &first_turn.receipt.basis.source_root,
1170     );
1171     try std.testing.expectEqualSlices(
1172         u8,
1173         &second_turn.delivery.next_source_root,
1174         &second_turn.receipt.basis.source_root,
1175     );
1176     try std.testing.expect(!std.mem.eql(
1177         u8,
1178         &first_turn.receipt.basis.source_root,
1179         &second_turn.receipt.basis.source_root,
1180     ));
1181     try std.testing.expectEqual(
1182         first_turn.receipt.block_root.generation,
1183         second_turn.receipt.block_root.generation,
1184     );
1185     try std.testing.expect(!std.mem.eql(
1186         u8,
1187         &first_turn.receipt.block_root.digest,
1188         &second_turn.receipt.block_root.digest,
1189     ));
1190     try std.testing.expect(!std.mem.eql(
1191         u8,
1192         &first_turn.receipt.semantic_transcript_digest,
1193         &second_turn.receipt.semantic_transcript_digest,
1194     ));
1195     try std.testing.expectEqual(
1196         @as(u64, 1),
1197         first_turn.receipt.basis.frontiers.effect,
1198     );
1199     try std.testing.expectEqual(
1200         @as(u64, 1),
1201         second_turn.receipt.basis.frontiers.effect,
1202     );
1203     try std.testing.expectEqual(
1204         @as(u64, 1),
1205         first_turn.receipt.boundary.effect_frontier,
1206     );
1207     try std.testing.expectEqual(
1208         @as(u64, 1),
1209         second_turn.receipt.boundary.effect_frontier,
1210     );
1211     try std.testing.expect(first_turn.receipt.basis.outstanding_effect == null);
1212     try std.testing.expect(second_turn.receipt.basis.outstanding_effect == null);
1213 
1214     const source_event = try os.abi.decodeEvent(&source_turn.events.storage[0]);
1215     const second_event = try os.abi.decodeEvent(&second_turn.events.storage[0]);
1216     const first_event_frontiers = try os.abi.EventRing.frontiers(
1217         layout.eventRing(first_branch.ram),
1218         first_fence,
1219     );
1220     const next_event_sequence = first_event_frontiers.produced + 1;
1221     var stale_source_event: os.abi.MessageWire = undefined;
1222     try os.abi.encodeEvent(
1223         selected.fence,
1224         next_event_sequence,
1225         source_event.header.correlation,
1226         source_event.value,
1227         &stale_source_event,
1228     );
1229     var stale_second_event: os.abi.MessageWire = undefined;
1230     try os.abi.encodeEvent(
1231         second_fence,
1232         next_event_sequence,
1233         second_event.header.correlation,
1234         second_event.value,
1235         &stale_second_event,
1236     );
1237     const first_before_stale = ramDigest(first_branch.ram);
1238     try std.testing.expectError(
1239         error.StaleActivation,
1240         os.abi.EventRing.push(
1241             layout.eventRing(first_branch.ram),
1242             first_fence,
1243             &stale_source_event,
1244         ),
1245     );
1246     try std.testing.expectEqualSlices(
1247         u8,
1248         &first_before_stale,
1249         &ramDigest(first_branch.ram),
1250     );
1251     try std.testing.expectError(
1252         error.StaleActivation,
1253         os.abi.EventRing.push(
1254             layout.eventRing(first_branch.ram),
1255             first_fence,
1256             &stale_second_event,
1257         ),
1258     );
1259     try std.testing.expectEqualSlices(
1260         u8,
1261         &first_before_stale,
1262         &ramDigest(first_branch.ram),
1263     );
1264     try std.testing.expectError(
1265         error.EffectRequestInvalid,
1266         admission.prepare(first_turn.receipt.basis, settled_record),
1267     );
1268     try std.testing.expectError(
1269         error.EffectRequestInvalid,
1270         admission.prepare(second_turn.receipt.basis, settled_record),
1271     );
1272 
1273     var first_checkpoint_storage = checkpoint.Storage.init();
1274     const first_checkpoint = try first_branch.captureCheckpoint(
1275         &first_checkpoint_storage,
1276         &fixture.ram,
1277     );
1278     const first_root = try first_checkpoint.root();
1279     first_branch.deinit();
1280     first_closed = true;
1281     try std.testing.expectEqualSlices(
1282         u8,
1283         &reopened_storage_before,
1284         &ramDigest(&reopened_storage.bytes),
1285     );
1286     try std.testing.expectEqualSlices(
1287         u8,
1288         &reopened_ram_before,
1289         &ramDigest(&second_ram),
1290     );
1291     var second_checkpoint_storage = checkpoint.Storage.init();
1292     const second_checkpoint = try second_branch.captureCheckpoint(
1293         &second_checkpoint_storage,
1294         &second_ram,
1295     );
1296     const second_root = try second_checkpoint.root();
1297     try std.testing.expectEqualDeep(first_root.profile, second_root.profile);
1298     try std.testing.expect(!std.meta.eql(first_root.state, second_root.state));
1299     try std.testing.expect(!std.meta.eql(first_root, second_root));
1300     try std.testing.expectEqualSlices(
1301         u8,
1302         &[_]u8{
1303             0xd2, 0x9d, 0x94, 0x1d, 0x6d, 0xfa, 0xf2, 0x11,
1304             0x6b, 0xc6, 0x62, 0xd1, 0xd4, 0x3b, 0xf7, 0x78,
1305             0x60, 0xed, 0x0f, 0xae, 0xca, 0xe9, 0xe3, 0x16,
1306             0xb7, 0xaa, 0x68, 0x06, 0xa2, 0x4d, 0x7e, 0x55,
1307         },
1308         &first_root.digest,
1309     );
1310     try std.testing.expectEqualSlices(
1311         u8,
1312         &[_]u8{
1313             0xa1, 0x09, 0x54, 0xe6, 0xd7, 0x3a, 0xf9, 0x68,
1314             0x1d, 0x0f, 0x22, 0x2d, 0x8a, 0x43, 0x28, 0x16,
1315             0xa1, 0x96, 0xec, 0x05, 0x80, 0xb8, 0xa3, 0xec,
1316             0xfa, 0xf0, 0xc8, 0xf2, 0xe2, 0x1a, 0x48, 0x68,
1317         },
1318         &second_root.digest,
1319     );
1320     second_branch.deinit();
1321     second_closed = true;
1322 }
1323 
1324 test "restore rejects absent corrupt mismatched and aliased components" {
1325     var checkpoint_storage = checkpoint.Storage.init();
1326     const captured = try captureAt(61, 0xe1, &checkpoint_storage, &first_ram);
1327     const expected_root = try captured.value.root();
1328     const supplied_fence: os.abi.ActivationFence = .{
1329         .world = @splat(0xe2),
1330         .generation = 1,
1331         .token = @splat(0xe3),
1332     };
1333     var restore_storage = instance.Storage.init();
1334     var restore_input: instance.RestoreInput = .{
1335         .checkpoint = .{ .durable = &captured.value },
1336         .expected_root = expected_root,
1337         .profile = profile.interpretedContinuationTestV1(),
1338         .execution_manifest = real_k0_manifest,
1339         .fence = supplied_fence,
1340     };
1341     @memset(&second_ram, 0xa5);
1342 
1343     try expectRestoreError(
1344         error.RamBytesMismatch,
1345         instance.Instance.restore(
1346             &restore_storage,
1347             second_ram[0 .. second_ram.len - layout.page_bytes],
1348             restore_input,
1349         ),
1350     );
1351     const storage_in_ram: *instance.Storage = @ptrCast(
1352         @alignCast(second_ram[0..].ptr),
1353     );
1354     try expectRestoreError(
1355         error.StorageAliasesRam,
1356         instance.Instance.restore(storage_in_ram, &second_ram, restore_input),
1357     );
1358     comptime std.debug.assert(real_k0_manifest.len <= instance.storage_bytes);
1359     restore_input.execution_manifest =
1360         restore_storage.bytes[0..real_k0_manifest.len];
1361     try expectRestoreError(
1362         error.ManifestAliasesStorage,
1363         instance.Instance.restore(&restore_storage, &second_ram, restore_input),
1364     );
1365     restore_input.execution_manifest = real_k0_manifest;
1366 
1367     var wrong_root = expected_root;
1368     wrong_root.digest[0] ^= 1;
1369     restore_input.expected_root = wrong_root;
1370     try expectRestoreError(
1371         error.CheckpointRootMismatch,
1372         instance.Instance.restore(&restore_storage, &second_ram, restore_input),
1373     );
1374 
1375     restore_input.expected_root = expected_root;
1376     restore_input.profile = profile.interpretedReconstructV1();
1377     try expectRestoreError(
1378         error.CheckpointContractMismatch,
1379         instance.Instance.restore(&restore_storage, &second_ram, restore_input),
1380     );
1381     restore_input.profile = profile.interpretedContinuationTestV1();
1382     restore_input.fence.generation = 0;
1383     try expectRestoreError(
1384         error.InvalidActivationFence,
1385         instance.Instance.restore(&restore_storage, &second_ram, restore_input),
1386     );
1387     restore_input.fence = supplied_fence;
1388     restore_input.execution_manifest = &.{};
1389     try expectRestoreError(
1390         error.Truncated,
1391         instance.Instance.restore(&restore_storage, &second_ram, restore_input),
1392     );
1393     const fixture_image = fixture.elf();
1394     const fixture_execution = try fixture.execution(&fixture_image);
1395     restore_input.execution_manifest = fixture_execution.bytes();
1396     try expectRestoreError(
1397         error.ExecutionFingerprintMismatch,
1398         instance.Instance.restore(&restore_storage, &second_ram, restore_input),
1399     );
1400 
1401     restore_input.execution_manifest = real_k0_manifest;
1402     const mutable = try firstWritableAddress(
1403         try os.boot.kernel.manifest.parse(real_k0_manifest),
1404     );
1405     first_ram[mutable] ^= 1;
1406     try expectRestoreError(
1407         error.MemoryDigestMismatch,
1408         instance.Instance.restore(&restore_storage, &second_ram, restore_input),
1409     );
1410     first_ram[mutable] ^= 1;
1411     const immutable: usize = @intCast(os.boot.kernel.physical_base);
1412     first_ram[immutable] ^= 1;
1413     try expectRestoreError(
1414         error.ImmutableImageMismatch,
1415         instance.Instance.restore(&restore_storage, &second_ram, restore_input),
1416     );
1417     first_ram[immutable] ^= 1;
1418 
1419     var closed_storage = checkpoint.Storage.init();
1420     const closed_checkpoint: checkpoint.Checkpoint = .{
1421         .storage = &closed_storage,
1422         .ram = &third_ram,
1423         .root_digest = expected_root.digest,
1424     };
1425     restore_input.checkpoint = .{ .durable = &closed_checkpoint };
1426     try expectRestoreError(
1427         error.CheckpointClosed,
1428         instance.Instance.restore(&restore_storage, &second_ram, restore_input),
1429     );
1430 
1431     restore_input.checkpoint = .{ .durable = &captured.value };
1432     restore_input.execution_manifest = second_ram[0..real_k0_manifest.len];
1433     try expectRestoreError(
1434         error.ManifestAliasesRam,
1435         instance.Instance.restore(&restore_storage, &second_ram, restore_input),
1436     );
1437     restore_input.execution_manifest = first_ram[0..real_k0_manifest.len];
1438     try expectRestoreError(
1439         error.ManifestAliasesCheckpoint,
1440         instance.Instance.restore(&restore_storage, &second_ram, restore_input),
1441     );
1442     restore_input.execution_manifest = real_k0_manifest;
1443     try expectRestoreError(
1444         error.RamAliasesCheckpoint,
1445         instance.Instance.restore(&restore_storage, &first_ram, restore_input),
1446     );
1447     comptime std.debug.assert(instance.storage_bytes <= checkpoint.ram_bytes);
1448     const aliased_storage: *instance.Storage = @ptrCast(
1449         @alignCast(first_ram[0..].ptr),
1450     );
1451     try expectRestoreError(
1452         error.StorageAliasesCheckpoint,
1453         instance.Instance.restore(aliased_storage, &second_ram, restore_input),
1454     );
1455     try expectFilled(&second_ram, 0xa5);
1456 
1457     var restored = switch (instance.Instance.restore(
1458         &restore_storage,
1459         &second_ram,
1460         restore_input,
1461     )) {
1462         .ready => |value| value,
1463         .unavailable => return error.UnexpectedBackendUnavailable,
1464         .rejected => |failure| return failure,
1465     };
1466     defer restored.deinit();
1467     const active_storage_before = storageDigest(&restore_storage);
1468     try expectRestoreError(
1469         error.StorageInUse,
1470         instance.Instance.restore(&restore_storage, &third_ram, restore_input),
1471     );
1472     const active_storage_after = storageDigest(&restore_storage);
1473     try std.testing.expectEqualSlices(
1474         u8,
1475         &active_storage_before,
1476         &active_storage_after,
1477     );
1478     try captured.value.verify();
1479 }
1480 
1481 test "checkpoint capture rejects every caller-owned storage alias" {
1482     comptime {
1483         std.debug.assert(checkpoint.storage_bytes <= layout.page_bytes);
1484         std.debug.assert(checkpoint.storage_alignment <= checkpoint.ram_alignment);
1485         std.debug.assert(checkpoint.storage_bytes <= instance.storage_bytes);
1486         std.debug.assert(checkpoint.storage_alignment <= instance.storage_alignment);
1487     }
1488     const execution = try os.boot.kernel.manifest.parse(real_k0_manifest);
1489     const selected = input(execution, 29, 0xd1);
1490     var live_storage = instance.Storage.init();
1491     var machine = try start(&live_storage, selected);
1492     defer machine.deinit();
1493     _ = try driveToReceipt(&machine, selected.fence);
1494 
1495     const memory_storage: *checkpoint.Storage = @ptrCast(@alignCast(first_ram[0..].ptr));
1496     memory_storage.* = checkpoint.Storage.init();
1497     try std.testing.expectError(
1498         error.MemoryAliasesStorage,
1499         machine.captureCheckpoint(memory_storage, &first_ram),
1500     );
1501 
1502     const boot_start: usize = @intCast(layout.boot_frame_address);
1503     const live_ram_storage: *checkpoint.Storage = @ptrCast(
1504         @alignCast(machine.ram[boot_start..].ptr),
1505     );
1506     try std.testing.expectError(
1507         error.StorageAliasesRam,
1508         machine.captureCheckpoint(live_ram_storage, &second_ram),
1509     );
1510 
1511     const owner_storage: *checkpoint.Storage = @ptrCast(
1512         @alignCast(live_storage.bytes[0..].ptr),
1513     );
1514     try std.testing.expectError(
1515         error.StorageAliasesOwner,
1516         machine.captureCheckpoint(owner_storage, &second_ram),
1517     );
1518 }
1519 
1520 fn captureAt(
1521     generation: u64,
1522     token: u8,
1523     storage: *checkpoint.Storage,
1524     destination: []align(checkpoint.ram_alignment) u8,
1525 ) !Captured {
1526     const execution = try os.boot.kernel.manifest.parse(real_k0_manifest);
1527     const selected = input(execution, generation, token);
1528     var live_storage = instance.Storage.init();
1529     var machine = try start(&live_storage, selected);
1530     defer machine.deinit();
1531     const receipt = try driveToReceipt(&machine, selected.fence);
1532     if (generation == 7) markTranslationActivity(machine.ram);
1533     const live_digest = ramDigest(machine.ram);
1534     const value = try machine.captureCheckpoint(storage, destination);
1535     try std.testing.expectEqualSlices(u8, &live_digest, &ramDigest(machine.ram));
1536     return .{ .value = value, .receipt = receipt };
1537 }
1538 
1539 fn markTranslationActivity(ram: []u8) void {
1540     setEntryBits(ram, layout.pml4_address, 0, 1 << 5);
1541     setEntryBits(ram, layout.pdpt_address, 0, 1 << 5);
1542     for (0..layout.identity_large_pages) |index| {
1543         const value = entryValue(ram, layout.page_directory_address, index);
1544         setEntryBits(
1545             ram,
1546             layout.page_directory_address,
1547             index,
1548             (@as(u64, 1) << 5) |
1549                 if (value & (@as(u64, 1) << 7) != 0)
1550                     @as(u64, 1) << 6
1551                 else
1552                     0,
1553         );
1554     }
1555     const entries = layout.page_bytes / @sizeOf(u64);
1556     for (0..entries) |index| {
1557         const physical = @as(u64, index) * layout.page_bytes;
1558         if (!pageTableAddress(physical)) {
1559             setEntryBits(
1560                 ram,
1561                 layout.low_page_table_address,
1562                 index,
1563                 (1 << 5) | (1 << 6),
1564             );
1565         }
1566     }
1567     for (0..layout.kernel_page_table_count) |table_index| {
1568         const address = layout.kernel_page_table_base +
1569             @as(u64, table_index) * layout.page_bytes;
1570         for (0..entries) |index| {
1571             const value = entryValue(ram, address, index);
1572             setEntryBits(
1573                 ram,
1574                 address,
1575                 index,
1576                 (@as(u64, 1) << 5) |
1577                     if (value & (@as(u64, 1) << 1) != 0)
1578                         @as(u64, 1) << 6
1579                     else
1580                         0,
1581             );
1582         }
1583     }
1584 }
1585 
1586 fn pageTableAddress(address: u64) bool {
1587     for (layout.page_table_addresses) |candidate| {
1588         if (address == candidate) return true;
1589     }
1590     return false;
1591 }
1592 
1593 fn setEntryBits(ram: []u8, address: u64, index: usize, mask: u64) void {
1594     const offset: usize = @intCast(address + index * @sizeOf(u64));
1595     std.mem.writeInt(
1596         u64,
1597         ram[offset..][0..@sizeOf(u64)],
1598         entryValue(ram, address, index) | mask,
1599         .little,
1600     );
1601 }
1602 
1603 fn entryValue(ram: []const u8, address: u64, index: usize) u64 {
1604     const offset: usize = @intCast(address + index * @sizeOf(u64));
1605     return std.mem.readInt(u64, ram[offset..][0..@sizeOf(u64)], .little);
1606 }
1607 
1608 fn toggleEntryBits(ram: []u8, address: u64, index: usize, mask: u64) void {
1609     const offset: usize = @intCast(address + index * @sizeOf(u64));
1610     const value = std.mem.readInt(u64, ram[offset..][0..@sizeOf(u64)], .little);
1611     std.mem.writeInt(u64, ram[offset..][0..@sizeOf(u64)], value ^ mask, .little);
1612 }
1613 
1614 fn ramDigest(ram: []const u8) os.abi.Digest {
1615     var digest: os.abi.Digest = undefined;
1616     std.crypto.hash.sha2.Sha256.hash(ram, &digest, .{});
1617     return digest;
1618 }
1619 
1620 fn driveToReceipt(
1621     machine: *instance.Instance,
1622     fence: os.abi.ActivationFence,
1623 ) !instance.QuiescenceReceipt {
1624     return driveTerminalToReceipt(machine, fence, 0);
1625 }
1626 
1627 fn activate(machine: *instance.Instance) !instance.EventBatch {
1628     const ready = try machine.run();
1629     try std.testing.expectEqual(
1630         os.abi.channel.DoorbellCode.ready,
1631         ready.doorbell.code,
1632     );
1633     var batch: instance.EventBatch = undefined;
1634     try machine.takeEvents(&batch);
1635     try std.testing.expectEqual(
1636         @as(usize, os.k0.events_per_activation),
1637         batch.frames().len,
1638     );
1639     return batch;
1640 }
1641 
1642 fn completeTurn(
1643     machine: *instance.Instance,
1644     admitted: admission.Admission,
1645     next_source_root: os.abi.Digest,
1646     fence: os.abi.ActivationFence,
1647 ) !Turn {
1648     const delivery = try admission.bindDelivery(
1649         admitted,
1650         next_source_root,
1651         fence,
1652     );
1653     try machine.deliverAdmitted(&delivery);
1654     const quiescent = try machine.run();
1655     try std.testing.expectEqual(
1656         os.abi.channel.DoorbellCode.quiescent,
1657         quiescent.doorbell.code,
1658     );
1659     var events: instance.EventBatch = undefined;
1660     try machine.takeEvents(&events);
1661     try machine.acknowledge(delivery.receipt);
1662     return .{
1663         .delivery = delivery,
1664         .events = events,
1665         .receipt = try machine.quiescenceReceipt(),
1666     };
1667 }
1668 
1669 fn restore(
1670     storage: *instance.Storage,
1671     ram: []align(instance.ram_alignment) u8,
1672     source: checkpoint.Checkpoint,
1673     expected_root: checkpoint.Root,
1674     fence: os.abi.ActivationFence,
1675 ) !instance.Instance {
1676     return switch (instance.Instance.restore(storage, ram, .{
1677         .checkpoint = .{ .durable = &source },
1678         .expected_root = expected_root,
1679         .profile = profile.interpretedContinuationTestV1(),
1680         .execution_manifest = real_k0_manifest,
1681         .fence = fence,
1682     })) {
1683         .ready => |value| value,
1684         .unavailable => error.UnexpectedBackendUnavailable,
1685         .rejected => |failure| failure,
1686     };
1687 }
1688 
1689 fn expectRestartFrame(
1690     machine: *const instance.Instance,
1691     receipt: instance.QuiescenceReceipt,
1692     fence: os.abi.ActivationFence,
1693 ) !void {
1694     const boot_start: usize = @intCast(layout.boot_frame_address);
1695     const wire: *const os.abi.BootWire = @ptrCast(
1696         machine.ram[boot_start..][0..os.abi.boot.frame_bytes].ptr,
1697     );
1698     const frame = try os.abi.decodeBootFrame(wire);
1699     try std.testing.expectEqualDeep(fence, frame.fence);
1700     try std.testing.expectEqual(
1701         @as(u32, @intCast(receipt.block_root.generation)),
1702         frame.restart.root_generation,
1703     );
1704     try std.testing.expectEqual(receipt.k0.counter, frame.restart.counter);
1705     try std.testing.expectEqual(
1706         receipt.boundary.semantic_frontier,
1707         frame.restart.semantic_frontier,
1708     );
1709     try std.testing.expectEqual(
1710         receipt.basis.frontiers.input,
1711         frame.input_frontier,
1712     );
1713     try std.testing.expectEqual(
1714         receipt.boundary.terminal_offset,
1715         frame.terminal_offset,
1716     );
1717 }
1718 
1719 fn expectEquivalentEvents(
1720     first: instance.EventBatch,
1721     second: instance.EventBatch,
1722     fence: os.abi.ActivationFence,
1723 ) !void {
1724     var normalized_first: instance.EventBatch = undefined;
1725     var normalized_second: instance.EventBatch = undefined;
1726     try normalizeBatch(first, fence, &normalized_first);
1727     try normalizeBatch(second, fence, &normalized_second);
1728     try std.testing.expectEqualDeep(normalized_first, normalized_second);
1729 }
1730 
1731 fn normalizeBatch(
1732     source: instance.EventBatch,
1733     fence: os.abi.ActivationFence,
1734     output: *instance.EventBatch,
1735 ) !void {
1736     var normalized: instance.EventBatch = .{
1737         .count = source.count,
1738         .storage = @splat(@splat(0)),
1739     };
1740     for (source.frames(), 0..) |*frame, index| {
1741         const decoded = try os.abi.decodeEvent(frame);
1742         var value = decoded.value;
1743         if (std.meta.activeTag(value) == .quiescent) {
1744             value.quiescent.capability_generation = fence.generation;
1745         }
1746         try os.abi.encodeEvent(
1747             fence,
1748             decoded.header.sequence,
1749             decoded.header.correlation,
1750             value,
1751             &normalized.storage[index],
1752         );
1753     }
1754     output.* = normalized;
1755 }
1756 
1757 fn encodeCheckpointStream(value: *const checkpoint.Checkpoint) !void {
1758     var writer = std.Io.Writer.fixed(
1759         checkpoint_stream[0..checkpoint.stream.stream_bytes],
1760     );
1761     try checkpoint.stream.encodeDisjoint(value, &writer);
1762     try std.testing.expectEqual(checkpoint.stream.stream_bytes, writer.end);
1763 }
1764 
1765 fn expectExactCheckpointStream(value: *const checkpoint.Checkpoint) !void {
1766     var comparing = ComparingWriter.init(
1767         checkpoint_stream[0..checkpoint.stream.stream_bytes],
1768         4093,
1769     );
1770     comparing.attach();
1771     try checkpoint.stream.encodeDisjoint(value, &comparing.writer);
1772     try std.testing.expect(!comparing.mismatch);
1773     try std.testing.expectEqual(
1774         checkpoint.stream.stream_bytes,
1775         comparing.offset,
1776     );
1777 }
1778 
1779 fn streamDigest() os.abi.Digest {
1780     return ramDigest(checkpoint_stream[0..checkpoint.stream.stream_bytes]);
1781 }
1782 
1783 fn expectStreamDecodeFailure(
1784     expected: anyerror,
1785     bytes: []const u8,
1786     expected_root: checkpoint.Root,
1787     storage: *checkpoint.Storage,
1788     ram: []align(checkpoint.ram_alignment) u8,
1789 ) !void {
1790     var reader = std.Io.Reader.fixed(bytes);
1791     try std.testing.expectError(
1792         expected,
1793         checkpoint.stream.decodeDisjoint(
1794             &reader,
1795             expected_root,
1796             storage,
1797             ram,
1798         ),
1799     );
1800     switch (try checkpoint.recoverAfterCrash(storage, ram, null)) {
1801         .empty => {},
1802         .published => return error.TestExpectedEmptyCheckpoint,
1803     }
1804 }
1805 
1806 fn expectStreamReadFailure(
1807     failure_offset: usize,
1808     expected_root: checkpoint.Root,
1809     storage: *checkpoint.Storage,
1810     ram: []align(checkpoint.ram_alignment) u8,
1811 ) !void {
1812     var reader = FragmentedReader.init(
1813         checkpoint_stream[0..checkpoint.stream.stream_bytes],
1814         4093,
1815     );
1816     reader.failure_offset = failure_offset;
1817     reader.attachUnbuffered();
1818     try std.testing.expectError(
1819         error.ReadFailed,
1820         checkpoint.stream.decodeDisjoint(
1821             &reader.reader,
1822             expected_root,
1823             storage,
1824             ram,
1825         ),
1826     );
1827     switch (try checkpoint.recoverAfterCrash(storage, ram, null)) {
1828         .empty => {},
1829         .published => return error.TestExpectedEmptyCheckpoint,
1830     }
1831 }
1832 
1833 fn storageDigest(storage: *const instance.Storage) os.abi.Digest {
1834     var digest: os.abi.Digest = undefined;
1835     std.crypto.hash.sha2.Sha256.hash(&storage.bytes, &digest, .{});
1836     return digest;
1837 }
1838 
1839 fn expectRestoreError(
1840     expected: anyerror,
1841     result: instance.RestoreResult,
1842 ) !void {
1843     switch (result) {
1844         .ready => |value| {
1845             var restored = value;
1846             restored.deinit();
1847             return error.TestExpectedRestoreRejection;
1848         },
1849         .unavailable => return error.TestExpectedRestoreRejection,
1850         .rejected => |actual| try std.testing.expectEqual(expected, actual),
1851     }
1852 }
1853 
1854 fn firstWritableAddress(execution: os.boot.kernel.manifest.View) !usize {
1855     var index: u16 = 0;
1856     while (index < execution.header.load_count) : (index += 1) {
1857         const load = execution.load(index);
1858         if (load.flags & os.boot.kernel.manifest.load_flag_write == 0) continue;
1859         return @intCast(
1860             execution.header.facts.physical_base + load.physical_offset,
1861         );
1862     }
1863     return error.TestExpectedWritableLoad;
1864 }
1865 
1866 fn expectFilled(bytes: []const u8, expected: u8) !void {
1867     try std.testing.expect(std.mem.allEqual(u8, bytes, expected));
1868 }
1869 
1870 fn driveTerminalToReceipt(
1871     machine: *instance.Instance,
1872     fence: os.abi.ActivationFence,
1873     offset: u64,
1874 ) !instance.QuiescenceReceipt {
1875     const ready = try machine.run();
1876     try std.testing.expectEqual(
1877         os.abi.channel.DoorbellCode.ready,
1878         ready.doorbell.code,
1879     );
1880     var batch: instance.EventBatch = undefined;
1881     try machine.takeEvents(&batch);
1882     const admitted = try admission.prepare(
1883         try machine.admissionBasis(),
1884         try admission.terminal(offset, os.k0.request_bytes),
1885     );
1886     const delivery = try admission.bindDelivery(admitted, @splat(0x88), fence);
1887     try machine.deliverAdmitted(&delivery);
1888     const quiescent = try machine.run();
1889     try std.testing.expectEqual(
1890         os.abi.channel.DoorbellCode.quiescent,
1891         quiescent.doorbell.code,
1892     );
1893     try machine.takeEvents(&batch);
1894     try machine.acknowledge(delivery.receipt);
1895     return machine.quiescenceReceipt();
1896 }
1897 
1898 fn start(
1899     storage: *instance.Storage,
1900     selected: instance.Input,
1901 ) !instance.Instance {
1902     return switch (instance.Instance.init(storage, &fixture.ram, selected)) {
1903         .ready => |value| value,
1904         .unavailable => error.UnexpectedBackendUnavailable,
1905         .rejected => |failure| failure,
1906     };
1907 }
1908 
1909 fn input(
1910     execution: os.boot.kernel.manifest.View,
1911     generation: u64,
1912     token: u8,
1913 ) instance.Input {
1914     return .{
1915         .profile = profile.interpretedContinuationTestV1(),
1916         .elf = real_k0_elf,
1917         .execution_manifest = real_k0_manifest,
1918         .expected_execution_fingerprint = execution.header.fingerprint,
1919         .fence = .{
1920             .world = @splat(0x44),
1921             .generation = generation,
1922             .token = @splat(token),
1923         },
1924         .initial_time_tick = 7,
1925         .entropy_generation = 1,
1926         .terminal_offset = 0,
1927         .effect_frontier = 0,
1928         .block_root = @splat(0x33),
1929         .source_root = @splat(0x77),
1930         .input_frontier = 0,
1931         .terminal_input_offset = 0,
1932         .outstanding_effect = null,
1933     };
1934 }
1935 
1936 fn expectZero(bytes: []const u8) !void {
1937     for (bytes) |byte| try std.testing.expectEqual(@as(u8, 0), byte);
1938 }