S545 · SOURCE-BOUND GATE EVIDENCE
S545 · R1 reachable-producer candidate freeze ve pre-arm sözleşmesi
tam S545 implementation modülü → Operations --test hedefi ile bağlı tam focused test → ayrı Operations kaydı Bu sayfa yalnız S545 kapısına aittir; komşu kapıların kaynakları bu kabulün içine katılmaz.
S545Focused kod testiOperations id exactsource SHA exacttest target exact
operation: g8l-s545-r1-reachable-producer-candidate-freeze-prearm-contract
uygulama/model · focused test · Operations · 3 exact excerpt
sequence-bound=true · implementation-bound=true
01 · Yürütme / doğrulama kodu
Kapının gerçek repository sözleşmesi
tam dosyaL1–L1043
kernel/src/g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s545_r1_reachable_producer_candidate_freeze_prearm_contract.rs::S545 r1 reachable producer candidate freeze prearm contract implementation
//! S545 models the host-only freeze of the first RPi5 candidate that contains
//! the S544 reachable CPU1 readiness producer hook, and pins the pre-arm
//! contract that a later S546 physical run must bind before any device
//! operation.
//!
//! The freeze itself was executed by the integrator on the host with the
//! read-only layout verifier and the freeze tool. This module records the
//! resulting identities as constants and re-derives the freeze receipt from a
//! structured observation: two isolated `CARGO_INCREMENTAL=0` builds with
//! byte-identical ELF and flat image, a read-only machine/layout audit that
//! left the input ELF unchanged, a four-entry `0444` package with a
//! grammar-checked `SHA256SUMS` manifest, exact marker membership, and the
//! `MARKER_LITERAL_MERGED` disposition of the `[R1:S536] BOOT_TO_UI_READY`
//! literal.
//!
//! It performs no device operation, does not rerun S543, opens no serial
//! descriptor, writes no SD card, and reports no power transition. It is not
//! wired into any boot, IRQ, scheduler or driver path. The pre-arm contract
//! for S546 is contract-only: `execution_permit` is always `false`, and the
//! authorization token is parsed and compared, never acted upon.
//!
//! Predecessor: S544 (reachable readiness producer remediation). Next gate:
//! S546 (third authorized physical boot/UART run with this exact package,
//! pending explicit operator authority; not automatic).
pub const S545_SEQUENCE: usize = 545;
pub const S545_EXPECTED_PREDECESSOR: usize = 544;
pub const S545_NEXT_SEQUENCE: usize = 546;
pub const S545_R1_STAGE: u8 = 1;
pub const S545_R1_RANGE_FIRST: usize = 536;
pub const S545_R1_RANGE_LAST: usize = 568;
pub const S545_SUPPORTED_PROFILE_RUNTIME_OBSERVATIONS: usize = 0;
pub const S545_PHYSICAL_OBSERVATIONS: usize = 0;
pub const S545_PHYSICAL_OR_DEVICE_OPERATIONS: usize = 0;
pub const S545_SD_WRITES: usize = 0;
pub const S545_UART_OPENS: usize = 0;
pub const S545_POWER_TRANSITIONS: usize = 0;
pub const S545_NEW_IMMUTABLE_RAW_CAPTURES: usize = 0;
pub const S545_S540_PHYSICAL_VERDICT_RETAINED_RED: bool = true;
pub const S545_S543_PHYSICAL_VERDICT_RETAINED_RED: bool = true;
pub const S545_AUTOMATIC_PROMOTION: bool = false;
pub const S545_BOOT_TO_UI_PHYSICALLY_OBSERVED: bool = false;
pub const S545_HARDWARE_PRESENT: bool = false;
pub const S545_R1_ACCEPTANCE_COMPLETE: bool = false;
pub const S545_EXECUTION_PERMIT: bool = false;
pub const RUNBOOK_EXECUTED_IN_S545: bool = false;
// Isolated build facts (host, integrator-executed).
pub const S545_CANDIDATE_PROFILE: &str = "board-rpi5";
pub const S545_CARGO_FEATURE_FLAGS: &str = "--no-default-features --features board-rpi5";
pub const S545_CARGO_INCREMENTAL: u8 = 0;
pub const S545_ISOLATED_BUILD_COUNT: usize = 2;
pub const S545_ELF_BYTES: u64 = 18_438_504;
pub const S545_ELF_SHA256: &str =
"6ce50d295e0aa97ab599cfa3cf567944ca7ed36d59d1b988e733be48b826c1c5";
pub const S545_BUILD_A_LOG_BYTES: u64 = 1_135_955;
pub const S545_BUILD_A_LOG_SHA256: &str =
"5aa11909f47b6ebe27b0dd18aa036573a48b37f05a966831aa089d3a3b6e73be";
pub const S545_BUILD_B_LOG_BYTES: u64 = 1_135_948;
pub const S545_BUILD_B_LOG_SHA256: &str =
"61160d45cc3114360a6107a96c557282ae9eaab76b13d3b8347c63b516468670";
pub const S545_BUILD_WARNING_HEADERS_EACH: usize = 2_865;
pub const S545_ZERO_WARNING_CLAIMED: bool = false;
// Flat image and the superseded S542 image it must not equal.
pub const S545_IMAGE_BYTES: u64 = 945_760;
pub const S545_IMAGE_SHA256: &str =
"ed1901a991e2f9e9ae3c16f254147a2b0180686a8d70ca5d7353374fee08d467";
pub const S545_SUPERSEDED_S542_IMAGE_BYTES: u64 = 941_392;
pub const S545_SUPERSEDED_S542_IMAGE_SHA256: &str =
"aa0c459b987c3f4c143b4eb14ce0ed655c2812e2a36516793e7bd8b27b60d87c";
// Frozen package.
pub const S545_PACKAGE_DIRECTORY: &str = "evidence/rpi5/r1/sequence-545-candidate-freeze/package";
pub const S545_PACKAGE_ENTRIES: usize = 4;
pub const S545_PACKAGE_MODE: u32 = 0o444;
pub const S545_PACKAGE_NLINK: u32 = 1;
pub const S545_IMAGE_NAME: &str = "aselsanos-rpi5.img";
pub const S545_DTB_NAME: &str = "bcm2712-rpi-5-b.dtb";
pub const S545_CONFIG_NAME: &str = "config.txt";
pub const S545_MANIFEST_NAME: &str = "SHA256SUMS";
pub const S545_DTB_BYTES: u64 = 78_703;
pub const S545_DTB_SHA256: &str =
"40a2fbe9c29e8b9a4912cf726a943068defb779fc052ec38e457a79c58abca00";
pub const S545_CONFIG_BYTES: u64 = 420;
pub const S545_CONFIG_SHA256: &str =
"aef848bf6e0c324148eade5054a15c71a1e8c04814a3ed2e680056f87c1f9bba";
pub const S545_MANIFEST_BYTES: u64 = 248;
pub const S545_MANIFEST_SHA256: &str =
"4accd201849f68107db4d21e4657b1510f043d7f900f713c383bd8909d33e586";
pub const S545_MANIFEST_LINES: usize = 3;
pub const S545_CONFIG_REQUIRED_DIRECTIVES: [&str; 4] = [
"kernel=aselsanos-rpi5.img",
"arm_64bit=1",
"kernel_address=0x80000",
"uart_2ndstage=0",
];
pub const S545_CONFIG_FORBIDDEN_DIRECTIVE: &str = "uart_2ndstage=1";
// Host tools (read-only audit and freeze; no disk, serial or power command).
pub const S545_LAYOUT_VERIFIER_PATH: &str = "scripts/verify-rpi5-s545-layout.sh";
pub const S545_LAYOUT_VERIFIER_BYTES: u64 = 11_150;
pub const S545_LAYOUT_VERIFIER_SHA256: &str =
"7a23bf574cda06d0fb4710d0c97427c0a743c7df4a3628d31077a220ad4140cd";
pub const S545_FREEZE_TOOL_PATH: &str = "scripts/freeze-rpi5-s545-r1-candidate.sh";
pub const S545_FREEZE_TOOL_BYTES: u64 = 9_175;
pub const S545_FREEZE_TOOL_SHA256: &str =
"ddd0f3baf1c2e47c26e97d1ee33d8ce00746dc6f5b64149489a63ff9cb42cfcd";
pub const S545_FIRMWARE_CONFIG_PATH: &str = "firmware/config-r1-s545.txt";
// Read-only machine/layout audit expectations.
pub const S545_ENTRY_ADDRESS: u64 = 0x80000;
pub const S545_KERNEL_START: u64 = 0x80000;
pub const S545_KERNEL_END: u64 = 0x11f_8000;
pub const S545_LINKED_SPAN: u64 = 18_317_312;
pub const S545_CPU1_TEXT_ORDER: [&str; 6] = [
"validate_identity_or_fail",
"service_s431_to_s535_production_acceptance_gate_on_cpu1",
"service_s536_r1_physical_boot_uart_evidence_contract_on_cpu1",
"service_s537_r1_physical_boot_uart_evidence_request_on_cpu1",
"service_s541_readiness_handoff_on_cpu1",
"service_s544_model_reachable_readiness_producer",
];
pub const S545_CPU0_TEXT_ORDER: [&str; 3] = [
"rpi5_g8h_prerequisite_complete",
"enter_s541_readiness_handoff_then_s538_boot_ui_on_cpu0",
"enter_s538_boot_ui_marker_runtime_on_cpu0",
];
pub const S545_S544_INLINED_SYMBOLS: [&str; 2] = [
"service_s544_model_reachable_readiness_producer",
"S544_PRODUCTION_STATE",
];
// Marker membership in the flat image (`strings | grep -c`).
pub const S545_MARKER_COUNT: usize = 7;
pub const S545_S541_HANDOFF_MARKER: &str = "ASELSAN/S541 HANDOFF=CPU1_PREFLIGHT_ARMED";
pub const S545_S541_ERROR_MARKER: &str = "ASELSAN/S541ERR";
pub const S545_BOOT_TO_UI_MARKER: &str = "[R1:S536] BOOT_TO_UI_READY";
pub const S545_S538_ROUTE_MARKER: &str = "ASELSAN/S538 ROUTE=PRIOR_BOOT_TO_UI";
pub const S545_S538_ERROR_MARKER: &str = "ASELSAN/S538ERR";
pub const S545_S538_CANDIDATE_TAG: &str = "ASELSAN-R1-S538-BOARD-RPI5";
pub const S545_BOOT8H_MARKER: &str = "ASELSAN/BOOT8H";
pub const S545_BOOT_TO_UI_MARKER_S542_COUNT: usize = 2;
pub const S545_BOOT_TO_UI_MARKER_SOURCE_REFERENCES: usize = 2;
// Pre-arm contract literals for S546 (contract only; no permit, no execution).
pub const S545_PREARM_CARD_SERIAL: u32 = 0x425001fa;
pub const S545_PREARM_CARD_SERIAL_HEX: &str = "0x425001fa";
pub const S545_PREARM_CARD_RAW_CID: &str = "009f5449534436344761425001fa01a1";
pub const S545_PREARM_CARD_BYTES: u64 = 62_549_655_552;
pub const S545_PREARM_CARD_NAME: &str = "TISD64G";
pub const S545_PREARM_VOLUME_LABEL: &str = "ASELSANBOOT";
pub const S545_PREARM_DEBUG_PROBE_SERIAL: &str = "E6647C74033F9131";
/// Last resolved serial path; S546 must freshly re-resolve it, never reuse it.
pub const S545_PREARM_SERIAL_PATH_LAST_RESOLVED: &str = "/dev/cu.usbmodem21302";
pub const S545_PREARM_UART_BAUD: u32 = 115_200;
pub const S545_PREARM_UART_DATA_BITS: u8 = 8;
pub const S545_PREARM_UART_STOP_BITS: u8 = 1;
pub const S545_PREARM_AUTHORIZATION_TOKEN: &str =
"S546_AUTHORIZE_SD_WRITE_READBACK_EJECT_UART_PREARM_ONE_POWER_ON_ed1901a9_425001fa_62549655552";
pub const S545_PREARM_AUTHORIZATION_PREFIX: &str =
"S546_AUTHORIZE_SD_WRITE_READBACK_EJECT_UART_PREARM_ONE_POWER_ON";
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct G8lS545ArtifactIdentity {
pub bytes: u64,
pub sha256: &'static str,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct G8lS545IsolatedBuildObservation {
pub cargo_incremental: u8,
pub profile: &'static str,
pub feature_flags: &'static str,
pub target_root_isolated: bool,
pub elf: G8lS545ArtifactIdentity,
pub log: G8lS545ArtifactIdentity,
pub warning_headers: usize,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct G8lS545ReproducibilityObservation {
pub isolated_builds: usize,
pub build_a: G8lS545IsolatedBuildObservation,
pub build_b: G8lS545IsolatedBuildObservation,
pub image: G8lS545ArtifactIdentity,
pub superseded_s542_image: G8lS545ArtifactIdentity,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct G8lS545LayoutAuditObservation {
pub entry: u64,
pub kernel_start: u64,
pub kernel_end: u64,
pub cpu1_text_lines: [u32; 6],
pub cpu1_call_counts: [u32; 6],
pub s544_inlined_symbol_counts: [u32; 2],
pub cpu0_text_lines: [u32; 3],
pub ldaxr_present: bool,
pub stlxr_present: bool,
pub dsb_ishst_count: u32,
pub sev_count: u32,
pub ldar_count: u32,
pub elf_before: G8lS545ArtifactIdentity,
pub elf_after: G8lS545ArtifactIdentity,
pub objcopy_invoked: bool,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct G8lS545PackageEntryObservation {
pub name: &'static str,
pub identity: G8lS545ArtifactIdentity,
pub mode: u32,
pub nlink: u32,
pub inode: u64,
pub regular_non_symlink: bool,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct G8lS545ToolObservation {
pub layout_verifier: G8lS545ArtifactIdentity,
pub freeze_tool: G8lS545ArtifactIdentity,
pub firmware_config: G8lS545ArtifactIdentity,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct G8lS545FreezeInput<'a> {
pub s544_source_gate_passed: bool,
pub reproducibility: G8lS545ReproducibilityObservation,
pub layout: G8lS545LayoutAuditObservation,
pub package: [G8lS545PackageEntryObservation; 4],
pub manifest_text: &'a str,
pub config_text: &'a str,
pub marker_counts: [usize; 7],
pub tools: G8lS545ToolObservation,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum G8lS545MarkerDisposition {
ExactOnce,
MarkerLiteralMerged { source_references: usize },
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct G8lS545MarkerExpectation {
pub literal: &'static str,
pub expected_count: usize,
pub disposition: G8lS545MarkerDisposition,
}
pub const S545_MARKER_TABLE: [G8lS545MarkerExpectation; S545_MARKER_COUNT] = [
G8lS545MarkerExpectation {
literal: S545_S541_HANDOFF_MARKER,
expected_count: 1,
disposition: G8lS545MarkerDisposition::ExactOnce,
},
G8lS545MarkerExpectation {
literal: S545_S541_ERROR_MARKER,
expected_count: 1,
disposition: G8lS545MarkerDisposition::ExactOnce,
},
G8lS545MarkerExpectation {
literal: S545_BOOT_TO_UI_MARKER,
expected_count: 1,
disposition: G8lS545MarkerDisposition::MarkerLiteralMerged {
source_references: S545_BOOT_TO_UI_MARKER_SOURCE_REFERENCES,
},
},
G8lS545MarkerExpectation {
literal: S545_S538_ROUTE_MARKER,
expected_count: 1,
disposition: G8lS545MarkerDisposition::ExactOnce,
},
G8lS545MarkerExpectation {
literal: S545_S538_ERROR_MARKER,
expected_count: 1,
disposition: G8lS545MarkerDisposition::ExactOnce,
},
G8lS545MarkerExpectation {
literal: S545_S538_CANDIDATE_TAG,
expected_count: 1,
disposition: G8lS545MarkerDisposition::ExactOnce,
},
G8lS545MarkerExpectation {
literal: S545_BOOT8H_MARKER,
expected_count: 1,
disposition: G8lS545MarkerDisposition::ExactOnce,
},
];
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct G8lS545CandidateFreezeReceipt {
pub sequence: usize,
pub predecessor_sequence: usize,
pub next_sequence: usize,
pub elf: G8lS545ArtifactIdentity,
pub image: G8lS545ArtifactIdentity,
pub superseded_s542_image_sha256: &'static str,
pub isolated_builds: usize,
pub warning_headers_each: usize,
pub zero_warning_claimed: bool,
pub linked_span: u64,
pub package_entries: usize,
pub package_mode: u32,
pub package_inode_signature: u64,
pub manifest_lines: usize,
pub marker_literals_merged: usize,
pub candidate_frozen: bool,
pub s544_hook_present: bool,
pub image_differs_from_s542: bool,
pub input_elf_immutable: bool,
pub execution_permit: bool,
pub device_operations: usize,
pub sd_writes: usize,
pub uart_opens: usize,
pub power_transitions: usize,
pub supported_profile_runtime_observations: usize,
pub physical_observations: usize,
pub runbook_executed: bool,
}
#[derive(Debug)]
pub struct G8lS545CandidateFreezeState {
receipt: Option<G8lS545CandidateFreezeReceipt>,
}
impl G8lS545CandidateFreezeState {
pub const fn new() -> Self {
Self { receipt: None }
}
pub const fn receipt(&self) -> Option<G8lS545CandidateFreezeReceipt> {
self.receipt
}
}
impl Default for G8lS545CandidateFreezeState {
fn default() -> Self {
Self::new()
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum G8lS545CandidateFreezeOutcome {
CandidateFrozen(G8lS545CandidateFreezeReceipt),
CandidateRetained(G8lS545CandidateFreezeReceipt),
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum G8lS545CandidateFreezeError {
PredecessorNotAccepted,
IsolatedBuildCountDrift,
BuildIsolationDrift,
ElfIdentityDrift,
BuildsNotByteIdentical,
BuildLogIdentityDrift,
WarningHeaderCountDrift,
ImageIdentityDrift,
ImageRetriesRejectedCandidate,
LayoutEntryDrift,
LayoutSpanDrift,
LayoutCallOrderDrift,
LayoutSymbolCountDrift,
LayoutBarrierDrift,
ElfMutatedDuringAudit,
PackageEntryNameDrift,
PackageEntryIdentityDrift,
PackageModeDrift,
PackageHardLink,
PackageInodeCollision,
PackageInodeSignatureOverflow,
ManifestLineCountDrift,
ManifestDigestGrammar,
ManifestSeparatorDrift,
ManifestFileNameDrift,
ManifestDigestMismatch,
ConfigDirectiveDrift,
MarkerCountDrift,
ToolIdentityDrift,
FrozenStateDrift,
AuthorizationTokenDrift,
AuthorizationTargetDrift,
PrearmSequenceDrift,
CandidateDrift,
}
impl G8lS545CandidateFreezeError {
pub const fn diagnostic_code(self) -> u64 {
match self {
Self::PredecessorNotAccepted => 1,
Self::IsolatedBuildCountDrift => 2,
Self::BuildIsolationDrift => 3,
Self::ElfIdentityDrift => 4,
Self::BuildsNotByteIdentical => 5,
Self::BuildLogIdentityDrift => 6,
Self::WarningHeaderCountDrift => 7,
Self::ImageIdentityDrift => 8,
Self::ImageRetriesRejectedCandidate => 9,
Self::LayoutEntryDrift => 10,
Self::LayoutSpanDrift => 11,
Self::LayoutCallOrderDrift => 12,
Self::LayoutSymbolCountDrift => 13,
Self::LayoutBarrierDrift => 14,
Self::ElfMutatedDuringAudit => 15,
Self::PackageEntryNameDrift => 16,
Self::PackageEntryIdentityDrift => 17,
Self::PackageModeDrift => 18,
Self::PackageHardLink => 19,
Self::PackageInodeCollision => 20,
Self::ManifestLineCountDrift => 21,
Self::ManifestDigestGrammar => 22,
Self::ManifestSeparatorDrift => 23,
Self::ManifestFileNameDrift => 24,
Self::ManifestDigestMismatch => 25,
Self::ConfigDirectiveDrift => 26,
Self::MarkerCountDrift => 27,
Self::ToolIdentityDrift => 28,
Self::FrozenStateDrift => 29,
Self::AuthorizationTokenDrift => 30,
Self::AuthorizationTargetDrift => 31,
Self::PrearmSequenceDrift => 32,
Self::CandidateDrift => 33,
Self::PackageInodeSignatureOverflow => 34,
}
}
}
const fn str_eq(left: &str, right: &str) -> bool {
let left = left.as_bytes();
let right = right.as_bytes();
if left.len() != right.len() {
return false;
}
let mut index = 0;
while index < left.len() {
if left[index] != right[index] {
return false;
}
index += 1;
}
true
}
const fn identity_eq(left: G8lS545ArtifactIdentity, right: G8lS545ArtifactIdentity) -> bool {
left.bytes == right.bytes && str_eq(left.sha256, right.sha256)
}
const fn is_lower_hex(byte: u8) -> bool {
matches!(byte, b'0'..=b'9' | b'a'..=b'f')
}
pub const fn s545_identity(bytes: u64, sha256: &'static str) -> G8lS545ArtifactIdentity {
G8lS545ArtifactIdentity { bytes, sha256 }
}
pub const fn s545_expected_package_identity(name: &str) -> Option<G8lS545ArtifactIdentity> {
if str_eq(name, S545_IMAGE_NAME) {
Some(s545_identity(S545_IMAGE_BYTES, S545_IMAGE_SHA256))
} else if str_eq(name, S545_DTB_NAME) {
Some(s545_identity(S545_DTB_BYTES, S545_DTB_SHA256))
} else if str_eq(name, S545_CONFIG_NAME) {
Some(s545_identity(S545_CONFIG_BYTES, S545_CONFIG_SHA256))
} else if str_eq(name, S545_MANIFEST_NAME) {
Some(s545_identity(S545_MANIFEST_BYTES, S545_MANIFEST_SHA256))
} else {
None
}
}
/// Reproducibility predicate: two isolated, non-incremental builds of the same
/// profile must emit byte-identical ELF and image; the logs may differ only in
/// their isolated target roots and are therefore bound by identity, not equality.
pub const fn s545_reproducibility_holds(observation: &G8lS545ReproducibilityObservation) -> bool {
let a = observation.build_a;
let b = observation.build_b;
observation.isolated_builds == S545_ISOLATED_BUILD_COUNT
&& a.cargo_incremental == S545_CARGO_INCREMENTAL
&& b.cargo_incremental == S545_CARGO_INCREMENTAL
&& str_eq(a.profile, S545_CANDIDATE_PROFILE)
&& str_eq(b.profile, S545_CANDIDATE_PROFILE)
&& str_eq(a.feature_flags, S545_CARGO_FEATURE_FLAGS)
&& str_eq(b.feature_flags, S545_CARGO_FEATURE_FLAGS)
&& a.target_root_isolated
&& b.target_root_isolated
&& identity_eq(a.elf, s545_identity(S545_ELF_BYTES, S545_ELF_SHA256))
&& identity_eq(a.elf, b.elf)
&& identity_eq(
a.log,
s545_identity(S545_BUILD_A_LOG_BYTES, S545_BUILD_A_LOG_SHA256),
)
&& identity_eq(
b.log,
s545_identity(S545_BUILD_B_LOG_BYTES, S545_BUILD_B_LOG_SHA256),
)
&& a.warning_headers == S545_BUILD_WARNING_HEADERS_EACH
&& b.warning_headers == S545_BUILD_WARNING_HEADERS_EACH
&& identity_eq(
observation.image,
s545_identity(S545_IMAGE_BYTES, S545_IMAGE_SHA256),
)
&& identity_eq(
observation.superseded_s542_image,
s545_identity(
S545_SUPERSEDED_S542_IMAGE_BYTES,
S545_SUPERSEDED_S542_IMAGE_SHA256,
),
)
&& !identity_eq(observation.image, observation.superseded_s542_image)
}
fn check_reproducibility(
observation: &G8lS545ReproducibilityObservation,
) -> Result<(), G8lS545CandidateFreezeError> {
use G8lS545CandidateFreezeError as E;
let a = observation.build_a;
let b = observation.build_b;
if observation.isolated_builds != S545_ISOLATED_BUILD_COUNT {
return Err(E::IsolatedBuildCountDrift);
}
for build in [a, b] {
if build.cargo_incremental != S545_CARGO_INCREMENTAL
|| !build.target_root_isolated
|| build.profile != S545_CANDIDATE_PROFILE
|| build.feature_flags != S545_CARGO_FEATURE_FLAGS
{
return Err(E::BuildIsolationDrift);
}
}
if a.elf != s545_identity(S545_ELF_BYTES, S545_ELF_SHA256) {
return Err(E::ElfIdentityDrift);
}
if a.elf != b.elf {
return Err(E::BuildsNotByteIdentical);
}
if a.log != s545_identity(S545_BUILD_A_LOG_BYTES, S545_BUILD_A_LOG_SHA256)
|| b.log != s545_identity(S545_BUILD_B_LOG_BYTES, S545_BUILD_B_LOG_SHA256)
{
return Err(E::BuildLogIdentityDrift);
}
if a.warning_headers != S545_BUILD_WARNING_HEADERS_EACH
|| b.warning_headers != S545_BUILD_WARNING_HEADERS_EACH
{
return Err(E::WarningHeaderCountDrift);
}
if observation.image.sha256 == S545_SUPERSEDED_S542_IMAGE_SHA256
|| observation.image == observation.superseded_s542_image
{
return Err(E::ImageRetriesRejectedCandidate);
}
if observation.image != s545_identity(S545_IMAGE_BYTES, S545_IMAGE_SHA256)
|| observation.superseded_s542_image
!= s545_identity(
S545_SUPERSEDED_S542_IMAGE_BYTES,
S545_SUPERSEDED_S542_IMAGE_SHA256,
)
{
return Err(E::ImageIdentityDrift);
}
if !s545_reproducibility_holds(observation) {
return Err(E::BuildsNotByteIdentical);
}
Ok(())
}
fn strictly_increasing(lines: &[u32]) -> bool {
lines.windows(2).all(|pair| pair[0] < pair[1])
}
/// Returns the linked span when the read-only layout audit matches the frozen
/// candidate exactly.
pub fn check_s545_layout_audit(
layout: &G8lS545LayoutAuditObservation,
) -> Result<u64, G8lS545CandidateFreezeError> {
use G8lS545CandidateFreezeError as E;
if layout.entry != S545_ENTRY_ADDRESS {
return Err(E::LayoutEntryDrift);
}
if layout.kernel_start != S545_KERNEL_START || layout.kernel_end != S545_KERNEL_END {
return Err(E::LayoutSpanDrift);
}
let span = layout
.kernel_end
.checked_sub(layout.kernel_start)
.ok_or(E::LayoutSpanDrift)?;
if span != S545_LINKED_SPAN {
return Err(E::LayoutSpanDrift);
}
if layout.cpu1_call_counts.iter().any(|&count| count != 1)
|| layout
.s544_inlined_symbol_counts
.iter()
.any(|&count| count != 1)
{
return Err(E::LayoutSymbolCountDrift);
}
if !strictly_increasing(&layout.cpu1_text_lines)
|| !strictly_increasing(&layout.cpu0_text_lines)
{
return Err(E::LayoutCallOrderDrift);
}
if !layout.ldaxr_present
|| !layout.stlxr_present
|| layout.dsb_ishst_count != 1
|| layout.sev_count != 1
|| layout.ldar_count < 1
{
return Err(E::LayoutBarrierDrift);
}
if layout.objcopy_invoked
|| layout.elf_before != layout.elf_after
|| layout.elf_before != s545_identity(S545_ELF_BYTES, S545_ELF_SHA256)
{
return Err(E::ElfMutatedDuringAudit);
}
Ok(span)
}
/// Returns the entry count and a device-independent inode signature: the
/// checked sum of the four distinct inode numbers, each weighted by its
/// canonical position. A re-created package therefore yields a different
/// receipt even when its bytes are identical.
pub fn check_s545_package_entries(
package: &[G8lS545PackageEntryObservation; 4],
) -> Result<(usize, u64), G8lS545CandidateFreezeError> {
use G8lS545CandidateFreezeError as E;
let expected_names = [
S545_IMAGE_NAME,
S545_DTB_NAME,
S545_CONFIG_NAME,
S545_MANIFEST_NAME,
];
let mut inodes = [0u64; 4];
let mut signature = 0u64;
for (index, entry) in package.iter().enumerate() {
if entry.name != expected_names[index] || !entry.regular_non_symlink {
return Err(E::PackageEntryNameDrift);
}
let expected =
s545_expected_package_identity(entry.name).ok_or(E::PackageEntryNameDrift)?;
if entry.identity != expected {
return Err(E::PackageEntryIdentityDrift);
}
if entry.mode & 0o777 != S545_PACKAGE_MODE {
return Err(E::PackageModeDrift);
}
if entry.nlink != S545_PACKAGE_NLINK {
return Err(E::PackageHardLink);
}
if inodes[..index].contains(&entry.inode) {
return Err(E::PackageInodeCollision);
}
inodes[index] = entry.inode;
let weight = u64::try_from(index).map_err(|_| E::PackageInodeSignatureOverflow)? + 1;
signature = entry
.inode
.checked_mul(weight)
.and_then(|weighted| signature.checked_add(weighted))
.ok_or(E::PackageInodeSignatureOverflow)?;
}
Ok((package.len(), signature))
}
/// `SHA256SUMS` grammar: exactly three `\n`-terminated lines, each a 64-char
/// lowercase-hex digest, two spaces, and one of the three payload names in
/// canonical order, with digests equal to the frozen constants.
pub fn validate_s545_manifest(text: &str) -> Result<usize, G8lS545CandidateFreezeError> {
use G8lS545CandidateFreezeError as E;
let expected: [(&str, &str); 3] = [
(S545_IMAGE_NAME, S545_IMAGE_SHA256),
(S545_DTB_NAME, S545_DTB_SHA256),
(S545_CONFIG_NAME, S545_CONFIG_SHA256),
];
if !text.ends_with('\n') || text.len() as u64 != S545_MANIFEST_BYTES {
return Err(E::ManifestLineCountDrift);
}
let mut lines = 0usize;
for (index, line) in text.split_terminator('\n').enumerate() {
lines = lines.checked_add(1).ok_or(E::ManifestLineCountDrift)?;
if index >= S545_MANIFEST_LINES {
return Err(E::ManifestLineCountDrift);
}
let bytes = line.as_bytes();
if bytes.len() < 66 || !bytes[..64].iter().all(|&byte| is_lower_hex(byte)) {
return Err(E::ManifestDigestGrammar);
}
if &bytes[64..66] != b" " {
return Err(E::ManifestSeparatorDrift);
}
let (digest, name) = (&line[..64], &line[66..]);
let (expected_name, expected_digest) = expected[index];
if name != expected_name {
return Err(E::ManifestFileNameDrift);
}
if digest != expected_digest {
return Err(E::ManifestDigestMismatch);
}
}
if lines != S545_MANIFEST_LINES {
return Err(E::ManifestLineCountDrift);
}
Ok(lines)
}
/// Each required directive must appear exactly once as a whole line; the
/// second-stage UART enable must be absent.
pub fn validate_s545_config_directives(text: &str) -> Result<usize, G8lS545CandidateFreezeError> {
use G8lS545CandidateFreezeError as E;
let mut counts = [0usize; 4];
for line in text.lines() {
let line = line.trim();
if line == S545_CONFIG_FORBIDDEN_DIRECTIVE {
return Err(E::ConfigDirectiveDrift);
}
for (index, directive) in S545_CONFIG_REQUIRED_DIRECTIVES.iter().enumerate() {
if line == *directive {
counts[index] = counts[index]
.checked_add(1)
.ok_or(E::ConfigDirectiveDrift)?;
}
}
}
if counts.iter().any(|&count| count != 1) {
return Err(E::ConfigDirectiveDrift);
}
Ok(counts.len())
}
/// Returns the number of literals recorded as `MARKER_LITERAL_MERGED`.
pub fn check_s545_marker_membership(
counts: &[usize; S545_MARKER_COUNT],
) -> Result<usize, G8lS545CandidateFreezeError> {
let mut merged = 0usize;
for (expectation, &count) in S545_MARKER_TABLE.iter().zip(counts.iter()) {
if count != expectation.expected_count {
return Err(G8lS545CandidateFreezeError::MarkerCountDrift);
}
if let G8lS545MarkerDisposition::MarkerLiteralMerged { source_references } =
expectation.disposition
{
if source_references <= count {
return Err(G8lS545CandidateFreezeError::MarkerCountDrift);
}
merged += 1;
}
}
Ok(merged)
}
fn check_tools(tools: &G8lS545ToolObservation) -> Result<(), G8lS545CandidateFreezeError> {
if tools.layout_verifier
!= s545_identity(S545_LAYOUT_VERIFIER_BYTES, S545_LAYOUT_VERIFIER_SHA256)
|| tools.freeze_tool != s545_identity(S545_FREEZE_TOOL_BYTES, S545_FREEZE_TOOL_SHA256)
|| tools.firmware_config != s545_identity(S545_CONFIG_BYTES, S545_CONFIG_SHA256)
{
return Err(G8lS545CandidateFreezeError::ToolIdentityDrift);
}
Ok(())
}
pub fn service_s545_model_candidate_freeze(
state: &mut G8lS545CandidateFreezeState,
input: &G8lS545FreezeInput<'_>,
) -> Result<G8lS545CandidateFreezeOutcome, G8lS545CandidateFreezeError> {
if !input.s544_source_gate_passed {
return Err(G8lS545CandidateFreezeError::PredecessorNotAccepted);
}
check_reproducibility(&input.reproducibility)?;
let linked_span = check_s545_layout_audit(&input.layout)?;
let (package_entries, package_inode_signature) = check_s545_package_entries(&input.package)?;
let manifest_lines = validate_s545_manifest(input.manifest_text)?;
validate_s545_config_directives(input.config_text)?;
let marker_literals_merged = check_s545_marker_membership(&input.marker_counts)?;
check_tools(&input.tools)?;
let receipt = G8lS545CandidateFreezeReceipt {
sequence: S545_SEQUENCE,
predecessor_sequence: S545_EXPECTED_PREDECESSOR,
next_sequence: S545_NEXT_SEQUENCE,
elf: input.reproducibility.build_a.elf,
image: input.reproducibility.image,
superseded_s542_image_sha256: input.reproducibility.superseded_s542_image.sha256,
isolated_builds: input.reproducibility.isolated_builds,
warning_headers_each: input.reproducibility.build_a.warning_headers,
zero_warning_claimed: S545_ZERO_WARNING_CLAIMED,
linked_span,
package_entries,
package_mode: S545_PACKAGE_MODE,
package_inode_signature,
manifest_lines,
marker_literals_merged,
candidate_frozen: true,
s544_hook_present: true,
image_differs_from_s542: true,
input_elf_immutable: true,
execution_permit: S545_EXECUTION_PERMIT,
device_operations: S545_PHYSICAL_OR_DEVICE_OPERATIONS,
sd_writes: S545_SD_WRITES,
uart_opens: S545_UART_OPENS,
power_transitions: S545_POWER_TRANSITIONS,
supported_profile_runtime_observations: S545_SUPPORTED_PROFILE_RUNTIME_OBSERVATIONS,
physical_observations: S545_PHYSICAL_OBSERVATIONS,
runbook_executed: RUNBOOK_EXECUTED_IN_S545,
};
if let Some(frozen) = state.receipt {
if frozen != receipt {
return Err(G8lS545CandidateFreezeError::FrozenStateDrift);
}
return Ok(G8lS545CandidateFreezeOutcome::CandidateRetained(frozen));
}
state.receipt = Some(receipt);
Ok(G8lS545CandidateFreezeOutcome::CandidateFrozen(receipt))
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct G8lS545AuthorizationTokenFields {
pub image_sha256_prefix: [u8; 8],
pub card_serial: u32,
pub card_bytes: u64,
}
fn parse_hex_u32(text: &str) -> Option<u32> {
let bytes = text.as_bytes();
if bytes.len() != 8 {
return None;
}
let mut value = 0u32;
for &byte in bytes {
let digit = match byte {
b'0'..=b'9' => byte - b'0',
b'a'..=b'f' => byte - b'a' + 10,
_ => return None,
};
value = value.checked_shl(4)?.checked_add(u32::from(digit))?;
}
Some(value)
}
fn parse_decimal_u64(text: &str) -> Option<u64> {
let bytes = text.as_bytes();
if bytes.is_empty() || bytes.len() > 20 || (bytes.len() > 1 && bytes[0] == b'0') {
return None;
}
let mut value = 0u64;
for &byte in bytes {
if !byte.is_ascii_digit() {
return None;
}
value = value.checked_mul(10)?.checked_add(u64::from(byte - b'0'))?;
}
Some(value)
}
/// Decodes `PREFIX_<8 hex image prefix>_<8 hex card serial>_<decimal card bytes>`
/// and binds every field to the frozen candidate and expected card.
pub fn parse_s546_authorization_token(
token: &str,
) -> Result<G8lS545AuthorizationTokenFields, G8lS545CandidateFreezeError> {
use G8lS545CandidateFreezeError as E;
let suffix = token
.strip_prefix(S545_PREARM_AUTHORIZATION_PREFIX)
.and_then(|rest| rest.strip_prefix('_'))
.ok_or(E::AuthorizationTokenDrift)?;
let mut parts = suffix.split('_');
let image_prefix = parts.next().ok_or(E::AuthorizationTokenDrift)?;
let serial = parts.next().ok_or(E::AuthorizationTokenDrift)?;
let card_bytes = parts.next().ok_or(E::AuthorizationTokenDrift)?;
if parts.next().is_some() {
return Err(E::AuthorizationTokenDrift);
}
let prefix_bytes = image_prefix.as_bytes();
if prefix_bytes.len() != 8 || !prefix_bytes.iter().all(|&byte| is_lower_hex(byte)) {
return Err(E::AuthorizationTokenDrift);
}
let mut image_sha256_prefix = [0u8; 8];
image_sha256_prefix.copy_from_slice(prefix_bytes);
let fields = G8lS545AuthorizationTokenFields {
image_sha256_prefix,
card_serial: parse_hex_u32(serial).ok_or(E::AuthorizationTokenDrift)?,
card_bytes: parse_decimal_u64(card_bytes).ok_or(E::AuthorizationTokenDrift)?,
};
if fields.image_sha256_prefix != S545_IMAGE_SHA256.as_bytes()[..8]
|| fields.card_serial != S545_PREARM_CARD_SERIAL
|| fields.card_bytes != S545_PREARM_CARD_BYTES
{
return Err(E::AuthorizationTargetDrift);
}
Ok(fields)
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct G8lS545PrearmRequest {
pub requested_sequence: usize,
pub authorization_token: &'static str,
pub card_serial: u32,
pub card_raw_cid: &'static str,
pub card_bytes: u64,
pub card_name: &'static str,
pub volume_label: &'static str,
pub debug_probe_serial: &'static str,
pub serial_path_freshly_resolved: bool,
pub uart_baud: u32,
pub uart_data_bits: u8,
pub uart_stop_bits: u8,
pub uart_parity_none: bool,
pub uart_flow_control_none: bool,
pub exclusive_tiocexcl: bool,
pub tciflush_before_capture: bool,
pub fresh_o_excl_raw: bool,
pub capture_armed_before_power_on: bool,
pub power_transitions_operator_reported_only: bool,
pub operator_asserts_pi_unpowered: bool,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct G8lS545PrearmContract {
pub sequence: usize,
pub target_sequence: usize,
pub candidate_image: G8lS545ArtifactIdentity,
pub token_fields: G8lS545AuthorizationTokenFields,
pub card_serial: u32,
pub card_raw_cid: &'static str,
pub card_bytes: u64,
pub card_name: &'static str,
pub volume_label: &'static str,
pub debug_probe_serial: &'static str,
pub uart_baud: u32,
pub uart_data_bits: u8,
pub uart_stop_bits: u8,
pub uart_parity_none: bool,
pub uart_flow_control_none: bool,
pub exclusive_tiocexcl: bool,
pub tciflush_before_capture: bool,
pub fresh_o_excl_raw: bool,
pub capture_armed_before_power_on: bool,
pub power_transitions_operator_reported_only: bool,
pub contract_ready: bool,
pub execution_permit: bool,
pub host_execution_started: bool,
pub device_operations: usize,
pub sd_writes: usize,
pub uart_opens: usize,
pub power_transitions: usize,
pub new_raw_captures: usize,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum G8lS545PrearmOutcome {
AwaitingFrozenCandidate,
StoppedAwaitingExplicitAuthorization,
StoppedAwaitingPowerOffAssertion,
StoppedAwaitingCompleteDiscipline,
ContractReadyExecutionPermitWithheld(G8lS545PrearmContract),
}
pub fn evaluate_s545_model_prearm_contract(
candidate: Option<G8lS545CandidateFreezeReceipt>,
request: Option<G8lS545PrearmRequest>,
) -> Result<G8lS545PrearmOutcome, G8lS545CandidateFreezeError> {
use G8lS545CandidateFreezeError as E;
let Some(candidate) = candidate else {
return Ok(G8lS545PrearmOutcome::AwaitingFrozenCandidate);
};
if candidate.sequence != S545_SEQUENCE
|| candidate.predecessor_sequence != S545_EXPECTED_PREDECESSOR
|| candidate.image != s545_identity(S545_IMAGE_BYTES, S545_IMAGE_SHA256)
|| candidate.superseded_s542_image_sha256 != S545_SUPERSEDED_S542_IMAGE_SHA256
|| !candidate.candidate_frozen
|| !candidate.s544_hook_present
|| !candidate.image_differs_from_s542
|| !candidate.input_elf_immutable
|| candidate.execution_permit
|| candidate.device_operations != 0
|| candidate.physical_observations != 0
|| candidate.runbook_executed
{
return Err(E::CandidateDrift);
}
let Some(request) = request else {
return Ok(G8lS545PrearmOutcome::StoppedAwaitingExplicitAuthorization);
};
if request.requested_sequence != S545_NEXT_SEQUENCE {
return Err(E::PrearmSequenceDrift);
}
let token_fields = parse_s546_authorization_token(request.authorization_token)?;
if request.card_serial != S545_PREARM_CARD_SERIAL
|| request.card_raw_cid != S545_PREARM_CARD_RAW_CID
|| request.card_bytes != S545_PREARM_CARD_BYTES
|| request.card_name != S545_PREARM_CARD_NAME
|| request.volume_label != S545_PREARM_VOLUME_LABEL
|| request.debug_probe_serial != S545_PREARM_DEBUG_PROBE_SERIAL
|| request.uart_baud != S545_PREARM_UART_BAUD
|| request.uart_data_bits != S545_PREARM_UART_DATA_BITS
|| request.uart_stop_bits != S545_PREARM_UART_STOP_BITS
|| !request.uart_parity_none
|| !request.uart_flow_control_none
{
return Err(E::AuthorizationTargetDrift);
}
if !request.operator_asserts_pi_unpowered {
return Ok(G8lS545PrearmOutcome::StoppedAwaitingPowerOffAssertion);
}
if !request.serial_path_freshly_resolved
|| !request.exclusive_tiocexcl
|| !request.tciflush_before_capture
|| !request.fresh_o_excl_raw
|| !request.capture_armed_before_power_on
|| !request.power_transitions_operator_reported_only
{
return Ok(G8lS545PrearmOutcome::StoppedAwaitingCompleteDiscipline);
}
Ok(G8lS545PrearmOutcome::ContractReadyExecutionPermitWithheld(
G8lS545PrearmContract {
sequence: S545_SEQUENCE,
target_sequence: S545_NEXT_SEQUENCE,
candidate_image: candidate.image,
token_fields,
card_serial: S545_PREARM_CARD_SERIAL,
card_raw_cid: S545_PREARM_CARD_RAW_CID,
card_bytes: S545_PREARM_CARD_BYTES,
card_name: S545_PREARM_CARD_NAME,
volume_label: S545_PREARM_VOLUME_LABEL,
debug_probe_serial: S545_PREARM_DEBUG_PROBE_SERIAL,
uart_baud: S545_PREARM_UART_BAUD,
uart_data_bits: S545_PREARM_UART_DATA_BITS,
uart_stop_bits: S545_PREARM_UART_STOP_BITS,
uart_parity_none: true,
uart_flow_control_none: true,
exclusive_tiocexcl: true,
tciflush_before_capture: true,
fresh_o_excl_raw: true,
capture_armed_before_power_on: true,
power_transitions_operator_reported_only: true,
contract_ready: true,
execution_permit: S545_EXECUTION_PERMIT,
host_execution_started: false,
device_operations: S545_PHYSICAL_OR_DEVICE_OPERATIONS,
sd_writes: S545_SD_WRITES,
uart_opens: S545_UART_OPENS,
power_transitions: S545_POWER_TRANSITIONS,
new_raw_captures: S545_NEW_IMMUTABLE_RAW_CAPTURES,
},
))
}
snippet sha256: 4ecd2ef5b35d…file sha256: 4ecd2ef5b35d…
02 · Doğrulayan test kodu
Operations komutuna bağlı focused test
tam dosyaL1–L946
simulation/tests/g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s545_r1_reachable_producer_candidate_freeze_prearm_contract.rs::S545 r1 reachable producer candidate freeze prearm contract focused tests
use aselsan_microkernel_simulation::g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s545_r1_reachable_producer_candidate_freeze_prearm_contract::*;
use sha2::{Digest, Sha256};
use std::collections::{BTreeSet, HashSet};
use std::fs;
use std::os::unix::fs::{MetadataExt, PermissionsExt};
use std::path::{Path, PathBuf};
const SOURCE: &str = include_str!(
"../../kernel/src/g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s545_r1_reachable_producer_candidate_freeze_prearm_contract.rs"
);
const MAIN: &str = include_str!("../../kernel/src/main.rs");
const SIMULATION_LIB: &str = include_str!("../src/lib.rs");
const PACKAGE_IMAGE: &[u8] =
include_bytes!("../../evidence/rpi5/r1/sequence-545-candidate-freeze/package/aselsanos-rpi5.img");
const PACKAGE_DTB: &[u8] =
include_bytes!("../../evidence/rpi5/r1/sequence-545-candidate-freeze/package/bcm2712-rpi-5-b.dtb");
const PACKAGE_CONFIG: &[u8] =
include_bytes!("../../evidence/rpi5/r1/sequence-545-candidate-freeze/package/config.txt");
const PACKAGE_MANIFEST_BYTES: &[u8] =
include_bytes!("../../evidence/rpi5/r1/sequence-545-candidate-freeze/package/SHA256SUMS");
const PACKAGE_MANIFEST: &str =
include_str!("../../evidence/rpi5/r1/sequence-545-candidate-freeze/package/SHA256SUMS");
const FIRMWARE_CONFIG: &str = include_str!("../../firmware/config-r1-s545.txt");
const LAYOUT_VERIFIER: &str = include_str!("../../scripts/verify-rpi5-s545-layout.sh");
const FREEZE_TOOL: &str = include_str!("../../scripts/freeze-rpi5-s545-r1-candidate.sh");
fn sha256(bytes: &[u8]) -> String {
format!("{:x}", Sha256::digest(bytes))
}
fn repository_root() -> PathBuf {
Path::new(env!("CARGO_MANIFEST_DIR")).join("..")
}
fn package_root() -> PathBuf {
repository_root().join(S545_PACKAGE_DIRECTORY)
}
fn count_bytes(haystack: &[u8], needle: &[u8]) -> usize {
haystack.windows(needle.len()).filter(|window| *window == needle).count()
}
fn build(log_bytes: u64, log_sha256: &'static str) -> G8lS545IsolatedBuildObservation {
G8lS545IsolatedBuildObservation {
cargo_incremental: 0,
profile: S545_CANDIDATE_PROFILE,
feature_flags: S545_CARGO_FEATURE_FLAGS,
target_root_isolated: true,
elf: s545_identity(S545_ELF_BYTES, S545_ELF_SHA256),
log: s545_identity(log_bytes, log_sha256),
warning_headers: S545_BUILD_WARNING_HEADERS_EACH,
}
}
fn reproducibility() -> G8lS545ReproducibilityObservation {
G8lS545ReproducibilityObservation {
isolated_builds: 2,
build_a: build(S545_BUILD_A_LOG_BYTES, S545_BUILD_A_LOG_SHA256),
build_b: build(S545_BUILD_B_LOG_BYTES, S545_BUILD_B_LOG_SHA256),
image: s545_identity(S545_IMAGE_BYTES, S545_IMAGE_SHA256),
superseded_s542_image: s545_identity(
S545_SUPERSEDED_S542_IMAGE_BYTES,
S545_SUPERSEDED_S542_IMAGE_SHA256,
),
}
}
fn layout() -> G8lS545LayoutAuditObservation {
G8lS545LayoutAuditObservation {
entry: 0x80000,
kernel_start: 0x80000,
kernel_end: 0x11f8000,
cpu1_text_lines: [40, 88, 131, 175, 210, 262],
cpu1_call_counts: [1; 6],
s544_inlined_symbol_counts: [1; 2],
cpu0_text_lines: [51, 97, 140],
ldaxr_present: true,
stlxr_present: true,
dsb_ishst_count: 1,
sev_count: 1,
ldar_count: 2,
elf_before: s545_identity(S545_ELF_BYTES, S545_ELF_SHA256),
elf_after: s545_identity(S545_ELF_BYTES, S545_ELF_SHA256),
objcopy_invoked: false,
}
}
fn package() -> [G8lS545PackageEntryObservation; 4] {
let entry = |name: &'static str, inode: u64| G8lS545PackageEntryObservation {
name,
identity: s545_expected_package_identity(name).unwrap(),
mode: 0o444,
nlink: 1,
inode,
regular_non_symlink: true,
};
[
entry(S545_IMAGE_NAME, 33_927_657),
entry(S545_DTB_NAME, 33_927_716),
entry(S545_CONFIG_NAME, 33_927_718),
entry(S545_MANIFEST_NAME, 33_927_719),
]
}
fn tools() -> G8lS545ToolObservation {
G8lS545ToolObservation {
layout_verifier: s545_identity(S545_LAYOUT_VERIFIER_BYTES, S545_LAYOUT_VERIFIER_SHA256),
freeze_tool: s545_identity(S545_FREEZE_TOOL_BYTES, S545_FREEZE_TOOL_SHA256),
firmware_config: s545_identity(S545_CONFIG_BYTES, S545_CONFIG_SHA256),
}
}
fn canonical_input() -> G8lS545FreezeInput<'static> {
G8lS545FreezeInput {
s544_source_gate_passed: true,
reproducibility: reproducibility(),
layout: layout(),
package: package(),
manifest_text: PACKAGE_MANIFEST,
config_text: FIRMWARE_CONFIG,
marker_counts: [1; 7],
tools: tools(),
}
}
fn freeze(
state: &mut G8lS545CandidateFreezeState,
) -> Result<G8lS545CandidateFreezeOutcome, G8lS545CandidateFreezeError> {
service_s545_model_candidate_freeze(state, &canonical_input())
}
fn frozen_receipt() -> G8lS545CandidateFreezeReceipt {
let mut state = G8lS545CandidateFreezeState::new();
let G8lS545CandidateFreezeOutcome::CandidateFrozen(receipt) = freeze(&mut state).unwrap()
else {
panic!("first S545 freeze must publish")
};
receipt
}
fn prearm_request() -> G8lS545PrearmRequest {
G8lS545PrearmRequest {
requested_sequence: 546,
authorization_token: S545_PREARM_AUTHORIZATION_TOKEN,
card_serial: 0x425001fa,
card_raw_cid: S545_PREARM_CARD_RAW_CID,
card_bytes: 62_549_655_552,
card_name: "TISD64G",
volume_label: "ASELSANBOOT",
debug_probe_serial: "E6647C74033F9131",
serial_path_freshly_resolved: true,
uart_baud: 115_200,
uart_data_bits: 8,
uart_stop_bits: 1,
uart_parity_none: true,
uart_flow_control_none: true,
exclusive_tiocexcl: true,
tciflush_before_capture: true,
fresh_o_excl_raw: true,
capture_armed_before_power_on: true,
power_transitions_operator_reported_only: true,
operator_asserts_pi_unpowered: true,
}
}
#[test]
fn sequence_scope_and_nonpromotion_are_exact() {
assert_eq!(S545_SEQUENCE, 545);
assert_eq!(S545_EXPECTED_PREDECESSOR, 544);
assert_eq!(S545_NEXT_SEQUENCE, 546);
assert_eq!(S545_R1_STAGE, 1);
assert_eq!(S545_R1_RANGE_FIRST, 536);
assert_eq!(S545_R1_RANGE_LAST, 568);
assert_eq!(S545_SUPPORTED_PROFILE_RUNTIME_OBSERVATIONS, 0);
assert_eq!(S545_PHYSICAL_OBSERVATIONS, 0);
assert_eq!(S545_PHYSICAL_OR_DEVICE_OPERATIONS, 0);
assert_eq!(S545_SD_WRITES, 0);
assert_eq!(S545_UART_OPENS, 0);
assert_eq!(S545_POWER_TRANSITIONS, 0);
assert_eq!(S545_NEW_IMMUTABLE_RAW_CAPTURES, 0);
assert!(S545_S540_PHYSICAL_VERDICT_RETAINED_RED);
assert!(S545_S543_PHYSICAL_VERDICT_RETAINED_RED);
assert!(!S545_AUTOMATIC_PROMOTION);
assert!(!S545_BOOT_TO_UI_PHYSICALLY_OBSERVED);
assert!(!S545_HARDWARE_PRESENT);
assert!(!S545_R1_ACCEPTANCE_COMPLETE);
assert!(!S545_EXECUTION_PERMIT);
assert!(!RUNBOOK_EXECUTED_IN_S545);
assert_eq!(S545_ISOLATED_BUILD_COUNT, 2);
assert_eq!(S545_CARGO_INCREMENTAL, 0);
assert_eq!(S545_ELF_BYTES, 18_438_504);
assert_eq!(S545_IMAGE_BYTES, 945_760);
assert_eq!(S545_SUPERSEDED_S542_IMAGE_BYTES, 941_392);
assert_eq!(S545_BUILD_WARNING_HEADERS_EACH, 2_865);
assert!(!S545_ZERO_WARNING_CLAIMED);
assert_eq!(S545_LINKED_SPAN, S545_KERNEL_END - S545_KERNEL_START);
assert_eq!(S545_PACKAGE_ENTRIES, 4);
assert_eq!(S545_PACKAGE_MODE, 0o444);
assert_eq!(S545_PREARM_CARD_SERIAL, 0x425001fa);
assert_eq!(S545_PREARM_CARD_BYTES, 62_549_655_552);
}
#[test]
fn module_is_registered_in_kernel_and_simulation() {
let module = "g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s545_r1_reachable_producer_candidate_freeze_prearm_contract";
assert!(MAIN.contains(&format!("mod {module};")));
assert!(SIMULATION_LIB.contains(&format!("pub mod {module};")));
}
#[test]
fn source_has_no_device_execution_or_uart_emission_surface() {
for forbidden in [
"unsafe",
"asm!",
"write_volatile",
"crate::uart",
"crate::arch",
"#[no_mangle]",
"spin::",
"std::",
"std::process::Command",
"/dev/disk",
"diskutil",
"dd if=",
"crate::kprintln!",
] {
assert!(!SOURCE.contains(forbidden), "forbidden token: {forbidden}");
}
assert!(SOURCE.contains("performs no device operation"));
assert!(SOURCE.contains("does not rerun S543"));
assert!(SOURCE.contains("not\n//! wired into any boot, IRQ, scheduler or driver path"));
assert!(SOURCE.contains("S545_SUPPORTED_PROFILE_RUNTIME_OBSERVATIONS: usize = 0"));
assert!(SOURCE.contains("S545_PHYSICAL_OBSERVATIONS: usize = 0"));
assert!(SOURCE.contains("S545_PHYSICAL_OR_DEVICE_OPERATIONS: usize = 0"));
assert!(SOURCE.contains("S545_R1_ACCEPTANCE_COMPLETE: bool = false"));
assert!(SOURCE.contains("S545_EXECUTION_PERMIT: bool = false"));
assert!(SOURCE.contains("RUNBOOK_EXECUTED_IN_S545: bool = false"));
}
#[test]
fn diagnostic_codes_are_nonzero_and_unique() {
use G8lS545CandidateFreezeError as E;
let errors = [
E::PredecessorNotAccepted,
E::IsolatedBuildCountDrift,
E::BuildIsolationDrift,
E::ElfIdentityDrift,
E::BuildsNotByteIdentical,
E::BuildLogIdentityDrift,
E::WarningHeaderCountDrift,
E::ImageIdentityDrift,
E::ImageRetriesRejectedCandidate,
E::LayoutEntryDrift,
E::LayoutSpanDrift,
E::LayoutCallOrderDrift,
E::LayoutSymbolCountDrift,
E::LayoutBarrierDrift,
E::ElfMutatedDuringAudit,
E::PackageEntryNameDrift,
E::PackageEntryIdentityDrift,
E::PackageModeDrift,
E::PackageHardLink,
E::PackageInodeCollision,
E::PackageInodeSignatureOverflow,
E::ManifestLineCountDrift,
E::ManifestDigestGrammar,
E::ManifestSeparatorDrift,
E::ManifestFileNameDrift,
E::ManifestDigestMismatch,
E::ConfigDirectiveDrift,
E::MarkerCountDrift,
E::ToolIdentityDrift,
E::FrozenStateDrift,
E::AuthorizationTokenDrift,
E::AuthorizationTargetDrift,
E::PrearmSequenceDrift,
E::CandidateDrift,
];
let codes: BTreeSet<_> = errors.into_iter().map(E::diagnostic_code).collect();
assert_eq!(codes.len(), errors.len());
assert_eq!(codes.len(), 34);
assert!(!codes.contains(&0));
}
#[test]
fn exact_observation_freezes_the_reachable_producer_candidate() {
let mut state = G8lS545CandidateFreezeState::new();
assert_eq!(state.receipt(), None);
let receipt = frozen_receipt();
assert_eq!(freeze(&mut state), Ok(G8lS545CandidateFreezeOutcome::CandidateFrozen(receipt)));
assert_eq!(state.receipt(), Some(receipt));
assert_eq!(receipt.sequence, 545);
assert_eq!(receipt.predecessor_sequence, 544);
assert_eq!(receipt.next_sequence, 546);
assert_eq!(receipt.elf, s545_identity(18_438_504, S545_ELF_SHA256));
assert_eq!(receipt.image, s545_identity(945_760, S545_IMAGE_SHA256));
assert_eq!(receipt.superseded_s542_image_sha256, S545_SUPERSEDED_S542_IMAGE_SHA256);
assert_eq!(receipt.isolated_builds, 2);
assert_eq!(receipt.warning_headers_each, 2_865);
assert!(!receipt.zero_warning_claimed);
assert_eq!(receipt.linked_span, 18_317_312);
assert_eq!(receipt.package_entries, 4);
assert_eq!(receipt.package_mode, 0o444);
assert_eq!(
receipt.package_inode_signature,
33_927_657 + 2 * 33_927_716 + 3 * 33_927_718 + 4 * 33_927_719
);
assert_eq!(receipt.manifest_lines, 3);
assert_eq!(receipt.marker_literals_merged, 1);
assert!(receipt.candidate_frozen);
assert!(receipt.s544_hook_present);
assert!(receipt.image_differs_from_s542);
assert!(receipt.input_elf_immutable);
assert!(!receipt.execution_permit);
assert_eq!(receipt.device_operations, 0);
assert_eq!(receipt.sd_writes, 0);
assert_eq!(receipt.uart_opens, 0);
assert_eq!(receipt.power_transitions, 0);
assert_eq!(receipt.supported_profile_runtime_observations, 0);
assert_eq!(receipt.physical_observations, 0);
assert!(!receipt.runbook_executed);
assert!(s545_reproducibility_holds(&reproducibility()));
}
#[test]
fn exact_replay_retains_the_same_receipt() {
let mut state = G8lS545CandidateFreezeState::default();
let G8lS545CandidateFreezeOutcome::CandidateFrozen(receipt) = freeze(&mut state).unwrap()
else {
panic!("first freeze missing")
};
assert_eq!(
freeze(&mut state),
Ok(G8lS545CandidateFreezeOutcome::CandidateRetained(receipt))
);
assert_eq!(
freeze(&mut state),
Ok(G8lS545CandidateFreezeOutcome::CandidateRetained(receipt))
);
assert_eq!(state.receipt(), Some(receipt));
}
#[test]
fn divergent_input_after_publication_fails_closed() {
let mut state = G8lS545CandidateFreezeState::new();
let receipt = match freeze(&mut state).unwrap() {
G8lS545CandidateFreezeOutcome::CandidateFrozen(receipt) => receipt,
other => panic!("unexpected {other:?}"),
};
let mut drift = canonical_input();
drift.reproducibility.build_b.elf.sha256 = S545_IMAGE_SHA256;
assert_eq!(
service_s545_model_candidate_freeze(&mut state, &drift),
Err(G8lS545CandidateFreezeError::BuildsNotByteIdentical)
);
let mut merged_twice = canonical_input();
merged_twice.marker_counts[2] = 2;
assert_eq!(
service_s545_model_candidate_freeze(&mut state, &merged_twice),
Err(G8lS545CandidateFreezeError::MarkerCountDrift)
);
let mut recreated = canonical_input();
for (entry, inode) in recreated.package.iter_mut().zip([1u64, 2, 3, 4]) {
entry.inode = inode;
}
assert_eq!(check_s545_package_entries(&recreated.package), Ok((4, 30)));
assert_eq!(
service_s545_model_candidate_freeze(&mut state, &recreated),
Err(G8lS545CandidateFreezeError::FrozenStateDrift)
);
assert_eq!(state.receipt(), Some(receipt));
let mut fresh = G8lS545CandidateFreezeState::new();
assert!(matches!(
service_s545_model_candidate_freeze(&mut fresh, &recreated),
Ok(G8lS545CandidateFreezeOutcome::CandidateFrozen(_))
));
}
#[test]
fn reproducibility_predicate_rejects_non_identical_builds_and_s542_retry() {
use G8lS545CandidateFreezeError as E;
let mut state = G8lS545CandidateFreezeState::new();
let cases: [(fn(&mut G8lS545FreezeInput<'static>), E); 8] = [
(|input| input.reproducibility.isolated_builds = 1, E::IsolatedBuildCountDrift),
(|input| input.reproducibility.build_a.cargo_incremental = 1, E::BuildIsolationDrift),
(|input| input.reproducibility.build_b.target_root_isolated = false, E::BuildIsolationDrift),
(|input| input.reproducibility.build_a.elf.bytes += 8, E::ElfIdentityDrift),
(|input| input.reproducibility.build_b.elf.bytes -= 8, E::BuildsNotByteIdentical),
(|input| input.reproducibility.build_b.log.sha256 = S545_BUILD_A_LOG_SHA256, E::BuildLogIdentityDrift),
(|input| input.reproducibility.build_a.warning_headers = 0, E::WarningHeaderCountDrift),
(|input| input.reproducibility.image.bytes = 945_761, E::ImageIdentityDrift),
];
for (mutate, expected) in cases {
let mut input = canonical_input();
mutate(&mut input);
assert!(!s545_reproducibility_holds(&input.reproducibility));
assert_eq!(service_s545_model_candidate_freeze(&mut state, &input), Err(expected));
}
let mut retry = canonical_input();
retry.reproducibility.image = retry.reproducibility.superseded_s542_image;
assert_eq!(
service_s545_model_candidate_freeze(&mut state, &retry),
Err(E::ImageRetriesRejectedCandidate)
);
let mut retry_sha_only = canonical_input();
retry_sha_only.reproducibility.image.sha256 = S545_SUPERSEDED_S542_IMAGE_SHA256;
assert_eq!(
service_s545_model_candidate_freeze(&mut state, &retry_sha_only),
Err(E::ImageRetriesRejectedCandidate)
);
let mut same = canonical_input();
same.reproducibility.superseded_s542_image = same.reproducibility.image;
assert_eq!(
service_s545_model_candidate_freeze(&mut state, &same),
Err(E::ImageRetriesRejectedCandidate)
);
let mut superseded_drift = canonical_input();
superseded_drift.reproducibility.superseded_s542_image.bytes = 941_393;
assert_eq!(
service_s545_model_candidate_freeze(&mut state, &superseded_drift),
Err(E::ImageIdentityDrift)
);
assert_ne!(S545_IMAGE_SHA256, S545_SUPERSEDED_S542_IMAGE_SHA256);
assert_ne!(S545_IMAGE_BYTES, S545_SUPERSEDED_S542_IMAGE_BYTES);
assert_eq!(state.receipt(), None);
}
#[test]
fn layout_audit_fails_closed_on_entry_span_order_symbol_barrier_and_elf_mutation() {
use G8lS545CandidateFreezeError as E;
assert_eq!(check_s545_layout_audit(&layout()), Ok(18_317_312));
let cases: [(fn(&mut G8lS545LayoutAuditObservation), E); 12] = [
(|l| l.entry = 0x80004, E::LayoutEntryDrift),
(|l| l.kernel_end = 0x11f8008, E::LayoutSpanDrift),
(|l| l.kernel_start = 0x11f8000, E::LayoutSpanDrift),
(|l| l.cpu1_text_lines = [40, 88, 175, 131, 210, 262], E::LayoutCallOrderDrift),
(|l| l.cpu1_text_lines[5] = 210, E::LayoutCallOrderDrift),
(|l| l.cpu0_text_lines = [97, 51, 140], E::LayoutCallOrderDrift),
(|l| l.cpu1_call_counts[5] = 2, E::LayoutSymbolCountDrift),
(|l| l.s544_inlined_symbol_counts[1] = 0, E::LayoutSymbolCountDrift),
(|l| l.dsb_ishst_count = 2, E::LayoutBarrierDrift),
(|l| l.ldar_count = 0, E::LayoutBarrierDrift),
(|l| l.elf_after.bytes = 18_438_505, E::ElfMutatedDuringAudit),
(|l| l.objcopy_invoked = true, E::ElfMutatedDuringAudit),
];
for (mutate, expected) in cases {
let mut observation = layout();
mutate(&mut observation);
assert_eq!(check_s545_layout_audit(&observation), Err(expected));
let mut input = canonical_input();
input.layout = observation;
let mut state = G8lS545CandidateFreezeState::new();
assert_eq!(service_s545_model_candidate_freeze(&mut state, &input), Err(expected));
}
let mut underflow = layout();
underflow.kernel_start = u64::MAX;
underflow.kernel_end = 0;
assert_eq!(check_s545_layout_audit(&underflow), Err(E::LayoutSpanDrift));
}
#[test]
fn package_entries_fail_closed_on_name_identity_mode_hardlink_and_inode() {
use G8lS545CandidateFreezeError as E;
assert_eq!(
check_s545_package_entries(&package()),
Ok((4, 33_927_657 + 2 * 33_927_716 + 3 * 33_927_718 + 4 * 33_927_719))
);
let mut overflow = package();
overflow[3].inode = u64::MAX;
assert_eq!(
check_s545_package_entries(&overflow),
Err(E::PackageInodeSignatureOverflow)
);
let cases: [(fn(&mut [G8lS545PackageEntryObservation; 4]), E); 7] = [
(|p| p.swap(0, 1), E::PackageEntryNameDrift),
(|p| p[3].name = "SHA512SUMS", E::PackageEntryNameDrift),
(|p| p[1].regular_non_symlink = false, E::PackageEntryNameDrift),
(|p| p[2].identity.bytes = 415, E::PackageEntryIdentityDrift),
(|p| p[0].mode = 0o644, E::PackageModeDrift),
(|p| p[1].nlink = 2, E::PackageHardLink),
(|p| p[3].inode = p[0].inode, E::PackageInodeCollision),
];
for (mutate, expected) in cases {
let mut observation = package();
mutate(&mut observation);
assert_eq!(check_s545_package_entries(&observation), Err(expected));
}
assert_eq!(s545_expected_package_identity("kernel8.img"), None);
assert_eq!(
s545_expected_package_identity("SHA256SUMS"),
Some(s545_identity(248, S545_MANIFEST_SHA256))
);
}
#[test]
fn manifest_grammar_validator_accepts_exact_and_rejects_malformed() {
use G8lS545CandidateFreezeError as E;
assert_eq!(validate_s545_manifest(PACKAGE_MANIFEST), Ok(3));
let lines: Vec<&str> = PACKAGE_MANIFEST.lines().collect();
let two_lines = format!("{}\n{}\n", lines[0], lines[1]);
assert_eq!(validate_s545_manifest(&two_lines), Err(E::ManifestLineCountDrift));
let four_lines = format!("{PACKAGE_MANIFEST}{}\n", lines[2]);
assert_eq!(validate_s545_manifest(&four_lines), Err(E::ManifestLineCountDrift));
let no_newline = PACKAGE_MANIFEST.trim_end_matches('\n').to_string();
assert_eq!(validate_s545_manifest(&no_newline), Err(E::ManifestLineCountDrift));
let uppercase = PACKAGE_MANIFEST.replacen("ed1901a9", "ED1901A9", 1);
assert_eq!(validate_s545_manifest(&uppercase), Err(E::ManifestDigestGrammar));
let single_space = format!(
"{} \n{}\n{}\n",
lines[0].replacen(" ", " ", 1),
lines[1],
lines[2]
);
assert_eq!(validate_s545_manifest(&single_space), Err(E::ManifestSeparatorDrift));
let renamed = PACKAGE_MANIFEST.replacen("config.txt", "config.tx1", 1);
assert_eq!(validate_s545_manifest(&renamed), Err(E::ManifestFileNameDrift));
let reordered = format!("{}\n{}\n{}\n", lines[1], lines[0], lines[2]);
assert_eq!(validate_s545_manifest(&reordered), Err(E::ManifestFileNameDrift));
let s542_digest = PACKAGE_MANIFEST.replacen(S545_IMAGE_SHA256, S545_SUPERSEDED_S542_IMAGE_SHA256, 1);
assert_eq!(validate_s545_manifest(&s542_digest), Err(E::ManifestDigestMismatch));
assert_eq!(validate_s545_manifest(""), Err(E::ManifestLineCountDrift));
}
#[test]
fn config_directive_validator_requires_exact_lines() {
use G8lS545CandidateFreezeError as E;
assert_eq!(validate_s545_config_directives(FIRMWARE_CONFIG), Ok(4));
assert_eq!(
validate_s545_config_directives(&FIRMWARE_CONFIG.replacen("uart_2ndstage=0", "uart_2ndstage=1", 1)),
Err(E::ConfigDirectiveDrift)
);
assert_eq!(
validate_s545_config_directives(&format!("{FIRMWARE_CONFIG}\nuart_2ndstage=1\n")),
Err(E::ConfigDirectiveDrift)
);
assert_eq!(
validate_s545_config_directives(&format!("{FIRMWARE_CONFIG}\narm_64bit=1\n")),
Err(E::ConfigDirectiveDrift)
);
assert_eq!(
validate_s545_config_directives(&FIRMWARE_CONFIG.replacen("kernel_address=0x80000", "kernel_address=0x200000", 1)),
Err(E::ConfigDirectiveDrift)
);
assert_eq!(
validate_s545_config_directives(&FIRMWARE_CONFIG.replacen("kernel=aselsanos-rpi5.img", "kernel=kernel8.img", 1)),
Err(E::ConfigDirectiveDrift)
);
assert_eq!(validate_s545_config_directives(""), Err(E::ConfigDirectiveDrift));
assert_eq!(FIRMWARE_CONFIG.as_bytes(), PACKAGE_CONFIG);
}
#[test]
fn marker_table_records_merged_literal_not_lost_reference() {
assert_eq!(S545_MARKER_TABLE.len(), 7);
assert_eq!(check_s545_marker_membership(&[1; 7]), Ok(1));
let merged = S545_MARKER_TABLE[2];
assert_eq!(merged.literal, "[R1:S536] BOOT_TO_UI_READY");
assert_eq!(merged.expected_count, 1);
assert_eq!(
merged.disposition,
G8lS545MarkerDisposition::MarkerLiteralMerged { source_references: 2 }
);
assert_eq!(S545_BOOT_TO_UI_MARKER_S542_COUNT, 2);
for (index, expectation) in S545_MARKER_TABLE.iter().enumerate() {
if index != 2 {
assert_eq!(expectation.disposition, G8lS545MarkerDisposition::ExactOnce);
}
assert_eq!(expectation.expected_count, 1);
let mut counts = [1usize; 7];
counts[index] = 0;
assert_eq!(
check_s545_marker_membership(&counts),
Err(G8lS545CandidateFreezeError::MarkerCountDrift)
);
counts[index] = 2;
assert_eq!(
check_s545_marker_membership(&counts),
Err(G8lS545CandidateFreezeError::MarkerCountDrift)
);
}
let literals: HashSet<&str> = S545_MARKER_TABLE.iter().map(|m| m.literal).collect();
assert_eq!(literals.len(), 7);
}
#[test]
fn authorization_token_decoder_binds_image_card_and_bytes() {
use G8lS545CandidateFreezeError as E;
let fields = parse_s546_authorization_token(S545_PREARM_AUTHORIZATION_TOKEN).unwrap();
assert_eq!(&fields.image_sha256_prefix, b"ed1901a9");
assert_eq!(fields.card_serial, 0x425001fa);
assert_eq!(fields.card_bytes, 62_549_655_552);
assert_eq!(
S545_PREARM_AUTHORIZATION_TOKEN,
"S546_AUTHORIZE_SD_WRITE_READBACK_EJECT_UART_PREARM_ONE_POWER_ON_ed1901a9_425001fa_62549655552"
);
let prefix = S545_PREARM_AUTHORIZATION_PREFIX;
let cases: Vec<(String, E)> = vec![
(String::new(), E::AuthorizationTokenDrift),
(prefix.to_string(), E::AuthorizationTokenDrift),
(
"S545_AUTHORIZE_SD_WRITE_READBACK_EJECT_UART_PREARM_ONE_POWER_ON_ed1901a9_425001fa_62549655552".to_string(),
E::AuthorizationTokenDrift,
),
(format!("{prefix}_ed1901a9_425001fa"), E::AuthorizationTokenDrift),
(format!("{prefix}_ed1901a9_425001fa_62549655552_extra"), E::AuthorizationTokenDrift),
(format!("{prefix}_ED1901A9_425001fa_62549655552"), E::AuthorizationTokenDrift),
(format!("{prefix}_ed1901a_425001fa_62549655552"), E::AuthorizationTokenDrift),
(format!("{prefix}_ed1901a9_425001fa9_62549655552"), E::AuthorizationTokenDrift),
(format!("{prefix}_ed1901a9_425001FA_62549655552"), E::AuthorizationTokenDrift),
(format!("{prefix}_ed1901a9_425001fa_062549655552"), E::AuthorizationTokenDrift),
(format!("{prefix}_ed1901a9_425001fa_184467440737095516160"), E::AuthorizationTokenDrift),
(format!("{prefix}_ed1901a9_425001fa_18446744073709551616"), E::AuthorizationTokenDrift),
(format!("{prefix}_ed1901a9_425001fa_6254965555x"), E::AuthorizationTokenDrift),
(format!("{prefix}_aa0c459b_425001fa_62549655552"), E::AuthorizationTargetDrift),
(format!("{prefix}_ed1901a9_425001fb_62549655552"), E::AuthorizationTargetDrift),
(format!("{prefix}_ed1901a9_425001fa_62549655553"), E::AuthorizationTargetDrift),
];
for (token, expected) in cases {
assert_eq!(parse_s546_authorization_token(&token), Err(expected), "{token}");
}
assert_eq!(
parse_s546_authorization_token(&format!("{prefix}_ed1901a9_425001fa_18446744073709551615")),
Err(E::AuthorizationTargetDrift)
);
}
#[test]
fn prearm_contract_never_publishes_execution_permit() {
use G8lS545CandidateFreezeError as E;
let receipt = frozen_receipt();
assert_eq!(
evaluate_s545_model_prearm_contract(None, Some(prearm_request())),
Ok(G8lS545PrearmOutcome::AwaitingFrozenCandidate)
);
assert_eq!(
evaluate_s545_model_prearm_contract(Some(receipt), None),
Ok(G8lS545PrearmOutcome::StoppedAwaitingExplicitAuthorization)
);
let mut unpowered_unknown = prearm_request();
unpowered_unknown.operator_asserts_pi_unpowered = false;
assert_eq!(
evaluate_s545_model_prearm_contract(Some(receipt), Some(unpowered_unknown)),
Ok(G8lS545PrearmOutcome::StoppedAwaitingPowerOffAssertion)
);
for mutate in [
(|r: &mut G8lS545PrearmRequest| r.serial_path_freshly_resolved = false) as fn(&mut G8lS545PrearmRequest),
|r| r.exclusive_tiocexcl = false,
|r| r.tciflush_before_capture = false,
|r| r.fresh_o_excl_raw = false,
|r| r.capture_armed_before_power_on = false,
|r| r.power_transitions_operator_reported_only = false,
] {
let mut request = prearm_request();
mutate(&mut request);
assert_eq!(
evaluate_s545_model_prearm_contract(Some(receipt), Some(request)),
Ok(G8lS545PrearmOutcome::StoppedAwaitingCompleteDiscipline)
);
}
let G8lS545PrearmOutcome::ContractReadyExecutionPermitWithheld(contract) =
evaluate_s545_model_prearm_contract(Some(receipt), Some(prearm_request())).unwrap()
else {
panic!("exact request must produce the contract")
};
assert_eq!(contract.sequence, 545);
assert_eq!(contract.target_sequence, 546);
assert_eq!(contract.candidate_image, receipt.image);
assert_eq!(contract.card_serial, 0x425001fa);
assert_eq!(contract.card_raw_cid, "009f5449534436344761425001fa01a1");
assert_eq!(contract.card_bytes, 62_549_655_552);
assert_eq!(contract.card_name, "TISD64G");
assert_eq!(contract.volume_label, "ASELSANBOOT");
assert_eq!(contract.debug_probe_serial, "E6647C74033F9131");
assert_eq!(contract.uart_baud, 115_200);
assert_eq!(contract.uart_data_bits, 8);
assert_eq!(contract.uart_stop_bits, 1);
assert!(contract.uart_parity_none && contract.uart_flow_control_none);
assert!(contract.exclusive_tiocexcl && contract.tciflush_before_capture);
assert!(contract.fresh_o_excl_raw && contract.capture_armed_before_power_on);
assert!(contract.power_transitions_operator_reported_only);
assert!(contract.contract_ready);
assert!(!contract.execution_permit);
assert!(!contract.host_execution_started);
assert_eq!(contract.device_operations, 0);
assert_eq!(contract.sd_writes, 0);
assert_eq!(contract.uart_opens, 0);
assert_eq!(contract.power_transitions, 0);
assert_eq!(contract.new_raw_captures, 0);
let mut early = prearm_request();
early.requested_sequence = 545;
assert_eq!(
evaluate_s545_model_prearm_contract(Some(receipt), Some(early)),
Err(E::PrearmSequenceDrift)
);
let mut late = prearm_request();
late.requested_sequence = 547;
assert_eq!(
evaluate_s545_model_prearm_contract(Some(receipt), Some(late)),
Err(E::PrearmSequenceDrift)
);
let mut wrong_probe = prearm_request();
wrong_probe.debug_probe_serial = "E6647C74033F9132";
assert_eq!(
evaluate_s545_model_prearm_contract(Some(receipt), Some(wrong_probe)),
Err(E::AuthorizationTargetDrift)
);
let mut wrong_cid = prearm_request();
wrong_cid.card_raw_cid = "009f5449534436344761425001fa01a2";
assert_eq!(
evaluate_s545_model_prearm_contract(Some(receipt), Some(wrong_cid)),
Err(E::AuthorizationTargetDrift)
);
let mut flow = prearm_request();
flow.uart_flow_control_none = false;
assert_eq!(
evaluate_s545_model_prearm_contract(Some(receipt), Some(flow)),
Err(E::AuthorizationTargetDrift)
);
let mut bad_token = prearm_request();
bad_token.authorization_token = "S546_AUTHORIZE";
assert_eq!(
evaluate_s545_model_prearm_contract(Some(receipt), Some(bad_token)),
Err(E::AuthorizationTokenDrift)
);
let mut permitted = receipt;
permitted.execution_permit = true;
assert_eq!(
evaluate_s545_model_prearm_contract(Some(permitted), Some(prearm_request())),
Err(E::CandidateDrift)
);
let mut s542 = receipt;
s542.image = s545_identity(S545_SUPERSEDED_S542_IMAGE_BYTES, S545_SUPERSEDED_S542_IMAGE_SHA256);
assert_eq!(
evaluate_s545_model_prearm_contract(Some(s542), Some(prearm_request())),
Err(E::CandidateDrift)
);
}
#[test]
fn predecessor_gate_and_tool_identity_drift_fail_closed() {
use G8lS545CandidateFreezeError as E;
let mut state = G8lS545CandidateFreezeState::new();
let mut unaccepted = canonical_input();
unaccepted.s544_source_gate_passed = false;
assert_eq!(
service_s545_model_candidate_freeze(&mut state, &unaccepted),
Err(E::PredecessorNotAccepted)
);
let mut verifier = canonical_input();
verifier.tools.layout_verifier.bytes = 11_151;
assert_eq!(service_s545_model_candidate_freeze(&mut state, &verifier), Err(E::ToolIdentityDrift));
let mut tool = canonical_input();
tool.tools.freeze_tool.sha256 = S545_LAYOUT_VERIFIER_SHA256;
assert_eq!(service_s545_model_candidate_freeze(&mut state, &tool), Err(E::ToolIdentityDrift));
let mut config = canonical_input();
config.tools.firmware_config.bytes = 415;
assert_eq!(service_s545_model_candidate_freeze(&mut state, &config), Err(E::ToolIdentityDrift));
let mut manifest = canonical_input();
manifest.manifest_text = "";
assert_eq!(
service_s545_model_candidate_freeze(&mut state, &manifest),
Err(E::ManifestLineCountDrift)
);
let mut directives = canonical_input();
directives.config_text = "uart_2ndstage=1\n";
assert_eq!(
service_s545_model_candidate_freeze(&mut state, &directives),
Err(E::ConfigDirectiveDrift)
);
assert_eq!(state.receipt(), None);
}
#[test]
fn frozen_package_files_have_exact_identities_modes_and_manifest() {
assert_eq!(PACKAGE_IMAGE.len() as u64, S545_IMAGE_BYTES);
assert_eq!(sha256(PACKAGE_IMAGE), S545_IMAGE_SHA256);
assert_eq!(PACKAGE_DTB.len() as u64, S545_DTB_BYTES);
assert_eq!(sha256(PACKAGE_DTB), S545_DTB_SHA256);
assert_eq!(PACKAGE_CONFIG.len() as u64, S545_CONFIG_BYTES);
assert_eq!(sha256(PACKAGE_CONFIG), S545_CONFIG_SHA256);
assert_eq!(PACKAGE_MANIFEST_BYTES.len() as u64, S545_MANIFEST_BYTES);
assert_eq!(sha256(PACKAGE_MANIFEST_BYTES), S545_MANIFEST_SHA256);
assert_eq!(PACKAGE_MANIFEST.as_bytes(), PACKAGE_MANIFEST_BYTES);
assert_eq!(
PACKAGE_MANIFEST,
"ed1901a991e2f9e9ae3c16f254147a2b0180686a8d70ca5d7353374fee08d467 aselsanos-rpi5.img\n40a2fbe9c29e8b9a4912cf726a943068defb779fc052ec38e457a79c58abca00 bcm2712-rpi-5-b.dtb\naef848bf6e0c324148eade5054a15c71a1e8c04814a3ed2e680056f87c1f9bba config.txt\n"
);
let mut inodes = HashSet::new();
let mut entries = 0usize;
for name in [S545_IMAGE_NAME, S545_DTB_NAME, S545_CONFIG_NAME, S545_MANIFEST_NAME] {
let metadata = fs::symlink_metadata(package_root().join(name)).unwrap();
assert!(metadata.is_file(), "{name} regular");
assert_eq!(metadata.permissions().mode() & 0o777, 0o444, "{name} mode");
assert_eq!(metadata.nlink(), 1, "{name} link count");
assert!(inodes.insert((metadata.dev(), metadata.ino())), "{name} inode");
assert_eq!(metadata.len(), s545_expected_package_identity(name).unwrap().bytes);
entries += 1;
}
assert_eq!(entries, S545_PACKAGE_ENTRIES);
assert_eq!(fs::read_dir(package_root()).unwrap().count(), S545_PACKAGE_ENTRIES);
assert_eq!(PACKAGE_CONFIG, FIRMWARE_CONFIG.as_bytes());
assert_eq!(FIRMWARE_CONFIG.matches("uart_2ndstage=0").count(), 1);
assert_eq!(FIRMWARE_CONFIG.matches("uart_2ndstage=1").count(), 0);
assert_eq!(FIRMWARE_CONFIG.matches("kernel=aselsanos-rpi5.img").count(), 1);
assert_eq!(FIRMWARE_CONFIG.matches("kernel_address=0x80000").count(), 1);
assert_eq!(FIRMWARE_CONFIG.matches("arm_64bit=1").count(), 1);
}
#[test]
fn frozen_image_contains_exact_marker_membership() {
for expectation in S545_MARKER_TABLE {
assert_eq!(
count_bytes(PACKAGE_IMAGE, expectation.literal.as_bytes()),
expectation.expected_count,
"{}",
expectation.literal
);
}
assert_eq!(count_bytes(PACKAGE_IMAGE, b"[R1:S536] BOOT_TO_UI_READY"), 1);
assert_eq!(count_bytes(PACKAGE_IMAGE, b"ASELSAN/BOOT8H"), 1);
assert!(LAYOUT_VERIFIER.contains("MARKER_LITERAL_MERGED=1"));
assert!(FREEZE_TOOL.contains("R1 marker merged literal is not exact-once"));
}
#[test]
fn host_tools_are_read_only_and_pin_the_frozen_identities() {
assert_eq!(LAYOUT_VERIFIER.len() as u64, S545_LAYOUT_VERIFIER_BYTES);
assert_eq!(sha256(LAYOUT_VERIFIER.as_bytes()), S545_LAYOUT_VERIFIER_SHA256);
assert_eq!(FREEZE_TOOL.len() as u64, S545_FREEZE_TOOL_BYTES);
assert_eq!(sha256(FREEZE_TOOL.as_bytes()), S545_FREEZE_TOOL_SHA256);
for tool in [LAYOUT_VERIFIER, FREEZE_TOOL] {
for required in [
"EXPECTED_ELF_BYTES=18438504",
"EXPECTED_ELF_SHA256=6ce50d295e0aa97ab599cfa3cf567944ca7ed36d59d1b988e733be48b826c1c5",
"EXPECTED_IMAGE_BYTES=945760",
"EXPECTED_IMAGE_SHA256=ed1901a991e2f9e9ae3c16f254147a2b0180686a8d70ca5d7353374fee08d467",
"set -eu",
] {
assert!(tool.contains(required), "{required}");
}
for forbidden in ["diskutil", "/dev/disk", "/dev/cu.", "/dev/tty.", "stty", "dd if="] {
assert!(!tool.contains(forbidden), "{forbidden}");
}
}
for required in [
"EXPECTED_LINKED_SPAN=18317312",
"[ \"$entry\" = 0x80000 ]",
"[ \"$start_hex\" = 0000000000080000 ]",
"[ \"$end_hex\" = 00000000011f8000 ]",
"require_call_count \"$secondary\" service_s544_model_reachable_readiness_producer 1",
"symbol_count '::S544_PRODUCTION_STATE'",
"symbol_count '::service_s544_model_reachable_readiness_producer'",
"require_marker_count '[R1:S536] BOOT_TO_UI_READY' 1",
"dsb[[:space:]]+ishst$",
"sev$",
"ldaxr",
"stlxr",
"ldar",
"ELF SHA-256 changed during audit",
"RUNBOOK_EXECUTED_IN_S545=NO",
"never invokes llvm-objcopy",
] {
assert!(LAYOUT_VERIFIER.contains(required), "{required}");
}
assert!(!LAYOUT_VERIFIER.contains("\"$objcopy\""));
for required in [
"EXPECTED_DTB_BYTES=78703",
"EXPECTED_DTB_SHA256=40a2fbe9c29e8b9a4912cf726a943068defb779fc052ec38e457a79c58abca00",
"EXPECTED_CONFIG_BYTES=420",
"EXPECTED_CONFIG_SHA256=aef848bf6e0c324148eade5054a15c71a1e8c04814a3ed2e680056f87c1f9bba",
"EXPECTED_SUMS_BYTES=248",
"EXPECTED_SUMS_SHA256=4accd201849f68107db4d21e4657b1510f043d7f900f713c383bd8909d33e586",
"EXPECTED_PACKAGE_ENTRIES=4",
"EXPECTED_FILE_MODE=444",
"EXPECTED_LAYOUT_VERIFIER_BYTES=11150",
"EXPECTED_LAYOUT_VERIFIER_SHA256=7a23bf574cda06d0fb4710d0c97427c0a743c7df4a3628d31077a220ad4140cd",
"uart_2ndstage=0",
"uart_2ndstage=1",
"S545_CANDIDATE_FREEZE=PASS",
"DEVICE_OPERATIONS=0 SD_WRITES=0 UART_OPENS=0 POWER_TRANSITIONS=0",
"EXECUTION_PERMIT=0",
"/bin/chmod 0444",
"config-r1-s545.txt",
] {
assert!(FREEZE_TOOL.contains(required), "{required}");
}
let firmware = fs::read(repository_root().join(S545_FIRMWARE_CONFIG_PATH)).unwrap();
assert_eq!(firmware.len() as u64, S545_CONFIG_BYTES);
assert_eq!(sha256(&firmware), S545_CONFIG_SHA256);
}
#[test]
fn isolated_build_logs_have_exact_identities_and_warning_headers() {
let evidence = repository_root().join("evidence/rpi5/r1/sequence-545-candidate-freeze");
for (name, bytes, digest) in [
("build-a.log", S545_BUILD_A_LOG_BYTES, S545_BUILD_A_LOG_SHA256),
("build-b.log", S545_BUILD_B_LOG_BYTES, S545_BUILD_B_LOG_SHA256),
] {
let log = fs::read(evidence.join(name)).unwrap();
assert_eq!(log.len() as u64, bytes, "{name} bytes");
assert_eq!(sha256(&log), digest, "{name} SHA-256");
let text = String::from_utf8_lossy(&log);
assert_eq!(
text.lines().filter(|line| line.starts_with("warning")).count(),
S545_BUILD_WARNING_HEADERS_EACH,
"{name} warning headers"
);
assert_eq!(text.lines().filter(|line| line.starts_with("error")).count(), 0);
}
assert_ne!(S545_BUILD_A_LOG_SHA256, S545_BUILD_B_LOG_SHA256);
assert_eq!(S545_BUILD_A_LOG_BYTES - S545_BUILD_B_LOG_BYTES, 7);
}
#[test]
fn immutable_s540_and_s543_raws_remain_unchanged_and_unpromoted() {
let s540 = fs::read(
repository_root().join("evidence/rpi5/r1/sequence-540-physical-boot-uart/s540-uart.raw"),
)
.unwrap();
assert_eq!(s540.len(), 20_525);
assert_eq!(
sha256(&s540),
"fc3f934543ab5d829ad8a16e2b332dd2bdc35a81c6c0f6423256101448e45114"
);
let s543 = fs::read(
repository_root()
.join("evidence/rpi5/r1/sequence-543-remediated-physical-retry/s543-uart.raw"),
)
.unwrap();
assert_eq!(s543.len(), 20_509);
assert_eq!(
sha256(&s543),
"1f1111a1a39ab6263b505b0889d025df19d5c48bb2f84e30708412b0da47dc11"
);
for raw in [&s540, &s543] {
assert_eq!(count_bytes(raw, b"[R1:S536] BOOT_TO_UI_READY"), 0);
assert_eq!(count_bytes(raw, b"ASELSAN/S538 ROUTE=PRIOR_BOOT_TO_UI"), 0);
}
assert_eq!(count_bytes(&s543, b"ASELSAN/S541ERR Cpu0ReadinessTimeout"), 1);
assert!(S545_S540_PHYSICAL_VERDICT_RETAINED_RED);
assert!(S545_S543_PHYSICAL_VERDICT_RETAINED_RED);
assert!(!S545_AUTOMATIC_PROMOTION);
assert!(!S545_BOOT_TO_UI_PHYSICALLY_OBSERVED);
}
snippet sha256: 13e364c18394…file sha256: 13e364c18394…
03 · Kapı kimlik kaydı
Operations sıra, kimlik ve başlık bağı
tam Operations kaydıL3232–L3291
website/src/lib/operations.ts::g8l-s545-r1-reachable-producer-candidate-freeze-prearm-contract
{
id: "g8l-s545-r1-reachable-producer-candidate-freeze-prearm-contract",
date: "2026-08-30",
sequence: 545,
status: "passed",
umbrella_status: "partial",
title: "S545 · R1 reachable-producer candidate freeze ve pre-arm sözleşmesi",
summary:
"S545 host-only kapısı PASS'tir: S544 reachable CPU1 readiness producer hook'unu içeren board-rpi5 candidate'ı iki izole CARGO_INCREMENTAL=0 build ile byte-exact yeniden üretildi (ELF 18438504 B / 6ce50d29…c1c5, flat image 945760 B / ed1901a9…8d467) ve dört dosyalı 0444 paket olarak donduruldu; reddedilen S542 imajından (941392 B / aa0c459b…d87c) farklıdır. Read-only layout auditi entry 0x80000, linked span 18317312, CPU1 identity→S431–S535→S536→S537→S541→S544 exact-once sırasını ve ldaxr/stlxr/dsb ishst/sev/ldar disiplinini doğruladı; [R1:S536] BOOT_TO_UI_READY literal'i linker tarafından birleştirildiği için MARKER_LITERAL_MERGED olarak kaydedildi, kayıp referans değildir. S546 pre-arm sözleşmesi (kart 0x425001fa / TISD64G / ASELSANBOOT, Debug Probe E6647C74033F9131, exclusive 115200/8N1) yalnız sözleşmedir; execution_permit=false'tur. Focused 21/21 PASS'tir. S540 ve S543 fiziksel RED immutable kalır; runtime/physical observation=0/0, device operation=0, SD/UART/power=0/0/0, RUNBOOK_EXECUTED_IN_S545=NO, Boot-to-UI=false ve R1 acceptance=false'tur. S546 bu exact paketle üçüncü yetkili fiziksel boot/UART koşusudur; açık operatör yetkisi bekler ve otomatik değildir.",
evidence: [
"S545 host-only bir kaynak/model kapısıdır: donanım, panel, modem, board, SD kart, UART veya güç gözlemi yoktur; entegratörün hostta yürüttüğü freeze'in kimlikleri modele sabit olarak kodlanmış ve focused testte doğrulanmıştır.",
"İki izole CARGO_INCREMENTAL=0 board-rpi5 build (--no-default-features --features board-rpi5) byte-exact ELF üretti: 18438504 B / 6ce50d295e0aa97ab599cfa3cf567944ca7ed36d59d1b988e733be48b826c1c5.",
"Build logları yalnız izole target root'ları nedeniyle farklıdır: build-a 1135955 B / 5aa11909f47b6ebe27b0dd18aa036573a48b37f05a966831aa089d3a3b6e73be, build-b 1135948 B / 61160d45cc3114360a6107a96c557282ae9eaab76b13d3b8347c63b516468670; her birinde 2865 warning başlığı sayılmıştır ve zero-warning iddiası kurulmaz.",
"Flat image (llvm-objcopy -O binary) 945760 B / ed1901a991e2f9e9ae3c16f254147a2b0180686a8d70ca5d7353374fee08d467'dir; önceki S542 imajı 941392 B / aa0c459b987c3f4c143b4eb14ce0ed655c2812e2a36516793e7bd8b27b60d87c'den hem byte hem SHA-256 olarak farklıdır, bu nedenle reddedilen imajın retry'ı değildir.",
"Paket evidence/rpi5/r1/sequence-545-candidate-freeze/package dört girdidir (mode 0444, nlink 1, ayrık inode): aselsanos-rpi5.img; bcm2712-rpi-5-b.dtb 78703 B / 40a2fbe9c29e8b9a4912cf726a943068defb779fc052ec38e457a79c58abca00; config.txt 420 B / aef848bf6e0c324148eade5054a15c71a1e8c04814a3ed2e680056f87c1f9bba; SHA256SUMS 248 B / 4accd201849f68107db4d21e4657b1510f043d7f900f713c383bd8909d33e586.",
"config.txt exact kernel=aselsanos-rpi5.img, kernel_address=0x80000, arm_64bit=1 ve tek uart_2ndstage=0 içerir, uart_2ndstage=1 içermez; firmware/config-r1-s545.txt paket config.txt ile byte-exact aynıdır.",
"Read-only layout auditi (scripts/verify-rpi5-s545-layout.sh 11150 B / 7a23bf574cda06d0fb4710d0c97427c0a743c7df4a3628d31077a220ad4140cd) entry 0x80000, __kernel_start 0x80000, __kernel_end 0x11f8000 ve linked span 18317312'yi; CPU1 secondary-run text sırasını identity → S431–S535 gate → S536 → S537 → S541 → S544 model call exact-once olarak; inlined S544 wrapper nedeniyle service_s544_model_reachable_readiness_producer ve S544_PRODUCTION_STATE sembollerinin exact-once olduğunu; CPU0 prior-boot → S541 → S538 sırasını; ldaxr/stlxr, exact-once dsb ishst, exact-once sev ve ldar'ı ve ELF'in audit öncesi/sonrası değişmediğini doğruladı.",
"Freeze aracı scripts/freeze-rpi5-s545-r1-candidate.sh 9175 B / ddd0f3baf1c2e47c26e97d1ee33d8ce00746dc6f5b64149489a63ff9cb42cfcd'dir; disk, seri port veya güç komutu içermez ve focused test onu çalıştırmaz, yalnız içeriğini ve kimliğini doğrular.",
"Marker üyeliği (strings | grep -c): ASELSAN/S541 HANDOFF=CPU1_PREFLIGHT_ARMED 1, ASELSAN/S541ERR 1, [R1:S536] BOOT_TO_UI_READY 1, ASELSAN/S538 ROUTE=PRIOR_BOOT_TO_UI 1, ASELSAN/S538ERR 1, ASELSAN-R1-S538-BOARD-RPI5 1, ASELSAN/BOOT8H 1. S542 Boot-to-UI literal'ini 2 saymıştı; bu build'de linker özdeş literal'i birleştirdiği için tablo MARKER_LITERAL_MERGED (source_references=2) olarak kaydeder, kayıp referans olarak değil.",
"Model freeze receipt, reproducibility predicate'i, SHA256SUMS grammar validator'ı (üç satır, 64 lowercase-hex, çift boşluk, canonical dosya sırası, exact digest), config directive validator'ı, marker-membership tablosu, checked inode signature'ı ve execution_permit=false pre-arm sözleşmesi struct'ını içerir; predecessor, build, ELF/image, layout, paket, manifest, config, marker, tool ve authorization drift'lerinin her biri fail-closed ayrı hata kodudur (34 nonzero unique kod).",
"Exact replay CandidateRetained ile aynı receipt'i döndürür; yayından sonra yeniden oluşturulmuş bir paket (farklı inode'lar) FrozenStateDrift ile reddedilir; S542 imajına eşit candidate ImageRetriesRejectedCandidate ile reddedilir.",
"S546 pre-arm sözleşmesi yalnız sözleşmedir: kart seri 0x425001fa / CID 009f5449534436344761425001fa01a1 / 62549655552 B / TISD64G / volume ASELSANBOOT; Debug Probe E6647C74033F9131 son çözümlenen /dev/cu.usbmodem21302 (S546 taze çözümlemelidir); exclusive TIOCEXCL 115200/8N1 parity yok flow yok, TCIFLUSH, fresh O_EXCL raw, güç verilmeden önce armed capture; yalnız operatör raporlu güç geçişleri; token literal S546_AUTHORIZE_SD_WRITE_READBACK_EJECT_UART_PREARM_ONE_POWER_ON_ed1901a9_425001fa_62549655552 decode edilip candidate ve karta bağlanır; exact istek bile ContractReadyExecutionPermitWithheld döndürür ve execution_permit=false, host_execution_started=false, tüm sayaçlar 0 kalır.",
"Focused test dört paket dosyasını, SHA256SUMS metnini, firmware config'i ve iki host aracını include_bytes!/include_str! ile gömer, byte uzunluklarını ve SHA-256 digest'lerini doğrular, iki build logunu yeniden okuyup her birinde 2865 warning başlığı sayar ve paket mode/nlink/inode'larını diskte kontrol eder.",
"Focused target 1 grup / 21 passed / 0 failed / 0 ignored / 0 filtered verdi; ilk derlenen koşu 20/21 idi ve tek fark test beklentisiydi (model doğru olarak ImageRetriesRejectedCandidate döndürdü), model davranışı değişmedi.",
"Implementation 40040 B / 4ecd2ef5b35d61fb2efca8a6cb28b215481854ed09bc6214e2e93d505ea866ab; focused test 40697 B / 13e364c18394f72d18f77b56fc82eb32b7294f47a16ea3c3c9acf5dbfd849483 SHA-256'dır.",
"Proof 9014 B'dır; evidence/rpi5/r1/sequence-545-candidate-freeze/README.md tüm kimlikleri ve closeout satırlarını kaydeder.",
"S540 immutable raw 20525 B / fc3f934543ab5d829ad8a16e2b332dd2bdc35a81c6c0f6423256101448e45114 ve S543 immutable raw 20509 B / 1f1111a1a39ab6263b505b0889d025df19d5c48bb2f84e30708412b0da47dc11 byte-exact korunur; her iki fiziksel verdict RED'dir, automatic promotion=false ve rerun=false'tur.",
"RUNBOOK_EXECUTED_IN_S545=NO; supported-profile runtime observations=0, physical observations=0, device operations=0, SD writes=0, UART opens=0, power transitions=0, new immutable raw=0, hardware present=false, Boot-to-UI physically observed=false ve R1 acceptance=false'tur.",
"S546 bu exact paketle (ed1901a9…8d467) üçüncü yetkili fiziksel boot/UART koşusudur; yalnız açık operatör yetkisiyle ve ayrı kapı olarak yürütülebilir, S545 onu ne planlar ne de izin verir.",
],
commands: [
"CARGO_INCREMENTAL=0 cargo test -p aselsan_microkernel_simulation --test g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s545_r1_reachable_producer_candidate_freeze_prearm_contract -- --test-threads=1",
],
terminalSessions: [
{
id: "s545-focused",
title: "S545 candidate freeze ve pre-arm sözleşmesi focused",
commandLines: [
"CARGO_INCREMENTAL=0 cargo test -p aselsan_microkernel_simulation --test g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s545_r1_reachable_producer_candidate_freeze_prearm_contract -- --test-threads=1",
],
outputLines: [
"test result: ok. 21 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.03s",
"S545 focused=1 group / 21 passed / 0 failed",
"hardware=none physical=0 runbook=NO",
],
exitCode: 0,
outputMode: "complete",
},
],
terminalSessionsNote:
"S545 host-only freeze ve pre-arm sözleşmesi PASS'tir; supported-profile runtime veya fiziksel PASS değildir. S540 ve S543 RED raw'ları ve kararları değişmez; execution permit yayımlanmaz.",
limitations: [
"S545 yalnız host üzerinde candidate freeze ve sözleşme modelidir; hiçbir donanım/panel/modem/board gözlemi yoktur.",
"S540 ve S543 fiziksel RED immutable kalır; S545 bunları yeniden yorumlamaz, yeniden koşmaz ve yükseltmez.",
"BOOT_TO_UI_READY gerçek UART'ta görülmedi; Boot-to-UI ve R1 acceptance false kalır.",
"S546 pre-arm sözleşmesi execution permit değildir; SD write/read-back/eject, UART açma ve güç geçişi S545'te sıfırdır ve yetkilendirilmemiştir.",
"Fresh build warning sayıları (2865) sıfır değildir; zero-warning iddiası yoktur.",
"S546 bu exact paketle üçüncü yetkili fiziksel boot/UART koşusu için ayrı kapı, taze target revalidation, açık operatör yetkisi ve yeni immutable raw ister; otomatik değildir.",
],
},snippet sha256: 4dbde9bfac66…file sha256: 9726dbf00f84…
Focused test komutu
CARGO_INCREMENTAL=0 cargo test -p aselsan_microkernel_simulation --test g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s545_r1_reachable_producer_candidate_freeze_prearm_contract -- --test-threads=1proof: docs/M8.1-RPi5-G8l-S545-R1-Reachable-Producer-Candidate-Freeze-Prearm-Contract-Proof.md
Registry schema v5 · generator
website/scripts/generate-code-gates.mjs · Tam SHA-256: 3050638b71a684d8f8f947a8a6faa237a17fa8db5dc0db04fb207b668b462af9