ASELSANMicrokernel
S571 · SOURCE-BOUND GATE EVIDENCE

S571 · Fiziksel boot/UART koşusu — immutable PASS

tam S571 implementation modülü → Operations --test hedefi ile bağlı tam focused test → ayrı Operations kaydı Bu sayfa yalnız S571 kapısına aittir; komşu kapıların kaynakları bu kabulün içine katılmaz.

S571Focused kod testiOperations id exactsource SHA exacttest target exact

operation: g8l-s571-r1-frozen-manifest-physical-boot-uart-pass

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–L642
kernel/src/g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s571_r1_frozen_manifest_physical_boot_uart_run.rs::S571 r1 frozen manifest physical boot uart run implementation
//! S571 records the separately authorized fourth physical Raspberry Pi 5
//! boot/UART run as an immutable physical PASS. The exact S570 candidate was
//! staged to the exact card, read back byte-for-byte, ejected, booted once and
//! captured through the exact Debug Probe. The 20947-byte immutable raw
//! contains BOOT8G, BOOT8H, S541 handoff, S538 route and the required
//! `[R1:S536] BOOT_TO_UI_READY` marker exactly once, with no bounded G8h,
//! S541/S538, panic or unknown-IRQ error marker.
//!
//! The prior no-card and card-present PENDING preflights remain immutable
//! historical evidence. This simulation-only module records both that
//! boundary and the later physical receipt; it cannot write a card, open a
//! UART, power hardware or execute the runbook. S540, S543 and S546 remain
//! separate RED observations. S571 proves the UART readiness marker, not
//! visible scanout, touch, modem/audio or the broader R1 product predicate.

#![allow(dead_code)]

pub const S571_SEQUENCE: usize = 571;
pub const S571_EXPECTED_PREDECESSOR: usize = 570;
pub const S571_R1_STAGE: u8 = 1;
pub const S571_PHYSICAL_GATE_STATUS: &str = "PASS";
pub const S571_PREFLIGHT_GATE_STATUS: &str = "PENDING_OPERATOR_AUTHORIZATION";
pub const S571_SUPPORTED_PROFILE_RUNTIME_OBSERVATIONS: usize = 1;
pub const S571_PHYSICAL_OBSERVATIONS: usize = 1;
pub const S571_PHYSICAL_OR_DEVICE_OPERATIONS: usize = 1;
pub const S571_PREFLIGHT_PHYSICAL_OR_DEVICE_OPERATIONS: usize = 0;
pub const S571_SD_WRITE_TRANSACTIONS: usize = 1;
pub const S571_SD_WRITES: usize = 4;
pub const S571_SD_READBACKS: usize = 4;
pub const S571_SD_EJECTS: usize = 1;
pub const S571_UART_OPENS: usize = 1;
pub const S571_POWER_TRANSITIONS: usize = 2;
pub const S571_POWER_TRANSITIONS_OPERATOR_REPORTED: usize = 2;
pub const S571_POWER_TRANSITIONS_INDEPENDENTLY_OBSERVED: usize = 0;
pub const S571_NEW_IMMUTABLE_RAW_CAPTURES: usize = 1;
pub const S571_HARDWARE_PRESENT: bool = true;
pub const S571_BOOT_TO_UI_PHYSICALLY_OBSERVED: bool = true;
pub const S571_R1_ACCEPTANCE_COMPLETE: bool = false;
pub const S571_AUTOMATIC_PROMOTION: bool = false;
pub const RUNBOOK_EXECUTED_IN_S571: bool = true;

pub const S571_CANDIDATE_IMAGE_BYTES: u64 = 945_920;
pub const S571_CANDIDATE_IMAGE_SHA256: &str =
    "a24f4d24e838cd7d1a6b2ff217d864e9c4b08f12ce7dd165b302e8073a980b04";
pub const S571_PREDECESSOR_IMAGE_BYTES: u64 = 945_760;
pub const S571_PREDECESSOR_IMAGE_SHA256: &str =
    "ed1901a991e2f9e9ae3c16f254147a2b0180686a8d70ca5d7353374fee08d467";
pub const S571_FLASH_TOOL_BYTES: u64 = 25_843;
pub const S571_FLASH_TOOL_SHA256: &str =
    "d8bc29601b4d80b6a83296bc2985b2b9765a654db0c4d18a37c4fde2c8dc032e";
pub const S571_CAPTURE_WRAPPER_BYTES: u64 = 339;
pub const S571_CAPTURE_WRAPPER_SHA256: &str =
    "6d75a29a235d1a5d7557621f5cd1a6b6838e86458a52511d1d87a864ef18f7b9";
pub const S571_CAPTURE_ENGINE_BYTES: u64 = 20_572;
pub const S571_CAPTURE_ENGINE_SHA256: &str =
    "9f001c4cec407bbb4310ca0f89d9cc7e8a1be32307ba8d7ea0541e315ff1efec";
pub const S571_INITIAL_NO_CARD_PREFLIGHT_BYTES: u64 = 773;
pub const S571_INITIAL_NO_CARD_PREFLIGHT_SHA256: &str =
    "abc20430aeca906d08216d7fbdb55ca3fef7a5fe709da485536d485e7ade1db8";
pub const S571_CARD_PREFLIGHT_BYTES: u64 = 2_028;
pub const S571_CARD_PREFLIGHT_SHA256: &str =
    "a66909c988a6da26db84ccb4a875815af3c35ee09772f560b8635538c4ffbf43";
pub const S571_EVIDENCE_README_BYTES: u64 = 4_710;
pub const S571_EVIDENCE_README_SHA256: &str =
    "d31bc0f3c92f7f24c2d61e258d97eb6abce08a7fa7234c143cefb4942ef321dd";
pub const S571_RAW_BYTES: u64 = 20_947;
pub const S571_RAW_SHA256: &str =
    "8eba34fcd970d7b5dd276690013b5513ec426020c915356d98d6e5bf0b4e1c83";
pub const S571_RAW_MODE_OCTAL: &str = "0444";
pub const S571_RAW_LINK_COUNT: usize = 1;
pub const S571_RAW_NUL_BYTES: usize = 5;
pub const S571_RAW_CR_BYTES: usize = 215;
pub const S571_RAW_LF_BYTES: usize = 215;
pub const S571_FLASH_LOG_BYTES: u64 = 644;
pub const S571_FLASH_LOG_SHA256: &str =
    "df136a52ee37792bde3dba222bf36af1ff4aee9c8889c02aa97369024cac7155";
pub const S571_CAPTURE_BUILD_LOG_BYTES: u64 = 769;
pub const S571_CAPTURE_BUILD_LOG_SHA256: &str =
    "0086fab68b15a8d647786d0834dae8974f10b5130490eb537822962d2b78660d";
pub const S571_CAPTURE_LOG_BYTES: u64 = 752;
pub const S571_CAPTURE_LOG_SHA256: &str =
    "1733302491aa1010a2f2b5a1e7683a4102649f4b5f8b2ce7e7e875f597289e24";
pub const S571_CLOSEOUT_LOG_BYTES: u64 = 1_319;
pub const S571_CLOSEOUT_LOG_SHA256: &str =
    "1b3557cb63999d7b98073392cbfeea16cc6739e3cde02a03c977bcf39ba7cdad";
pub const S571_EVIDENCE_MANIFEST_BYTES: u64 = 606;
pub const S571_EVIDENCE_MANIFEST_SHA256: &str =
    "7887075a7c152e6491cc6fd520179efd9b92a0aa73f0a05331f55d98e796c5d3";
pub const S571_CAPTURE_BINARY_BYTES: u64 = 35_224;
pub const S571_CAPTURE_BINARY_SHA256: &str =
    "de1af99ba9c2de5730280b192bc6f3cd00eaa9ed08948685fc0e40763b882664";

pub const S571_EXPECTED_CARD_SERIAL: u32 = 0x425001fa;
pub const S571_EXPECTED_CARD_BYTES: u64 = 62_549_655_552;
pub const S571_EXPECTED_CARD_RAW_CID: &str = "009f5449534436344761425001fa01a1";
pub const S571_EXPECTED_PROBE_SERIAL: &str = "E6647C74033F9131";
pub const S571_EXPECTED_UART_CALLOUT: &str = "/dev/cu.usbmodem21302";
pub const S571_EXPECTED_UART_DIALIN: &str = "/dev/tty.usbmodem21302";
pub const S571_AUTHORIZATION_TOKEN: &str =
    "S571_AUTHORIZE_SD_WRITE_READBACK_EJECT_UART_PREARM_ONE_POWER_ON_a24f4d24_425001fa_62549655552";
