tiny.machine.profile.determinism
Defined in profile.
API (24)
Actions
Public operations.
Types and contracts
Public types and contracts.
Assumption: Assumptions are the dependencies a control rests on and takes on trust, listed so a reader sees what the package trusts without a check.AuditErrorCategory: The eleven families a divergence source can belong to are categories, so a reader sees which part of the machine a source comes from: CPU instructions, CPUID features, scheduler choices, interrupts, devices, the clock, entropy, packets, host services, the test driver, and external results.ClaimClaimAssumptionClaimKindClaimWitnessClaims: The four determinism claims one profile makes, one at each of four levels (semantic replay, whole-system replay on one backend, equivalence across hosts, and equivalence down to the instruction).Control: A control determines whether a witness enforces a source or the source stands as an assumption, so a reader opens the value to see whether a source is held by a mechanism or by trust.ControlKindEntry: One row of the inventory names a source with its category and its version, giving the control that holds under the portable x86-64 interpreter, or reference backend, beside the control that holds under KVM so a reader sees how that source is held on each backend.Identity: What identifies one inventory is its schema, how many entries it holds, and its digest, so a caller compares this value to know whether two profiles were built against the same inventory.SchemaSource: The places where two runs of the same program could differ that the package takes responsibility for are divergence sources, so a reader checks a source against this list to see whether the package has accounted for it.Witness: The named, versioned mechanisms that hold a divergence source fixed are witnesses, so a reader follows a name to the mechanism.
Values and defaults
Public values and defaults.
entries: The complete source inventory in canonical order, provided so a reader walks this to audit the whole scope of the determinism promise in one place.inventory_identitykvm_continuation_claimskvm_reconstruct_claimsportable_continuation_claimsportable_reconstruct_claimsprofile_sources
Source
Source: lib/machine/src/profile/determinism.zig
zig
const std = @import("std");const Sha256 = std.crypto.hash.sha2.Sha256;/// The eleven families a divergence source can belong to are categories, so a reader/// sees which part of the machine a source comes from: CPU instructions, CPUID features,/// scheduler choices, interrupts, devices, the clock, entropy, packets, host services,/// the test driver, and external results./// Each inventory entry records its source's category.pub const Category = enum(u8) { cpu_instruction = 1, cpuid_feature = 2, scheduler_choice = 3, interrupt = 4, device = 5, clock = 6, entropy = 7, packet = 8, host_service = 9, test_driver = 10, external_result = 11,};/// The places where two runs of the same program could differ that the package takes/// responsibility for are divergence sources, so a reader checks a source against/// this list to see whether the package has accounted for it./// The list holds 42 sources, and the inventory carries exactly one entry per source/// in the same order.pub const Source = enum(u16) { backend_selection = 1, backend_availability = 2, executable_bytes = 3, instruction_forms = 4, instruction_flags = 5, initial_cpu_state = 6, backend_instruction_result = 7, cpuid_vendor = 8, cpuid_signature = 9, cpuid_page_size_extension = 10, cpuid_physical_address_extension = 11, cpuid_conditional_move = 12, cpuid_execute_disable = 13, cpuid_long_mode = 14, cpuid_address_widths = 15, cpuid_leaf_range = 16, guest_schedule = 17, host_run_stutter = 18, guest_interrupt = 19, host_signal_interrupt = 20, channel_device = 21, doorbell_exit = 22, unmodeled_device_exit = 23, cpu_clock_instruction = 24, cpu_entropy_instruction = 25, checkpoint_memory = 26, checkpoint_source = 27, terminal_input = 28, virtual_time = 29, entropy_input = 30, packet_payload = 31, packet_delivery = 32, packet_fault = 33, host_service_result = 34, effect_result = 35, fault_choice = 36, capacity_fault = 37, machine_crash = 38, process_crash = 39, activation_fence = 40, turn_selection = 41, replay_source = 42,};/// The named, versioned mechanisms that hold a divergence source fixed are witnesses,/// so a reader follows a name to the mechanism./// Each name carries its own version, so a strengthened mechanism shows up as a/// new value.pub const Witness = enum(u16) { backend_selection_v1 = 1, backend_availability_v1 = 2, execution_manifest_v1 = 3, instruction_policy_v2 = 4, instruction_flags_v2 = 5, initial_cpu_state_v1 = 6, portable_instruction_result_v1 = 7, cpuid_model_v1 = 8, cooperative_schedule_v2 = 9, portable_no_stutter_v1 = 10, guest_interrupt_exclusion_v1 = 11, portable_no_host_signal_v1 = 12, channel_device_v1 = 13, doorbell_completion_v1 = 14, unmodeled_device_rejection_v1 = 15, clock_instruction_rejection_v1 = 16, entropy_instruction_rejection_v1 = 17, checkpoint_memory_v1 = 18, checkpoint_stream_v1 = 19, terminal_admission_v1 = 20, virtual_time_admission_v1 = 21, entropy_admission_v1 = 22, packet_payload_v3 = 23, packet_delivery_v3 = 24, packet_fault_v1 = 25, service_result_v1 = 26, effect_result_v1 = 27, fault_decision_v1 = 28, capacity_fault_v1 = 29, machine_crash_v1 = 30, activation_fence_v1 = 31, world_turn_v1 = 32, transition_replay_v1 = 33,};/// Assumptions are the dependencies a control rests on and takes on trust, listed/// so a reader sees what the package trusts without a check./// Three assumptions exist today: two concern the Linux kernel interface for running/// a virtual machine on host hardware, KVM, covering instruction equivalence under/// it and its stutter budget, and the third is the process-crash provider.pub const Assumption = enum(u16) { kvm_instruction_equivalence_v1 = 1, kvm_stutter_budget_v1 = 2, process_crash_provider_v1 = 3,};pub const ControlKind = enum(u8) { enforced = 1, assumed = 2,};/// A control determines whether a witness enforces a source or the source stands/// as an assumption, so a reader opens the value to see whether a source is held/// by a mechanism or by trust.pub const Control = union(ControlKind) { enforced: Witness, assumed: Assumption,};/// One row of the inventory names a source with its category and its version, giving/// the control that holds under the portable x86-64 interpreter, or reference backend,/// beside the control that holds under KVM so a reader sees how that source is held/// on each backend./// The two control fields are separate, so a source enforced by the interpreter/// and assumed under KVM records both at once.pub const Entry = struct { source: Source, category: Category, version: u16, reference: Control, kvm: Control,};pub const ClaimWitness = enum(u16) { portable_semantics_v1 = 1, portable_world_replay_v1 = 2,};pub const ClaimAssumption = enum(u16) { kvm_semantics_v1 = 1, reconstruct_whole_system_v1 = 2, kvm_whole_system_v1 = 3, cross_host_equivalence_v1 = 4, instruction_exact_equivalence_v1 = 5,};pub const ClaimKind = enum(u8) { enforced = 1, assumed = 2,};pub const Claim = union(ClaimKind) { enforced: ClaimWitness, assumed: ClaimAssumption,};/// The four determinism claims one profile makes, one at each of four levels (semantic/// replay, whole-system replay on one backend, equivalence across hosts, and equivalence/// down to the instruction)./// A caller reads them to learn what the profile promises and on what evidence./// Each claim either carries a claim witness that enforces it or stands as an assumption.pub const Claims = struct { semantic: Claim, same_backend_whole_system: Claim, cross_host: Claim, instruction_exact: Claim,};pub const Schema = enum(u16) { whole_system_v1 = 1,};/// What identifies one inventory is its schema, how many entries it holds, and its/// digest, so a caller compares this value to know whether two profiles were built/// against the same inventory./// Every contract embeds this identity, so a change to the inventory changes the/// identity of the shared execution rules, which is the contract fingerprint./// The digest is taken over every entry in order, covering each source, category,/// version, and both controls.pub const Identity = struct { schema: Schema, entry_count: u16, digest: [Sha256.digest_length]u8,};pub const AuditError = error{ InventoryIdentityMismatch, SurfaceCountMismatch, SurfaceOrderMismatch,};pub const profile_sources = [_]Source{ .backend_selection, .backend_availability,};/// The complete source inventory in canonical order, provided so a reader walks/// this to audit the whole scope of the determinism promise in one place./// A compile-time check enforces that the order matches the source enum one for/// one.pub const entries = [_]Entry{ same(.backend_selection, .test_driver, 1, .backend_selection_v1), same(.backend_availability, .external_result, 1, .backend_availability_v1), same(.executable_bytes, .cpu_instruction, 1, .execution_manifest_v1), same(.instruction_forms, .cpu_instruction, 2, .instruction_policy_v2), same(.instruction_flags, .cpu_instruction, 2, .instruction_flags_v2), same(.initial_cpu_state, .cpu_instruction, 1, .initial_cpu_state_v1), split( .backend_instruction_result, .cpu_instruction, 1, .portable_instruction_result_v1, .kvm_instruction_equivalence_v1, ), same(.cpuid_vendor, .cpuid_feature, 1, .cpuid_model_v1), same(.cpuid_signature, .cpuid_feature, 1, .cpuid_model_v1), same(.cpuid_page_size_extension, .cpuid_feature, 1, .cpuid_model_v1), same( .cpuid_physical_address_extension, .cpuid_feature, 1, .cpuid_model_v1, ), same(.cpuid_conditional_move, .cpuid_feature, 1, .cpuid_model_v1), same(.cpuid_execute_disable, .cpuid_feature, 1, .cpuid_model_v1), same(.cpuid_long_mode, .cpuid_feature, 1, .cpuid_model_v1), same(.cpuid_address_widths, .cpuid_feature, 1, .cpuid_model_v1), same(.cpuid_leaf_range, .cpuid_feature, 1, .cpuid_model_v1), same(.guest_schedule, .scheduler_choice, 2, .cooperative_schedule_v2), split( .host_run_stutter, .scheduler_choice, 1, .portable_no_stutter_v1, .kvm_stutter_budget_v1, ), same(.guest_interrupt, .interrupt, 1, .guest_interrupt_exclusion_v1), split( .host_signal_interrupt, .interrupt, 1, .portable_no_host_signal_v1, .kvm_stutter_budget_v1, ), same(.channel_device, .device, 1, .channel_device_v1), same(.doorbell_exit, .device, 1, .doorbell_completion_v1), same(.unmodeled_device_exit, .device, 1, .unmodeled_device_rejection_v1), same(.cpu_clock_instruction, .clock, 1, .clock_instruction_rejection_v1), same(.cpu_entropy_instruction, .entropy, 1, .entropy_instruction_rejection_v1), same(.checkpoint_memory, .external_result, 1, .checkpoint_memory_v1), same(.checkpoint_source, .external_result, 1, .checkpoint_stream_v1), same(.terminal_input, .test_driver, 1, .terminal_admission_v1), same(.virtual_time, .clock, 1, .virtual_time_admission_v1), same(.entropy_input, .entropy, 1, .entropy_admission_v1), same(.packet_payload, .packet, 3, .packet_payload_v3), same(.packet_delivery, .packet, 3, .packet_delivery_v3), same(.packet_fault, .packet, 1, .packet_fault_v1), same(.host_service_result, .host_service, 1, .service_result_v1), same(.effect_result, .external_result, 1, .effect_result_v1), same(.fault_choice, .test_driver, 1, .fault_decision_v1), same(.capacity_fault, .test_driver, 1, .capacity_fault_v1), same(.machine_crash, .test_driver, 1, .machine_crash_v1), assumed(.process_crash, .host_service, 1, .process_crash_provider_v1), same(.activation_fence, .test_driver, 1, .activation_fence_v1), same(.turn_selection, .test_driver, 1, .world_turn_v1), same(.replay_source, .external_result, 1, .transition_replay_v1),};pub const inventory_identity: Identity = .{ .schema = .whole_system_v1, .entry_count = @intCast(entries.len), .digest = inventoryDigest(),};pub const portable_reconstruct_claims: Claims = .{ .semantic = .{ .enforced = .portable_semantics_v1 }, .same_backend_whole_system = .{ .assumed = .reconstruct_whole_system_v1 }, .cross_host = .{ .assumed = .cross_host_equivalence_v1 }, .instruction_exact = .{ .assumed = .instruction_exact_equivalence_v1 },};pub const portable_continuation_claims: Claims = .{ .semantic = .{ .enforced = .portable_semantics_v1 }, .same_backend_whole_system = .{ .enforced = .portable_world_replay_v1 }, .cross_host = .{ .assumed = .cross_host_equivalence_v1 }, .instruction_exact = .{ .assumed = .instruction_exact_equivalence_v1 },};pub const kvm_reconstruct_claims: Claims = .{ .semantic = .{ .assumed = .kvm_semantics_v1 }, .same_backend_whole_system = .{ .assumed = .reconstruct_whole_system_v1 }, .cross_host = .{ .assumed = .cross_host_equivalence_v1 }, .instruction_exact = .{ .assumed = .instruction_exact_equivalence_v1 },};pub const kvm_continuation_claims: Claims = .{ .semantic = .{ .assumed = .kvm_semantics_v1 }, .same_backend_whole_system = .{ .assumed = .kvm_whole_system_v1 }, .cross_host = .{ .assumed = .cross_host_equivalence_v1 }, .instruction_exact = .{ .assumed = .instruction_exact_equivalence_v1 },};pub fn entry(source: Source) *const Entry { const index = @backingInt(source) - 1; std.debug.assert(index < entries.len); std.debug.assert(entries[index].source == source); return &entries[index];}pub fn audit(identity: Identity, surface: []const Source) AuditError!void { if (!std.meta.eql(identity, inventory_identity)) { return error.InventoryIdentityMismatch; } if (surface.len != entries.len) return error.SurfaceCountMismatch; for (surface, entries) |source, declared| { if (source != declared.source) return error.SurfaceOrderMismatch; }}fn same( source: Source, category: Category, version: u16, witness: Witness,) Entry { return .{ .source = source, .category = category, .version = version, .reference = .{ .enforced = witness }, .kvm = .{ .enforced = witness }, };}fn split( source: Source, category: Category, version: u16, reference: Witness, kvm: Assumption,) Entry { return .{ .source = source, .category = category, .version = version, .reference = .{ .enforced = reference }, .kvm = .{ .assumed = kvm }, };}fn assumed( source: Source, category: Category, version: u16, assumption: Assumption,) Entry { return .{ .source = source, .category = category, .version = version, .reference = .{ .assumed = assumption }, .kvm = .{ .assumed = assumption }, };}fn inventoryDigest() [Sha256.digest_length]u8 { @setEvalBranchQuota(100_000); var hasher = Sha256.init(.{}); hasher.update("tiny.machine-determinism-inventory/v1"); for (entries) |declared| { var encoded: [11]u8 = @splat(0); std.mem.writeInt(u16, encoded[0..2], @backingInt(declared.source), .little); encoded[2] = @backingInt(declared.category); std.mem.writeInt(u16, encoded[3..5], declared.version, .little); encodeControl(declared.reference, encoded[5..8]); encodeControl(declared.kvm, encoded[8..11]); hasher.update(&encoded); } var digest: [Sha256.digest_length]u8 = undefined; hasher.final(&digest); return digest;}fn encodeControl(control: Control, output: *[3]u8) void { switch (control) { .enforced => |witness| { output[0] = 1; std.mem.writeInt(u16, output[1..3], @backingInt(witness), .little); }, .assumed => |assumption| { output[0] = 2; std.mem.writeInt(u16, output[1..3], @backingInt(assumption), .little); }, }}comptime { const sources = std.meta.tags(Source); std.debug.assert(entries.len == sources.len); std.debug.assert(entries.len <= std.math.maxInt(u16)); for (entries, sources) |declared, source| { std.debug.assert(declared.source == source); std.debug.assert(declared.version > 0); }}Source: lib/machine/src/profile/root.zig:47
zig
pub const determinism = @import("determinism.zig");Complete caller list for profile.determinism.entry
7 direct callers.
lib.machine.src.explore.capsule.owner.validateOrigin[function] — private source atlib/machine/src/explore/capsule/owner.zig:411in nearest public ownerlib.machine.src.explore.capsule.ownerlib.machine.src.explore.distributed.test.expectOrigin[function] — private source atlib/machine/src/explore/distributed/test.zig:274in nearest public ownerlib.machine.src.explore.distributed.testtiny.machine.explore.origin[function] atlib/machine/src/explore/model.zig:91lib.machine.src.explore.query.history.validateOrigin[function] — private source atlib/machine/src/explore/query/history.zig:525in nearest public ownerlib.machine.src.explore.query.historylib.machine.src.explore.test.expectOrigin[function] — private source atlib/machine/src/explore/test.zig:426in nearest public ownerlib.machine.src.explore.testlib.machine.src.profile.test.test_determinism_inventory_versions_every_source_and_declares_assumptions[function] — test source atlib/machine/src/profile/test.zig:76in nearest public ownerlib.machine.src.profile.testlib.machine.src.properties.generator.Replay.property[function] — private source atlib/machine/src/properties/generator.zig:9in nearest public ownerlib.machine.src.properties.generator
Audit
| Definitions | 25 |
|---|---|
| Public names | 43 |
| Members | 120 |
| Version | 26.7.0 |
| Revision | daab053ee433 |