pub const S571_READ_ONLY_PROBE_PRESENT: bool = true;
pub const S571_READ_ONLY_UART_HOLDERS: usize = 0;
pub const S571_READ_ONLY_EXTERNAL_PHYSICAL_DISKS: usize = 0;
pub const S571_EXPECTED_CARD_PRESENT: bool = true;
pub const S571_PREFLIGHT_AUTHORIZATION_RECEIVED: bool = false;
pub const S571_AUTHORIZATION_RECEIVED: bool = true;
pub const S571_PI_POWER_OFF_ASSERTION_RECEIVED: bool = true;
pub const S571_OPERATOR_POWER_ON_REPORTED: bool = true;
pub const S571_OPERATOR_POWER_OFF_AFTER_CAPTURE_REPORTED: bool = true;
pub const S571_UART_HOLDERS_AT_CLOSEOUT: usize = 0;
pub const S571_DISK_PRESENT_AT_CLOSEOUT: bool = false;
pub const S571_CAPTURE_ARMED_BEFORE_POWER: bool = true;
pub const S571_CAPTURE_CLOSED: bool = true;
pub const S571_CAPTURE_TERMINAL_SEEN: bool = true;
pub const S571_CAPTURE_GRACE_COMPLETE: bool = true;
pub const S571_CAPTURE_DURABLE: bool = true;
pub const S571_VISIBLE_SCANOUT_OBSERVED: bool = false;
pub const S571_PHYSICAL_INPUT_OBSERVED: bool = false;
pub const S571_CARD_RAW_CID_UART_COUNT: usize = 1;

pub const S571_BOOT8G_MARKER: &str = "ASELSAN/BOOT8G";
pub const S571_BOOT8H_MARKER: &str = "ASELSAN/BOOT8H";
pub const S571_REQUIRED_MARKER: &str = "[R1:S536] BOOT_TO_UI_READY";
pub const S571_ROUTE_MARKER: &str = "ASELSAN/S538 ROUTE=PRIOR_BOOT_TO_UI";
pub const S571_HANDOFF_MARKER: &str = "ASELSAN/S541 HANDOFF=CPU1_PREFLIGHT_ARMED";
pub const S571_G8H_ERROR_MARKER: &str = "ASELSAN/G8HERR REPORTER=CPU0";
pub const S571_S541_ERROR_MARKER: &str = "ASELSAN/S541ERR";
pub const S571_S538_ERROR_MARKER: &str = "ASELSAN/S538ERR";

pub const S571_S546_RETAINED_RED: bool = true;
pub const S571_S546_RAW_BYTES: u64 = 16_990;
pub const S571_S546_RAW_SHA256: &str =
    "a71a9107b4b6ea351eb65720a6b82486105fffdb931563d1c39e8a381c3e485d";

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct G8lS571ArtifactIdentity {
    pub bytes: u64,
    pub sha256: &'static str,
}

pub const fn s571_identity(bytes: u64, sha256: &'static str) -> G8lS571ArtifactIdentity {
    G8lS571ArtifactIdentity { bytes, sha256 }
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct G8lS571ReadOnlyPreflightObservation<'a> {
    pub predecessor_sequence: usize,
    pub predecessor_passed: bool,
    pub candidate: G8lS571ArtifactIdentity,
    pub flash_tool: G8lS571ArtifactIdentity,
    pub capture_wrapper: G8lS571ArtifactIdentity,
    pub capture_engine: G8lS571ArtifactIdentity,
    pub preflight_log: G8lS571ArtifactIdentity,
    pub evidence_readme: G8lS571ArtifactIdentity,
    pub probe_present: bool,
    pub probe_serial: &'a str,
    pub uart_callout: &'a str,
    pub uart_dialin: &'a str,
    pub uart_holders: usize,
    pub external_physical_disks: usize,
    pub expected_card_present: bool,
    pub authorization_token: Option<&'a str>,
    pub pi_power_off_asserted: bool,
    pub physical_or_device_operations: usize,
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct G8lS571PendingReceipt {
    pub sequence: usize,
    pub predecessor_sequence: usize,
    pub status: &'static str,
    pub candidate: G8lS571ArtifactIdentity,
    pub probe_present: bool,
    pub uart_holders: usize,
    pub external_physical_disks: usize,
    pub authorization_received: bool,
    pub pi_power_off_assertion_received: bool,
    pub physical_or_device_operations: usize,
    pub runbook_executed: bool,
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct G8lS571PendingState {
    receipt: Option<G8lS571PendingReceipt>,
}

impl G8lS571PendingState {
    pub const fn new() -> Self {
        Self { receipt: None }
    }

    pub const fn receipt(&self) -> Option<G8lS571PendingReceipt> {
        self.receipt
    }
}

impl Default for G8lS571PendingState {
    fn default() -> Self {
        Self::new()
    }
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum G8lS571PendingOutcome {
    PendingRecorded(G8lS571PendingReceipt),
    PendingRetained(G8lS571PendingReceipt),
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum G8lS571PendingError {
    PredecessorRejected,
    CandidateIdentityDrift,
    ToolIdentityDrift,
    EvidenceIdentityDrift,
    ProbeIdentityDrift,
    UartHolderPresent,
    CardPresenceClaimDrift,
    AuthorizationClaimDrift,
    PowerAssertionClaimDrift,
    DeviceOperationClaimDrift,
    PublishedStateDrift,
}

impl G8lS571PendingError {
    pub const fn diagnostic_code(self) -> u64 {
        match self {
            Self::PredecessorRejected => 0x5711,
            Self::CandidateIdentityDrift => 0x5712,
            Self::ToolIdentityDrift => 0x5713,
            Self::EvidenceIdentityDrift => 0x5714,
            Self::ProbeIdentityDrift => 0x5715,
            Self::UartHolderPresent => 0x5716,
            Self::CardPresenceClaimDrift => 0x5717,
            Self::AuthorizationClaimDrift => 0x5718,
            Self::PowerAssertionClaimDrift => 0x5719,
            Self::DeviceOperationClaimDrift => 0x571a,
            Self::PublishedStateDrift => 0x571b,
        }
    }
}

fn identity_eq(left: G8lS571ArtifactIdentity, right: G8lS571ArtifactIdentity) -> bool {
    left == right
}

pub fn service_s571_model_pending_preflight(
    state: &mut G8lS571PendingState,
    observation: G8lS571ReadOnlyPreflightObservation<'_>,
) -> Result<G8lS571PendingOutcome, G8lS571PendingError> {
    if observation.predecessor_sequence != S571_EXPECTED_PREDECESSOR
        || !observation.predecessor_passed
    {
        return Err(G8lS571PendingError::PredecessorRejected);
    }
    if !identity_eq(
        observation.candidate,
        s571_identity(S571_CANDIDATE_IMAGE_BYTES, S571_CANDIDATE_IMAGE_SHA256),
    ) {
        return Err(G8lS571PendingError::CandidateIdentityDrift);
    }
    if !identity_eq(
        observation.flash_tool,
        s571_identity(S571_FLASH_TOOL_BYTES, S571_FLASH_TOOL_SHA256),
    ) || !identity_eq(
        observation.capture_wrapper,
        s571_identity(S571_CAPTURE_WRAPPER_BYTES, S571_CAPTURE_WRAPPER_SHA256),
    ) || !identity_eq(
        observation.capture_engine,
        s571_identity(S571_CAPTURE_ENGINE_BYTES, S571_CAPTURE_ENGINE_SHA256),
    ) {
        return Err(G8lS571PendingError::ToolIdentityDrift);
    }
    if !identity_eq(
        observation.preflight_log,
        s571_identity(S571_CARD_PREFLIGHT_BYTES, S571_CARD_PREFLIGHT_SHA256),
    ) || !identity_eq(
        observation.evidence_readme,
        s571_identity(S571_EVIDENCE_README_BYTES, S571_EVIDENCE_README_SHA256),
    ) {
        return Err(G8lS571PendingError::EvidenceIdentityDrift);
    }
    if observation.probe_present != S571_READ_ONLY_PROBE_PRESENT
        || observation.probe_serial != S571_EXPECTED_PROBE_SERIAL
        || observation.uart_callout != S571_EXPECTED_UART_CALLOUT
        || observation.uart_dialin != S571_EXPECTED_UART_DIALIN
    {
        return Err(G8lS571PendingError::ProbeIdentityDrift);
    }
    if observation.uart_holders != S571_READ_ONLY_UART_HOLDERS {
        return Err(G8lS571PendingError::UartHolderPresent);
    }
    if observation.external_physical_disks != S571_READ_ONLY_EXTERNAL_PHYSICAL_DISKS
        || observation.expected_card_present != S571_EXPECTED_CARD_PRESENT
    {
        return Err(G8lS571PendingError::CardPresenceClaimDrift);
    }
    if observation.authorization_token.is_some() || S571_PREFLIGHT_AUTHORIZATION_RECEIVED {
        return Err(G8lS571PendingError::AuthorizationClaimDrift);
    }
    if observation.pi_power_off_asserted != S571_PI_POWER_OFF_ASSERTION_RECEIVED {
        return Err(G8lS571PendingError::PowerAssertionClaimDrift);
    }
    if observation.physical_or_device_operations != S571_PREFLIGHT_PHYSICAL_OR_DEVICE_OPERATIONS {
        return Err(G8lS571PendingError::DeviceOperationClaimDrift);
    }

    let receipt = G8lS571PendingReceipt {
        sequence: S571_SEQUENCE,
        predecessor_sequence: observation.predecessor_sequence,
        status: S571_PREFLIGHT_GATE_STATUS,
        candidate: observation.candidate,
        probe_present: observation.probe_present,
        uart_holders: observation.uart_holders,
        external_physical_disks: observation.external_physical_disks,
        authorization_received: S571_PREFLIGHT_AUTHORIZATION_RECEIVED,
        pi_power_off_assertion_received: S571_PI_POWER_OFF_ASSERTION_RECEIVED,
        physical_or_device_operations: observation.physical_or_device_operations,
        runbook_executed: false,
    };
    match state.receipt {
        None => {
            state.receipt = Some(receipt);
            Ok(G8lS571PendingOutcome::PendingRecorded(receipt))
        }
        Some(existing) if existing == receipt => {
            Ok(G8lS571PendingOutcome::PendingRetained(existing))
        }
        Some(_) => Err(G8lS571PendingError::PublishedStateDrift),
    }
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct G8lS571MarkerCounts {
    pub boot8g: usize,
    pub boot8h: usize,
    pub required: usize,
    pub route: usize,
    pub handoff: usize,
    pub g8h_error: usize,
    pub s541_error: usize,
    pub s538_error: usize,
    pub panic: usize,
    pub unknown_irq: usize,
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum G8lS571PhysicalVerdict {
    Pending,
    Pass,
    RedG8hError,
    RedS541Error,
    RedS538Error,
    RedPanic,
    RedUnknownIrq,
    RedBoot8hAbsent,
    RedMarkerMatrix,
}

pub fn count_s571_substring(haystack: &[u8], needle: &[u8]) -> usize {
    if needle.is_empty() || haystack.len() < needle.len() {
        return 0;
    }
    haystack
        .windows(needle.len())
        .filter(|window| *window == needle)
        .count()
}

pub fn count_s571_markers(raw: &[u8]) -> G8lS571MarkerCounts {
    G8lS571MarkerCounts {
        boot8g: count_s571_substring(raw, S571_BOOT8G_MARKER.as_bytes()),
        boot8h: count_s571_substring(raw, S571_BOOT8H_MARKER.as_bytes()),
        required: count_s571_substring(raw, S571_REQUIRED_MARKER.as_bytes()),
        route: count_s571_substring(raw, S571_ROUTE_MARKER.as_bytes()),
        handoff: count_s571_substring(raw, S571_HANDOFF_MARKER.as_bytes()),
        g8h_error: count_s571_substring(raw, S571_G8H_ERROR_MARKER.as_bytes()),
        s541_error: count_s571_substring(raw, S571_S541_ERROR_MARKER.as_bytes()),
        s538_error: count_s571_substring(raw, S571_S538_ERROR_MARKER.as_bytes()),
        panic: count_s571_substring(raw, b"panic") + count_s571_substring(raw, b"PANIC"),
        unknown_irq: count_s571_substring(raw, b"unknown IRQ")
            + count_s571_substring(raw, "Bilinmeyen IRQ".as_bytes()),
    }
}

pub const fn classify_s571_counts(counts: G8lS571MarkerCounts) -> G8lS571PhysicalVerdict {
    if counts.panic != 0 {
        G8lS571PhysicalVerdict::RedPanic
    } else if counts.unknown_irq != 0 {
        G8lS571PhysicalVerdict::RedUnknownIrq
    } else if counts.g8h_error != 0 {
        G8lS571PhysicalVerdict::RedG8hError
    } else if counts.s541_error != 0 {
        G8lS571PhysicalVerdict::RedS541Error
    } else if counts.s538_error != 0 {
        G8lS571PhysicalVerdict::RedS538Error
    } else if counts.boot8h == 0 {
        G8lS571PhysicalVerdict::RedBoot8hAbsent
    } else if counts.boot8g == 1
        && counts.boot8h == 1
        && counts.required == 1
        && counts.route == 1
        && counts.handoff == 1
    {
        G8lS571PhysicalVerdict::Pass
    } else {
        G8lS571PhysicalVerdict::RedMarkerMatrix
    }
}

pub fn classify_s571_raw(raw: &[u8]) -> G8lS571PhysicalVerdict {
    classify_s571_counts(count_s571_markers(raw))
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct G8lS571PhysicalRunObservation<'a> {
    pub predecessor_sequence: usize,
    pub predecessor_passed: bool,
    pub candidate: G8lS571ArtifactIdentity,
    pub raw: G8lS571ArtifactIdentity,
    pub flash_log: G8lS571ArtifactIdentity,
    pub capture_build_log: G8lS571ArtifactIdentity,
    pub capture_log: G8lS571ArtifactIdentity,
    pub closeout_log: G8lS571ArtifactIdentity,
    pub evidence_manifest: G8lS571ArtifactIdentity,
    pub evidence_readme: G8lS571ArtifactIdentity,
    pub authorization_token: &'a str,
    pub pi_unpowered_before_write: bool,
    pub sd_write_transactions: usize,
    pub sd_writes: usize,
    pub sd_readbacks: usize,
    pub sd_ejects: usize,
    pub uart_opens: usize,
    pub capture_armed_before_power: bool,
    pub operator_power_on_reported: bool,
    pub operator_power_off_after_capture_reported: bool,
    pub power_transitions_operator_reported: usize,
    pub power_transitions_independently_observed: usize,
    pub capture_closed: bool,
    pub terminal_seen: bool,
    pub terminal_grace_complete: bool,
    pub capture_durable: bool,
    pub raw_mode_octal: &'a str,
    pub raw_link_count: usize,
    pub uart_holders_at_closeout: usize,
    pub disk_present_at_closeout: bool,
    pub runbook_executed: bool,
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct G8lS571PhysicalReceipt {
    pub sequence: usize,
    pub predecessor_sequence: usize,
    pub status: &'static str,
    pub candidate: G8lS571ArtifactIdentity,
    pub raw: G8lS571ArtifactIdentity,
    pub counts: G8lS571MarkerCounts,
    pub physical_observations: usize,
    pub power_transitions_operator_reported: usize,
    pub power_transitions_independently_observed: usize,
    pub boot_to_ui_marker_physically_observed: bool,
    pub visible_scanout_observed: bool,
    pub physical_input_observed: bool,
    pub r1_acceptance_complete: bool,
    pub runbook_executed: bool,
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct G8lS571PhysicalState {
    receipt: Option<G8lS571PhysicalReceipt>,
}

impl G8lS571PhysicalState {
    pub const fn new() -> Self {
        Self { receipt: None }
    }

    pub const fn receipt(&self) -> Option<G8lS571PhysicalReceipt> {
        self.receipt
    }
}

impl Default for G8lS571PhysicalState {
    fn default() -> Self {
        Self::new()
    }
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum G8lS571PhysicalOutcome {
    PassRecorded(G8lS571PhysicalReceipt),
    PassRetained(G8lS571PhysicalReceipt),
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum G8lS571PhysicalError {
    PredecessorRejected,
    CandidateIdentityDrift,
    EvidenceIdentityDrift,
    AuthorizationRejected,
    DeviceOperationDrift,
    PowerAttestationDrift,
    CaptureContractDrift,
    RawIdentityDrift,
    RawClassifierRejected,
    CloseoutDrift,
    PublishedStateDrift,
}

impl G8lS571PhysicalError {
    pub const fn diagnostic_code(self) -> u64 {
        match self {
            Self::PredecessorRejected => 0x571c,
            Self::CandidateIdentityDrift => 0x571d,
            Self::EvidenceIdentityDrift => 0x571e,
            Self::AuthorizationRejected => 0x571f,
            Self::DeviceOperationDrift => 0x5720,
            Self::PowerAttestationDrift => 0x5721,
            Self::CaptureContractDrift => 0x5722,
            Self::RawIdentityDrift => 0x5723,
            Self::RawClassifierRejected => 0x5724,
            Self::CloseoutDrift => 0x5725,
            Self::PublishedStateDrift => 0x5726,
        }
    }
}

pub fn service_s571_model_physical_run(
    state: &mut G8lS571PhysicalState,
    observation: G8lS571PhysicalRunObservation<'_>,
    raw: &[u8],
) -> Result<G8lS571PhysicalOutcome, G8lS571PhysicalError> {
    if observation.predecessor_sequence != S571_EXPECTED_PREDECESSOR
        || !observation.predecessor_passed
    {
        return Err(G8lS571PhysicalError::PredecessorRejected);
    }
    if !identity_eq(
        observation.candidate,
        s571_identity(S571_CANDIDATE_IMAGE_BYTES, S571_CANDIDATE_IMAGE_SHA256),
    ) {
        return Err(G8lS571PhysicalError::CandidateIdentityDrift);
    }
    if !identity_eq(
        observation.flash_log,
        s571_identity(S571_FLASH_LOG_BYTES, S571_FLASH_LOG_SHA256),
    ) || !identity_eq(
        observation.capture_build_log,
        s571_identity(S571_CAPTURE_BUILD_LOG_BYTES, S571_CAPTURE_BUILD_LOG_SHA256),
    ) || !identity_eq(
        observation.capture_log,
        s571_identity(S571_CAPTURE_LOG_BYTES, S571_CAPTURE_LOG_SHA256),
    ) || !identity_eq(
        observation.closeout_log,
        s571_identity(S571_CLOSEOUT_LOG_BYTES, S571_CLOSEOUT_LOG_SHA256),
    ) || !identity_eq(
        observation.evidence_manifest,
        s571_identity(S571_EVIDENCE_MANIFEST_BYTES, S571_EVIDENCE_MANIFEST_SHA256),
    ) || !identity_eq(
        observation.evidence_readme,
        s571_identity(S571_EVIDENCE_README_BYTES, S571_EVIDENCE_README_SHA256),
    ) {
        return Err(G8lS571PhysicalError::EvidenceIdentityDrift);
    }
    if !S571_AUTHORIZATION_RECEIVED
        || observation.authorization_token != S571_AUTHORIZATION_TOKEN
        || !observation.pi_unpowered_before_write
    {
        return Err(G8lS571PhysicalError::AuthorizationRejected);
    }
    if observation.sd_write_transactions != S571_SD_WRITE_TRANSACTIONS
        || observation.sd_writes != S571_SD_WRITES
        || observation.sd_readbacks != S571_SD_READBACKS
        || observation.sd_ejects != S571_SD_EJECTS
        || observation.uart_opens != S571_UART_OPENS
        || !observation.runbook_executed
    {
        return Err(G8lS571PhysicalError::DeviceOperationDrift);
    }
    if !observation.operator_power_on_reported
        || !observation.operator_power_off_after_capture_reported
        || observation.power_transitions_operator_reported
            != S571_POWER_TRANSITIONS_OPERATOR_REPORTED
        || observation.power_transitions_independently_observed
            != S571_POWER_TRANSITIONS_INDEPENDENTLY_OBSERVED
    {
        return Err(G8lS571PhysicalError::PowerAttestationDrift);
    }
    if !observation.capture_armed_before_power
        || !observation.capture_closed
        || !observation.terminal_seen
        || !observation.terminal_grace_complete
        || !observation.capture_durable
    {
        return Err(G8lS571PhysicalError::CaptureContractDrift);
    }
    if raw.len() as u64 != S571_RAW_BYTES
        || !identity_eq(
            observation.raw,
            s571_identity(S571_RAW_BYTES, S571_RAW_SHA256),
        )
        || observation.raw_mode_octal != S571_RAW_MODE_OCTAL
        || observation.raw_link_count != S571_RAW_LINK_COUNT
    {
        return Err(G8lS571PhysicalError::RawIdentityDrift);
    }
    let counts = count_s571_markers(raw);
    if classify_s571_counts(counts) != G8lS571PhysicalVerdict::Pass {
        return Err(G8lS571PhysicalError::RawClassifierRejected);
    }
    if observation.uart_holders_at_closeout != S571_UART_HOLDERS_AT_CLOSEOUT
        || observation.disk_present_at_closeout != S571_DISK_PRESENT_AT_CLOSEOUT
    {
        return Err(G8lS571PhysicalError::CloseoutDrift);
    }

    let receipt = G8lS571PhysicalReceipt {
        sequence: S571_SEQUENCE,
        predecessor_sequence: observation.predecessor_sequence,
        status: S571_PHYSICAL_GATE_STATUS,
        candidate: observation.candidate,
        raw: observation.raw,
        counts,
        physical_observations: S571_PHYSICAL_OBSERVATIONS,
        power_transitions_operator_reported: observation.power_transitions_operator_reported,
        power_transitions_independently_observed: observation
            .power_transitions_independently_observed,
        boot_to_ui_marker_physically_observed: S571_BOOT_TO_UI_PHYSICALLY_OBSERVED,
        visible_scanout_observed: S571_VISIBLE_SCANOUT_OBSERVED,
        physical_input_observed: S571_PHYSICAL_INPUT_OBSERVED,
        r1_acceptance_complete: S571_R1_ACCEPTANCE_COMPLETE,
        runbook_executed: RUNBOOK_EXECUTED_IN_S571,
    };
    match state.receipt {
        None => {
            state.receipt = Some(receipt);
            Ok(G8lS571PhysicalOutcome::PassRecorded(receipt))
        }
        Some(existing) if existing == receipt => Ok(G8lS571PhysicalOutcome::PassRetained(existing)),
        Some(_) => Err(G8lS571PhysicalError::PublishedStateDrift),
    }
}
snippet sha256: e62d4956968afile sha256: e62d4956968a
02 · Doğrulayan test kodu

Operations komutuna bağlı focused test

tam dosyaL1–L700
simulation/tests/g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s571_r1_frozen_manifest_physical_boot_uart_run.rs::S571 r1 frozen manifest physical boot uart run focused tests
use aselsan_microkernel_simulation::g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s571_r1_frozen_manifest_physical_boot_uart_run::*;
use sha2::{Digest, Sha256};
use std::collections::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_s571_r1_frozen_manifest_physical_boot_uart_run.rs"
);
const MAIN: &str = include_str!("../../kernel/src/main.rs");
const SIMULATION_LIB: &str = include_str!("../src/lib.rs");
const FLASH_TOOL: &[u8] = include_bytes!("../../scripts/flash-rpi5-s571-r1-candidate.sh");
const CAPTURE_WRAPPER: &[u8] = include_bytes!("../../scripts/capture-rpi5-s571-r1-uart.c");
const CAPTURE_ENGINE: &[u8] = include_bytes!("../../scripts/capture-rpi5-s540-r1-uart.c");
const INITIAL_PREFLIGHT_LOG: &[u8] = include_bytes!(
    "../../evidence/rpi5/r1/sequence-571-physical-boot-uart/s571-read-only-preflight.log"
);
const CARD_PREFLIGHT_LOG: &[u8] = include_bytes!(
    "../../evidence/rpi5/r1/sequence-571-physical-boot-uart/s571-card-preflight.log"
);
const FLASH_LOG: &[u8] =
    include_bytes!("../../evidence/rpi5/r1/sequence-571-physical-boot-uart/s571-flash.log");
const CAPTURE_BUILD_LOG: &[u8] =
    include_bytes!("../../evidence/rpi5/r1/sequence-571-physical-boot-uart/s571-capture-build.log");
const CAPTURE_LOG: &[u8] =
    include_bytes!("../../evidence/rpi5/r1/sequence-571-physical-boot-uart/s571-capture.log");
const CLOSEOUT_LOG: &[u8] =
    include_bytes!("../../evidence/rpi5/r1/sequence-571-physical-boot-uart/s571-run-closeout.log");
const EVIDENCE_MANIFEST: &[u8] =
    include_bytes!("../../evidence/rpi5/r1/sequence-571-physical-boot-uart/EVIDENCE_SHA256SUMS");
const EVIDENCE_README: &[u8] =
    include_bytes!("../../evidence/rpi5/r1/sequence-571-physical-boot-uart/README.md");
const PHYSICAL_RAW: &[u8] =
    include_bytes!("../../evidence/rpi5/r1/sequence-571-physical-boot-uart/s571-uart.raw");
const PACKAGE_IMAGE: &[u8] = include_bytes!(
    "../../evidence/rpi5/r1/sequence-570-candidate-freeze/package/aselsanos-rpi5.img"
);

fn sha256(bytes: &[u8]) -> String {
    format!("{:x}", Sha256::digest(bytes))
}

fn repository_root() -> PathBuf {
    Path::new(env!("CARGO_MANIFEST_DIR")).join("..")
}

fn observation() -> G8lS571ReadOnlyPreflightObservation<'static> {
    G8lS571ReadOnlyPreflightObservation {
        predecessor_sequence: 570,
        predecessor_passed: true,
        candidate: s571_identity(S571_CANDIDATE_IMAGE_BYTES, S571_CANDIDATE_IMAGE_SHA256),
        flash_tool: s571_identity(S571_FLASH_TOOL_BYTES, S571_FLASH_TOOL_SHA256),
        capture_wrapper: s571_identity(S571_CAPTURE_WRAPPER_BYTES, S571_CAPTURE_WRAPPER_SHA256),
        capture_engine: s571_identity(S571_CAPTURE_ENGINE_BYTES, S571_CAPTURE_ENGINE_SHA256),
        preflight_log: s571_identity(S571_CARD_PREFLIGHT_BYTES, S571_CARD_PREFLIGHT_SHA256),
        evidence_readme: s571_identity(S571_EVIDENCE_README_BYTES, S571_EVIDENCE_README_SHA256),
        probe_present: true,
        probe_serial: S571_EXPECTED_PROBE_SERIAL,
        uart_callout: S571_EXPECTED_UART_CALLOUT,
        uart_dialin: S571_EXPECTED_UART_DIALIN,
        uart_holders: 0,
        external_physical_disks: 0,
        expected_card_present: true,
        authorization_token: None,
        pi_power_off_asserted: true,
        physical_or_device_operations: 0,
    }
}

fn pass_raw() -> Vec<u8> {
    [
        S571_BOOT8G_MARKER,
        S571_BOOT8H_MARKER,
        S571_HANDOFF_MARKER,
        S571_ROUTE_MARKER,
        S571_REQUIRED_MARKER,
    ]
    .join("\r\n")
    .into_bytes()
}

fn physical_observation() -> G8lS571PhysicalRunObservation<'static> {
    G8lS571PhysicalRunObservation {
        predecessor_sequence: 570,
        predecessor_passed: true,
        candidate: s571_identity(S571_CANDIDATE_IMAGE_BYTES, S571_CANDIDATE_IMAGE_SHA256),
        raw: s571_identity(S571_RAW_BYTES, S571_RAW_SHA256),
        flash_log: s571_identity(S571_FLASH_LOG_BYTES, S571_FLASH_LOG_SHA256),
        capture_build_log: s571_identity(
            S571_CAPTURE_BUILD_LOG_BYTES,
            S571_CAPTURE_BUILD_LOG_SHA256,
        ),
        capture_log: s571_identity(S571_CAPTURE_LOG_BYTES, S571_CAPTURE_LOG_SHA256),
        closeout_log: s571_identity(S571_CLOSEOUT_LOG_BYTES, S571_CLOSEOUT_LOG_SHA256),
        evidence_manifest: s571_identity(
            S571_EVIDENCE_MANIFEST_BYTES,
            S571_EVIDENCE_MANIFEST_SHA256,
        ),
        evidence_readme: s571_identity(S571_EVIDENCE_README_BYTES, S571_EVIDENCE_README_SHA256),
        authorization_token: S571_AUTHORIZATION_TOKEN,
        pi_unpowered_before_write: true,
        sd_write_transactions: 1,
        sd_writes: 4,
        sd_readbacks: 4,
        sd_ejects: 1,
        uart_opens: 1,
        capture_armed_before_power: true,
        operator_power_on_reported: true,
        operator_power_off_after_capture_reported: true,
        power_transitions_operator_reported: 2,
        power_transitions_independently_observed: 0,
        capture_closed: true,
        terminal_seen: true,
        terminal_grace_complete: true,
        capture_durable: true,
        raw_mode_octal: "0444",
        raw_link_count: 1,
        uart_holders_at_closeout: 0,
        disk_present_at_closeout: false,
        runbook_executed: true,
    }
}

#[test]
fn sequence_status_and_recorded_physical_operation_claims_are_exact() {
    assert_eq!(S571_SEQUENCE, 571);
    assert_eq!(S571_EXPECTED_PREDECESSOR, 570);
    assert_eq!(S571_R1_STAGE, 1);
    assert_eq!(S571_PHYSICAL_GATE_STATUS, "PASS");
    assert_eq!(S571_PREFLIGHT_GATE_STATUS, "PENDING_OPERATOR_AUTHORIZATION");
    assert_eq!(S571_SUPPORTED_PROFILE_RUNTIME_OBSERVATIONS, 1);
    assert_eq!(S571_PHYSICAL_OBSERVATIONS, 1);
    assert_eq!(S571_PHYSICAL_OR_DEVICE_OPERATIONS, 1);
    assert_eq!(S571_PREFLIGHT_PHYSICAL_OR_DEVICE_OPERATIONS, 0);
    assert_eq!(S571_SD_WRITE_TRANSACTIONS, 1);
    assert_eq!(S571_SD_WRITES, 4);
    assert_eq!(S571_SD_READBACKS, 4);
    assert_eq!(S571_SD_EJECTS, 1);
    assert_eq!(S571_UART_OPENS, 1);
    assert_eq!(S571_POWER_TRANSITIONS, 2);
    assert_eq!(S571_POWER_TRANSITIONS_OPERATOR_REPORTED, 2);
    assert_eq!(S571_POWER_TRANSITIONS_INDEPENDENTLY_OBSERVED, 0);
    assert_eq!(S571_NEW_IMMUTABLE_RAW_CAPTURES, 1);
    assert!(S571_HARDWARE_PRESENT);
    assert!(S571_BOOT_TO_UI_PHYSICALLY_OBSERVED);
    assert!(!S571_R1_ACCEPTANCE_COMPLETE);
    assert!(!S571_AUTOMATIC_PROMOTION);
    assert!(S571_EXPECTED_CARD_PRESENT);
    assert!(!S571_PREFLIGHT_AUTHORIZATION_RECEIVED);
    assert!(S571_AUTHORIZATION_RECEIVED);
    assert!(S571_PI_POWER_OFF_ASSERTION_RECEIVED);
    assert!(S571_OPERATOR_POWER_ON_REPORTED);
    assert!(S571_OPERATOR_POWER_OFF_AFTER_CAPTURE_REPORTED);
    assert!(S571_CAPTURE_ARMED_BEFORE_POWER);
    assert!(S571_CAPTURE_CLOSED);
    assert!(S571_CAPTURE_TERMINAL_SEEN);
    assert!(S571_CAPTURE_GRACE_COMPLETE);
    assert!(S571_CAPTURE_DURABLE);
    assert!(!S571_VISIBLE_SCANOUT_OBSERVED);
    assert!(!S571_PHYSICAL_INPUT_OBSERVED);
    assert!(RUNBOOK_EXECUTED_IN_S571);
}

#[test]
fn host_model_is_simulation_only_and_cannot_execute_the_runbook() {
    let module = "g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s571_r1_frozen_manifest_physical_boot_uart_run";
    assert!(!MAIN.contains(module));
    assert_eq!(
        SIMULATION_LIB
            .matches(&format!("pub mod {module};"))
            .count(),
        1
    );
    for forbidden in [
        "unsafe {",
        "asm!(",
        "global_asm!(",
        "kprintln!(",
        "std::process",
        "diskutil",
        "TIOCEXCL",
        "tcsetattr",
    ] {
        assert!(!SOURCE.contains(forbidden), "{forbidden}");
    }
}

#[test]
fn pending_diagnostic_codes_are_unique_and_nonzero() {
    let errors = [
        G8lS571PendingError::PredecessorRejected,
        G8lS571PendingError::CandidateIdentityDrift,
        G8lS571PendingError::ToolIdentityDrift,
        G8lS571PendingError::EvidenceIdentityDrift,
        G8lS571PendingError::ProbeIdentityDrift,
        G8lS571PendingError::UartHolderPresent,
        G8lS571PendingError::CardPresenceClaimDrift,
        G8lS571PendingError::AuthorizationClaimDrift,
        G8lS571PendingError::PowerAssertionClaimDrift,
        G8lS571PendingError::DeviceOperationClaimDrift,
        G8lS571PendingError::PublishedStateDrift,
    ];
    let mut unique = HashSet::new();
    for code in errors.into_iter().map(G8lS571PendingError::diagnostic_code) {
        assert_ne!(code, 0);
        assert!(unique.insert(code));
    }
    assert_eq!(unique.len(), 11);
}

#[test]
fn exact_read_only_observation_records_pending_receipt() {
    let mut state = G8lS571PendingState::new();
    let G8lS571PendingOutcome::PendingRecorded(receipt) =
        service_s571_model_pending_preflight(&mut state, observation()).unwrap()
    else {
        panic!("first exact observation must record pending")
    };
    assert_eq!(receipt.sequence, 571);
    assert_eq!(receipt.predecessor_sequence, 570);
    assert_eq!(receipt.status, "PENDING_OPERATOR_AUTHORIZATION");
    assert!(receipt.probe_present);
    assert_eq!(receipt.uart_holders, 0);
    assert_eq!(receipt.external_physical_disks, 0);
    assert!(!receipt.authorization_received);
    assert!(receipt.pi_power_off_assertion_received);
    assert_eq!(receipt.physical_or_device_operations, 0);
    assert!(!receipt.runbook_executed);
    assert_eq!(state.receipt(), Some(receipt));
}

#[test]
fn exact_replay_retains_and_state_divergence_fails_closed() {
    let mut state = G8lS571PendingState::new();
    let G8lS571PendingOutcome::PendingRecorded(receipt) =
        service_s571_model_pending_preflight(&mut state, observation()).unwrap()
    else {
        panic!("first receipt")
    };
    assert_eq!(
        service_s571_model_pending_preflight(&mut state, observation()),
        Ok(G8lS571PendingOutcome::PendingRetained(receipt))
    );
}

#[test]
fn identity_drift_fails_before_pending_publication() {
    let cases = [
        (0usize, G8lS571PendingError::PredecessorRejected),
        (1, G8lS571PendingError::CandidateIdentityDrift),
        (2, G8lS571PendingError::ToolIdentityDrift),
        (3, G8lS571PendingError::EvidenceIdentityDrift),
    ];
    for (case, expected) in cases {
        let mut observed = observation();
        match case {
            0 => observed.predecessor_passed = false,
            1 => observed.candidate.bytes += 1,
            2 => observed.flash_tool.sha256 = S571_CAPTURE_WRAPPER_SHA256,
            3 => observed.preflight_log.bytes += 1,
            _ => unreachable!(),
        }
        let mut state = G8lS571PendingState::new();
        assert_eq!(
            service_s571_model_pending_preflight(&mut state, observed),
            Err(expected)
        );
        assert_eq!(state.receipt(), None);
    }
}

#[test]
fn environment_authority_and_operation_claim_drift_fail_closed() {
    let cases = [
        (0usize, G8lS571PendingError::ProbeIdentityDrift),
        (1, G8lS571PendingError::UartHolderPresent),
        (2, G8lS571PendingError::CardPresenceClaimDrift),
        (3, G8lS571PendingError::AuthorizationClaimDrift),
        (4, G8lS571PendingError::PowerAssertionClaimDrift),
        (5, G8lS571PendingError::DeviceOperationClaimDrift),
    ];
    for (case, expected) in cases {
        let mut observed = observation();
        match case {
            0 => observed.probe_serial = "WRONG",
            1 => observed.uart_holders = 1,
            2 => observed.expected_card_present = false,
            3 => observed.authorization_token = Some(S571_AUTHORIZATION_TOKEN),
            4 => observed.pi_power_off_asserted = false,
            5 => observed.physical_or_device_operations = 1,
            _ => unreachable!(),
        }
        let mut state = G8lS571PendingState::new();
        assert_eq!(
            service_s571_model_pending_preflight(&mut state, observed),
            Err(expected)
        );
    }
}

#[test]
fn preflight_and_final_evidence_files_are_byte_exact_and_immutable() {
    for (bytes, expected_len, expected_sha) in [
        (
            INITIAL_PREFLIGHT_LOG,
            S571_INITIAL_NO_CARD_PREFLIGHT_BYTES,
            S571_INITIAL_NO_CARD_PREFLIGHT_SHA256,
        ),
        (
            CARD_PREFLIGHT_LOG,
            S571_CARD_PREFLIGHT_BYTES,
            S571_CARD_PREFLIGHT_SHA256,
        ),
        (
            EVIDENCE_README,
            S571_EVIDENCE_README_BYTES,
            S571_EVIDENCE_README_SHA256,
        ),
        (FLASH_LOG, S571_FLASH_LOG_BYTES, S571_FLASH_LOG_SHA256),
        (
            CAPTURE_BUILD_LOG,
            S571_CAPTURE_BUILD_LOG_BYTES,
            S571_CAPTURE_BUILD_LOG_SHA256,
        ),
        (CAPTURE_LOG, S571_CAPTURE_LOG_BYTES, S571_CAPTURE_LOG_SHA256),
        (
            CLOSEOUT_LOG,
            S571_CLOSEOUT_LOG_BYTES,
            S571_CLOSEOUT_LOG_SHA256,
        ),
        (
            EVIDENCE_MANIFEST,
            S571_EVIDENCE_MANIFEST_BYTES,
            S571_EVIDENCE_MANIFEST_SHA256,
        ),
        (PHYSICAL_RAW, S571_RAW_BYTES, S571_RAW_SHA256),
    ] {
        assert_eq!(bytes.len() as u64, expected_len);
        assert_eq!(sha256(bytes), expected_sha);
    }
    for name in [
        "s571-read-only-preflight.log",
        "s571-card-preflight.log",
        "s571-flash.log",
        "s571-capture-build.log",
        "s571-capture.log",
        "s571-run-closeout.log",
        "EVIDENCE_SHA256SUMS",
        "s571-uart.raw",
    ] {
        let path = repository_root()
            .join("evidence/rpi5/r1/sequence-571-physical-boot-uart")
            .join(name);
        let metadata = fs::symlink_metadata(path).unwrap();
        assert!(metadata.is_file());
        assert_eq!(metadata.permissions().mode() & 0o777, 0o444);
        assert_eq!(metadata.nlink(), 1);
    }
    let log = std::str::from_utf8(CARD_PREFLIGHT_LOG).unwrap();
    for required in [
        "CHECK=READ_ONLY_CARD_PREFLIGHT",
        "RESULT=PASS",
        "DEVICE=/dev/disk6",
        "CARD_SERIAL_HEX=0x425001fa",
        "PREDECESSOR=S545",
        "DEBUG_PROBE_PRESENT=YES",
        "UART_HOLDERS=0",
        "DISKUTIL_EXTERNAL_PHYSICAL_COUNT=0",
        "AUTHORIZATION_RECEIVED=NO",
        "PI_POWER_OFF_ASSERTION_RECEIVED=YES",
        "SD_WRITE_TRANSACTIONS=0",
        "RUNBOOK_EXECUTED_IN_S571=NO",
    ] {
        assert!(log.contains(required), "{required}");
    }
    let closeout = std::str::from_utf8(CLOSEOUT_LOG).unwrap();
    for required in [
        "S571_PHYSICAL_CLOSEOUT=PASS",
        "AUTHORIZATION_RECEIVED=YES",
        "SD_WRITE_TRANSACTIONS=1",
        "SD_FILE_WRITES=4",
        "SD_BYTE_EXACT_READBACKS=4",
        "SD_EJECTS=1",
        "UART_OPENS=1",
        "UART_CAPTURE_ARMED_BEFORE_POWER=YES",
        "POWER_TRANSITIONS_OPERATOR_REPORTED=2",
        "POWER_TRANSITIONS_INDEPENDENTLY_OBSERVED=0",
        "RAW_BYTES=20947",
        "BOOT8H_COUNT=1",
        "BOOT_TO_UI_READY_COUNT=1",
        "PHYSICAL_GATE_VERDICT=PASS",
        "R1_OVERALL_ACCEPTANCE_COMPLETE=NO",
    ] {
        assert!(closeout.contains(required), "{required}");
    }
    let manifest = std::str::from_utf8(EVIDENCE_MANIFEST).unwrap();
    assert_eq!(manifest.lines().count(), 7);
    for name in [
        "s571-read-only-preflight.log",
        "s571-card-preflight.log",
        "s571-flash.log",
        "s571-capture-build.log",
        "s571-capture.log",
        "s571-run-closeout.log",
        "s571-uart.raw",
    ] {
        assert_eq!(manifest.matches(name).count(), 1, "{name}");
    }
}

#[test]
fn flash_and_capture_tools_are_exact_and_candidate_bound() {
    for (bytes, expected_len, expected_sha) in [
        (FLASH_TOOL, S571_FLASH_TOOL_BYTES, S571_FLASH_TOOL_SHA256),
        (
            CAPTURE_WRAPPER,
            S571_CAPTURE_WRAPPER_BYTES,
            S571_CAPTURE_WRAPPER_SHA256,
        ),
        (
            CAPTURE_ENGINE,
            S571_CAPTURE_ENGINE_BYTES,
            S571_CAPTURE_ENGINE_SHA256,
        ),
    ] {
        assert_eq!(bytes.len() as u64, expected_len);
        assert_eq!(sha256(bytes), expected_sha);
    }
    let flash = std::str::from_utf8(FLASH_TOOL).unwrap();
    for required in [
        "EXPECTED_IMAGE_BYTES=945920",
        "EXPECTED_IMAGE_SHA256=a24f4d24e838cd7d1a6b2ff217d864e9c4b08f12ce7dd165b302e8073a980b04",
        "PREDECESSOR_IMAGE_BYTES=945760",
        "PREDECESSOR_IMAGE_SHA256=ed1901a991e2f9e9ae3c16f254147a2b0180686a8d70ca5d7353374fee08d467",
        "EXPECTED_CARD_SERIAL_HEX=0x425001fa",
        "EXPECTED_DISK_BYTES=62549655552",
        "EXPECTED_PI_ASSERTION=S571_PI_UNPOWERED_ASSERTED",
        S571_AUTHORIZATION_TOKEN,
        "S571_SOURCE_CHECK=PASS",
        "PREFLIGHT=PASS SEQUENCE=S571",
        "RERUN_FORBIDDEN=YES",
    ] {
        assert!(flash.contains(required), "{required}");
    }
    assert!(
        flash.find("if [ \"${1:-}\" = --preflight ]").unwrap()
            < flash.find("[ \"$AUTH\" = \"$EXPECTED_AUTH\" ]").unwrap(),
        "read-only preflight must be reachable before authorization parsing"
    );
    let wrapper = std::str::from_utf8(CAPTURE_WRAPPER).unwrap();
    assert_eq!(wrapper.matches("capture-rpi5-s540-r1-uart.c").count(), 1);
    let engine = std::str::from_utf8(CAPTURE_ENGINE).unwrap();
    for required in [
        "TIOCEXCL",
        "B115200",
        "TCIFLUSH",
        "O_CREAT | O_EXCL",
        "TERMINAL_GRACE_SECONDS 3.0",
        "fchmod(output_fd, 0444)",
    ] {
        assert!(engine.contains(required), "{required}");
    }
}

#[test]
fn frozen_candidate_image_is_exact_and_bound_to_one_physical_observation() {
    assert_eq!(PACKAGE_IMAGE.len() as u64, S571_CANDIDATE_IMAGE_BYTES);
    assert_eq!(sha256(PACKAGE_IMAGE), S571_CANDIDATE_IMAGE_SHA256);
    assert_eq!(
        count_s571_substring(PACKAGE_IMAGE, S571_G8H_ERROR_MARKER.as_bytes()),
        1
    );
    assert_eq!(S571_PHYSICAL_OBSERVATIONS, 1);
    assert!(S571_HARDWARE_PRESENT);
}

#[test]
fn synthetic_exact_marker_matrix_is_the_only_pass_shape() {
    let raw = pass_raw();
    let counts = count_s571_markers(&raw);
    assert_eq!(counts.boot8g, 1);
    assert_eq!(counts.boot8h, 1);
    assert_eq!(counts.required, 1);
    assert_eq!(counts.route, 1);
    assert_eq!(counts.handoff, 1);
    assert_eq!(counts.g8h_error, 0);
    assert_eq!(classify_s571_counts(counts), G8lS571PhysicalVerdict::Pass);
    assert_eq!(classify_s571_raw(&raw), G8lS571PhysicalVerdict::Pass);
    let mut duplicate = raw;
    duplicate.extend_from_slice(S571_REQUIRED_MARKER.as_bytes());
    assert_eq!(
        classify_s571_raw(&duplicate),
        G8lS571PhysicalVerdict::RedMarkerMatrix
    );
}

#[test]
fn error_classifier_is_fail_closed_with_explicit_precedence() {
    for (suffix, expected) in [
        ("PANIC", G8lS571PhysicalVerdict::RedPanic),
        ("unknown IRQ", G8lS571PhysicalVerdict::RedUnknownIrq),
        (S571_G8H_ERROR_MARKER, G8lS571PhysicalVerdict::RedG8hError),
        (S571_S541_ERROR_MARKER, G8lS571PhysicalVerdict::RedS541Error),
        (S571_S538_ERROR_MARKER, G8lS571PhysicalVerdict::RedS538Error),
    ] {
        let raw = format!("{}\n{suffix}", String::from_utf8(pass_raw()).unwrap());
        assert_eq!(classify_s571_raw(raw.as_bytes()), expected);
    }
    assert_eq!(
        classify_s571_raw(S571_BOOT8G_MARKER.as_bytes()),
        G8lS571PhysicalVerdict::RedBoot8hAbsent
    );
}

#[test]
fn immutable_s546_red_remains_exact_and_unpromoted() {
    let raw = fs::read(
        repository_root().join("evidence/rpi5/r1/sequence-546-physical-boot-uart/s546-uart.raw"),
    )
    .unwrap();
    assert_eq!(raw.len() as u64, S571_S546_RAW_BYTES);
    assert_eq!(sha256(&raw), S571_S546_RAW_SHA256);
    assert_eq!(count_s571_substring(&raw, S571_BOOT8H_MARKER.as_bytes()), 0);
    assert_eq!(
        count_s571_substring(&raw, S571_G8H_ERROR_MARKER.as_bytes()),
        0
    );
    assert!(S571_S546_RETAINED_RED);
    assert!(!S571_AUTOMATIC_PROMOTION);
}

#[test]
fn immutable_s571_raw_is_exact_and_classifies_physical_pass() {
    assert_eq!(PHYSICAL_RAW.len() as u64, S571_RAW_BYTES);
    assert_eq!(sha256(PHYSICAL_RAW), S571_RAW_SHA256);
    let raw_path =
        repository_root().join("evidence/rpi5/r1/sequence-571-physical-boot-uart/s571-uart.raw");
    let metadata = fs::symlink_metadata(raw_path).unwrap();
    assert!(metadata.is_file());
    assert_eq!(metadata.permissions().mode() & 0o777, 0o444);
    assert_eq!(metadata.nlink(), 1);

    let counts = count_s571_markers(PHYSICAL_RAW);
    assert_eq!(counts.boot8g, 1);
    assert_eq!(counts.boot8h, 1);
    assert_eq!(counts.required, 1);
    assert_eq!(counts.route, 1);
    assert_eq!(counts.handoff, 1);
    assert_eq!(counts.g8h_error, 0);
    assert_eq!(counts.s541_error, 0);
    assert_eq!(counts.s538_error, 0);
    assert_eq!(counts.panic, 0);
    assert_eq!(counts.unknown_irq, 0);
    assert_eq!(
        classify_s571_raw(PHYSICAL_RAW),
        G8lS571PhysicalVerdict::Pass
    );
    assert_eq!(
        count_s571_substring(PHYSICAL_RAW, S571_EXPECTED_CARD_RAW_CID.as_bytes()),
        S571_CARD_RAW_CID_UART_COUNT
    );
    assert_eq!(
        count_s571_substring(PHYSICAL_RAW, b"SCANOUT=NOT_OBSERVED"),
        1
    );
    assert_eq!(count_s571_substring(PHYSICAL_RAW, b"INPUT=NOT_OBSERVED"), 1);
    assert_eq!(
        PHYSICAL_RAW.iter().filter(|byte| **byte == 0).count(),
        S571_RAW_NUL_BYTES
    );
    assert_eq!(
        PHYSICAL_RAW.iter().filter(|byte| **byte == b'\r').count(),
        S571_RAW_CR_BYTES
    );
    assert_eq!(
        PHYSICAL_RAW.iter().filter(|byte| **byte == b'\n').count(),
        S571_RAW_LF_BYTES
    );
}

#[test]
fn exact_physical_observation_records_and_replays_pass_receipt() {
    let mut state = G8lS571PhysicalState::new();
    let G8lS571PhysicalOutcome::PassRecorded(receipt) =
        service_s571_model_physical_run(&mut state, physical_observation(), PHYSICAL_RAW).unwrap()
    else {
        panic!("first exact physical observation must record PASS")
    };
    assert_eq!(receipt.sequence, 571);
    assert_eq!(receipt.predecessor_sequence, 570);
    assert_eq!(receipt.status, "PASS");
    assert_eq!(receipt.raw, s571_identity(S571_RAW_BYTES, S571_RAW_SHA256));
    assert_eq!(receipt.physical_observations, 1);
    assert!(receipt.boot_to_ui_marker_physically_observed);
    assert!(!receipt.visible_scanout_observed);
    assert!(!receipt.physical_input_observed);
    assert!(!receipt.r1_acceptance_complete);
    assert!(receipt.runbook_executed);
    assert_eq!(state.receipt(), Some(receipt));
    assert_eq!(
        service_s571_model_physical_run(&mut state, physical_observation(), PHYSICAL_RAW),
        Ok(G8lS571PhysicalOutcome::PassRetained(receipt))
    );
}

#[test]
fn physical_diagnostic_codes_are_unique_nonzero_and_disjoint_from_preflight() {
    let pending = [
        G8lS571PendingError::PredecessorRejected,
        G8lS571PendingError::CandidateIdentityDrift,
        G8lS571PendingError::ToolIdentityDrift,
        G8lS571PendingError::EvidenceIdentityDrift,
        G8lS571PendingError::ProbeIdentityDrift,
        G8lS571PendingError::UartHolderPresent,
        G8lS571PendingError::CardPresenceClaimDrift,
        G8lS571PendingError::AuthorizationClaimDrift,
        G8lS571PendingError::PowerAssertionClaimDrift,
        G8lS571PendingError::DeviceOperationClaimDrift,
        G8lS571PendingError::PublishedStateDrift,
    ];
    let physical = [
        G8lS571PhysicalError::PredecessorRejected,
        G8lS571PhysicalError::CandidateIdentityDrift,
        G8lS571PhysicalError::EvidenceIdentityDrift,
        G8lS571PhysicalError::AuthorizationRejected,
        G8lS571PhysicalError::DeviceOperationDrift,
        G8lS571PhysicalError::PowerAttestationDrift,
        G8lS571PhysicalError::CaptureContractDrift,
        G8lS571PhysicalError::RawIdentityDrift,
        G8lS571PhysicalError::RawClassifierRejected,
        G8lS571PhysicalError::CloseoutDrift,
        G8lS571PhysicalError::PublishedStateDrift,
    ];
    let mut unique = HashSet::new();
    for code in pending
        .into_iter()
        .map(G8lS571PendingError::diagnostic_code)
        .chain(
            physical
                .into_iter()
                .map(G8lS571PhysicalError::diagnostic_code),
        )
    {
        assert_ne!(code, 0);
        assert!(unique.insert(code));
    }
    assert_eq!(unique.len(), 22);
}

#[test]
fn physical_authority_operation_capture_raw_and_closeout_drift_fail_closed() {
    let cases = [
        (0usize, G8lS571PhysicalError::AuthorizationRejected),
        (1, G8lS571PhysicalError::DeviceOperationDrift),
        (2, G8lS571PhysicalError::PowerAttestationDrift),
        (3, G8lS571PhysicalError::CaptureContractDrift),
        (4, G8lS571PhysicalError::RawIdentityDrift),
        (5, G8lS571PhysicalError::CloseoutDrift),
    ];
    for (case, expected) in cases {
        let mut observed = physical_observation();
        match case {
            0 => observed.authorization_token = "WRONG",
            1 => observed.sd_writes = 3,
            2 => observed.power_transitions_operator_reported = 1,
            3 => observed.capture_durable = false,
            4 => observed.raw.bytes += 1,
            5 => observed.uart_holders_at_closeout = 1,
            _ => unreachable!(),
        }
        assert_eq!(
            service_s571_model_physical_run(
                &mut G8lS571PhysicalState::new(),
                observed,
                PHYSICAL_RAW,
            ),
            Err(expected)
        );
    }
    let mut corrupted = PHYSICAL_RAW.to_vec();
    corrupted.extend_from_slice(S571_G8H_ERROR_MARKER.as_bytes());
    let mut observed = physical_observation();
    observed.raw.bytes = corrupted.len() as u64;
    assert_eq!(
        service_s571_model_physical_run(&mut G8lS571PhysicalState::new(), observed, &corrupted,),
        Err(G8lS571PhysicalError::RawIdentityDrift)
    );
    let mut classifier_red = PHYSICAL_RAW.to_vec();
    classifier_red[..5].copy_from_slice(b"PANIC");
    assert_eq!(
        service_s571_model_physical_run(
            &mut G8lS571PhysicalState::new(),
            physical_observation(),
            &classifier_red,
        ),
        Err(G8lS571PhysicalError::RawClassifierRejected)
    );
}
snippet sha256: 0f7256ac1171file sha256: 0f7256ac1171
03 · Kapı kimlik kaydı

Operations sıra, kimlik ve başlık bağı

tam Operations kaydıL1632–L1713
website/src/lib/operations.ts::g8l-s571-r1-frozen-manifest-physical-boot-uart-pass
  {
    id: "g8l-s571-r1-frozen-manifest-physical-boot-uart-pass",
    date: "2026-08-31",
    sequence: 571,
    status: "passed",
    umbrella_status: "partial",
    title: "S571 · Fiziksel boot/UART koşusu — immutable PASS",
    summary:
      "S571 host sözleşmesi ve ayrı yetkili fiziksel kapı PASS'tir. Exact S570 adayı exact /dev/disk6 karta staged exact4 olarak yazıldı, dört dosya byte-eş geri okundu, manifest doğrulandı ve kart eject edildi. Debug Probe UART capture_armed=YES sonrasında operatör tek power-on bildirdi; 20947 B immutable raw BOOT8G, BOOT8H, S541 handoff, S538 route ve BOOT_TO_UI_READY marker'larını exact-once, bütün hata/panik marker'larını sıfır kaydetti. Capture terminal grace ile durable kapandı ve operatör power-off bildirdi; RUNBOOK_EXECUTED_IN_S571=YES. Visible scanout/touch gözlenmediği ve S547–S568 device evidence taşımadığı için genel R1 kabulü hâlâ false ve umbrella PARTIAL'dır.",
    evidence: [
      "S571 fiziksel kapı PASS; host contract=PASS, R1 umbrella=PARTIAL ve otomatik promotion=false'dur.",
      "Exact aday 945920 B / a24f4d24e838cd7d1a6b2ff217d864e9c4b08f12ce7dd165b302e8073a980b04 olarak S570 paketine bağlanır; S545 predecessor 945760 B / ed1901a9…8d467 ayrıca korunur.",
      "No-token preflight Debug Probe E6647C74033F9131, /dev/disk6 + /Volumes/ASELSANBOOT, root disk3 ayrımı ve dört S545 predecessor payload'ını doğruladı; built-in reader nedeniyle diskutil external physical count=0 kalması kart yokluğu değildir.",
      "Operatör pi_power_off_assertion_received=true ve authorization_received=true'dur. Bir SD transaction'da 4 write + 4 byte-exact read-back + manifest PASS + 1 eject tamamlandı; retained lock RERUN_FORBIDDEN=YES'tir.",
      "UART wrapper 339 B / 6d75a29a…18f7b9, audited engine 20572 B / 9f001c4c…f1efec ve compiled binary 35224 B / de1af99b…882664 kimliğine bağlıdır; TIOCEXCL, 115200/8N1, TCIFLUSH ve fresh O_EXCL raw power öncesi arm edildi.",
      "Immutable raw 20947 B / 8eba34fcd970d7b5dd276690013b5513ec426020c915356d98d6e5bf0b4e1c83, mode 0444, nlink=1'dir; capture terminal_seen/grace_complete/durable/success=true kapandı.",
      "Raw matrisi BOOT8G/BOOT8H/S541 handoff/S538 route/BOOT_TO_UI_READY=1/1/1/1/1; G8HERR/S541ERR/S538ERR/panic/unknown-IRQ=0/0/0/0/0'dır. Kart raw CID'i UART bootloader çıktısında exact-once gözlendi.",
      "Flash/build/capture/closeout logları 644/769/752/1319 B; EVIDENCE_SHA256SUMS 606 B ve 7/7 entry PASS'tir. İlk no-card ve card-present preflight logları tarihsel sırayı bozmadan immutable korunur.",
      "Focused test 1 grup / 17 passed / 0 failed / 0 ignored / 0 filtered verdi.",
      "Implementation 25250 B / e62d4956968a48549c8f1a602a76b22b54d80f379514641ebec261adecb38079; focused test 26455 B / 0f7256ac1171d7bd0f3e80c38ed7741a8d12a6015bb5dc59bd87e9559fb68336; PASS proof 7633 B / e744ae05aee19b189303d6469bf0bc71edeca6d59e1cabf4b0286dcfa3962d56 SHA-256'dır.",
      "S540, S543 ve S546 immutable fiziksel RED kalır; S571 dördüncü ve ilk remediation-sonrası fiziksel PASS gözlemidir.",
      "physical/device operations=1, runtime observations=1, physical observations=1, Boot-to-UI UART marker=true; visible scanout/input=false ve R1 acceptance=false'dur.",
    ],
    commands: [
      "CARGO_INCREMENTAL=0 cargo test -p aselsan_microkernel_simulation --test g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s571_r1_frozen_manifest_physical_boot_uart_run -- --test-threads=1",
      "scripts/flash-rpi5-s571-r1-candidate.sh --source-check",
      "scripts/flash-rpi5-s571-r1-candidate.sh --preflight <absolute-S570-package> /dev/disk6 /Volumes/ASELSANBOOT S571_PI_UNPOWERED_ASSERTED",
      "scripts/flash-rpi5-s571-r1-candidate.sh <absolute-S570-package> /dev/disk6 /Volumes/ASELSANBOOT <exact-operator-authorization> S571_PI_UNPOWERED_ASSERTED",
      "cc -std=c11 -Wall -Wextra -Werror scripts/capture-rpi5-s571-r1-uart.c -o <fresh-capture-binary>",
      "<fresh-capture-binary> /dev/cu.usbmodem21302 evidence/rpi5/r1/sequence-571-physical-boot-uart/s571-uart.raw",
    ],
    terminalSessions: [
      {
        id: "s571-host-contract",
        title: "S571 focused host sözleşmesi",
        commandLines: [
          "CARGO_INCREMENTAL=0 cargo test -p aselsan_microkernel_simulation --test g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s571_r1_frozen_manifest_physical_boot_uart_run -- --test-threads=1",
        ],
        outputLines: [
          "test result: ok. 17 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out",
          "physical gate=PASS; host contract=PASS; runbook=YES; overall R1=false",
        ],
        exitCode: 0,
        outputMode: "complete",
      },
      {
        id: "s571-write-readback-eject",
        title: "S571 yetkili staged write/read-back/eject",
        commandLines: [
          "scripts/flash-rpi5-s571-r1-candidate.sh <absolute-S570-package> /dev/disk6 /Volumes/ASELSANBOOT <exact-operator-authorization> S571_PI_UNPOWERED_ASSERTED",
        ],
        outputLines: [
          "PASS: S571 frozen-manifest candidate exact4 staged/commit/read-back/sync/eject",
          "READBACK=PASS EJECT=PASS UART=NOT_OPENED POWER=NOT_RUN",
          "S571 lock retained; RERUN_FORBIDDEN=YES",
        ],
        exitCode: 0,
        outputMode: "complete",
      },
      {
        id: "s571-physical-uart-pass",
        title: "S571 exclusive UART physical PASS",
        commandLines: [
          "<fresh-capture-binary> /dev/cu.usbmodem21302 evidence/rpi5/r1/sequence-571-physical-boot-uart/s571-uart.raw",
        ],
        outputLines: [
          "capture_armed=YES",
          "terminal_marker_seen=[R1:S536] BOOT_TO_UI_READY start_offset=20919 end_offset=20945",
          "capture_closed=true terminal_seen=true grace_complete=true exact_bytes=20947 mode=0444 durable=true success=true",
        ],
        exitCode: 0,
        outputMode: "complete",
      },
    ],
    limitations: [
      "S571 tek-seferlik transaction tamamlandı; retained lock nedeniyle yeniden çalıştırılamaz.",
      "Güç geçişleri operatör bildirimidir; bağımsız elektrik ölçümü sıfırdır.",
      "BOOT_TO_UI_READY UART marker'ı fiziksel PASS'tir fakat raw route SCANOUT=NOT_OBSERVED ve INPUT=NOT_OBSERVED der; görünür panel/touch PASS iddiası yoktur.",
      "S547–S568 device evidence taşımadığı için genel R1 acceptance=false ve umbrella=PARTIAL kalır.",
      "RUNBOOK_EXECUTED_IN_S571=YES; SD writes/read-backs/ejects=4/4/1, UART/power/new-raw=1/2/1.",
    ],
  },
snippet sha256: 3b7fbde57a69file 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_s571_r1_frozen_manifest_physical_boot_uart_run -- --test-threads=1
proof: docs/M8.1-RPi5-G8l-S571-R1-Frozen-Manifest-Physical-Boot-Uart-Pass-Proof.md
Registry schema v5 · generator website/scripts/generate-code-gates.mjs · Tam SHA-256: 3050638b71a684d8f8f947a8a6faa237a17fa8db5dc0db04fb207b668b462af9