ASELSANMicrokernel
S403 · SOURCE-BOUND GATE EVIDENCE

S403 · Provider invocation observation consumer

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

S403Focused kod testiOperations id exactsource SHA exacttest target exact

operation: g8l-s403-provider-invocation-observation-consumer-partial

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–L159
kernel/src/g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s403_provider_invocation_observation_consumer.rs::S403 provider invocation observation consumer implementation
#![allow(unexpected_cfgs)]

//! S403 CPU0 one-shot provider-invocation observation consumer.
//!
//! S402 retains one copyable post-release observation on CPU1's behalf. S403
//! validates and takes that exact slot on CPU0, producing a non-copyable audit
//! receipt. Consuming the slot removes S402 backpressure but cannot revive the
//! released S247 lease or turn the observation into admission authority.
//!
//! S242 returned authorities and the S240 receipt remain untouched. S244,
//! S243/S236, supported-profile runtime observation, and physical acceptance
//! therefore remain open after this gate.

use crate::g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s244_whole_scheduler_exclusion_admission_request::S245_SOURCE_CPU0;
use crate::g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s402_provider_invocation_observation_publication::{
    G8lS402ProviderInvocationObservation, G8lS402ProviderInvocationObservationError,
    G8lS402ProviderInvocationObservationState, S402_DIRECT_SCHEDULER_ACCESS_SITES,
    S402_PRODUCTION_GUARDED_DIRECT_ACCESS_SITES, S402_SOURCE_AUDIT_UNITS,
    S402_SOURCE_MODEL_COVERED_DIRECT_ACCESS_SITES, S402_UNROUTED_DIRECT_ACCESS_SITES,
};

pub const S403_SOURCE_AUDIT_UNITS: usize = S402_SOURCE_AUDIT_UNITS;
pub const S403_DIRECT_SCHEDULER_ACCESS_SITES: usize = S402_DIRECT_SCHEDULER_ACCESS_SITES;
pub const S403_SOURCE_MODEL_COVERED_DIRECT_ACCESS_SITES: usize =
    S402_SOURCE_MODEL_COVERED_DIRECT_ACCESS_SITES;
pub const S403_PRODUCTION_GUARDED_DIRECT_ACCESS_SITES: usize =
    S402_PRODUCTION_GUARDED_DIRECT_ACCESS_SITES;
pub const S403_UNROUTED_DIRECT_ACCESS_SITES: usize = S402_UNROUTED_DIRECT_ACCESS_SITES;
pub const S403_PRODUCTION_OBSERVATION_CONSUMER_CALLSITES: usize = 1;
pub const S403_PRODUCTION_ADMISSION_PUBLISHER_SITES: usize = 0;
pub const S403_SUPPORTED_PROFILE_RUNTIME_OBSERVATIONS: usize = 0;
pub const S403_PROVIDER_INVOCATION_OBSERVATION_CONSUMER_COMPLETE: bool = true;
pub const S403_END_TO_END_EXCLUSION_ADMISSION_COMPLETE: bool = false;

/// Linear audit receipt for one consumed S402 slot. Its explicit `Drop` keeps
/// it non-`Copy`/non-`Clone`; dropping it performs no authority action because
/// the corresponding S247 lease was already released by S401.
#[derive(Debug, PartialEq, Eq)]
pub struct G8lS403ProviderInvocationObservationReceipt {
    observation: G8lS402ProviderInvocationObservation,
}

impl G8lS403ProviderInvocationObservationReceipt {
    fn new(observation: G8lS402ProviderInvocationObservation) -> Self {
        Self { observation }
    }

    pub const fn request_id(&self) -> u64 {
        self.observation.request_id()
    }

    pub const fn exclusive_token(&self) -> u64 {
        self.observation.exclusive_token()
    }

    pub const fn observation_consumed(&self) -> bool {
        true
    }

    pub const fn authority_was_released(&self) -> bool {
        self.observation.authority_released()
    }

    pub const fn authority_live(&self) -> bool {
        false
    }

    pub const fn whole_scheduler_exclusion_proven(&self) -> bool {
        false
    }

    pub const fn admission_published(&self) -> bool {
        false
    }
}

impl Drop for G8lS403ProviderInvocationObservationReceipt {
    fn drop(&mut self) {}
}

#[derive(Debug, PartialEq, Eq)]
pub enum G8lS403ProviderInvocationObservationConsumerOutcome {
    Idle,
    ObservationConsumed(G8lS403ProviderInvocationObservationReceipt),
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum G8lS403ProviderInvocationObservationConsumerError {
    WrongCpu,
    S402(G8lS402ProviderInvocationObservationError),
    ObservationInvariantDrift,
    ObservationDisappeared,
}

fn validate_observation(observation: &G8lS402ProviderInvocationObservation) -> bool {
    observation.request_id() != 0
        && observation.exclusive_token() != 0
        && observation.provider_constructor_invoked()
        && observation.authority_released()
        && !observation.authority_live()
        && !observation.whole_scheduler_exclusion_proven()
        && !observation.admission_published()
}

pub fn service_s403_model_provider_invocation_observation_consumer(
    observations: &mut G8lS402ProviderInvocationObservationState,
    caller_cpu: usize,
) -> Result<
    G8lS403ProviderInvocationObservationConsumerOutcome,
    G8lS403ProviderInvocationObservationConsumerError,
> {
    if caller_cpu != S245_SOURCE_CPU0 {
        return Err(G8lS403ProviderInvocationObservationConsumerError::WrongCpu);
    }
    let Some(observation) = observations.pending_observation() else {
        return Ok(G8lS403ProviderInvocationObservationConsumerOutcome::Idle);
    };
    if !validate_observation(&observation) {
        return Err(G8lS403ProviderInvocationObservationConsumerError::ObservationInvariantDrift);
    }
    let taken = observations
        .take(caller_cpu)
        .map_err(G8lS403ProviderInvocationObservationConsumerError::S402)?
        .ok_or(G8lS403ProviderInvocationObservationConsumerError::ObservationDisappeared)?;
    if taken != observation {
        return Err(G8lS403ProviderInvocationObservationConsumerError::ObservationInvariantDrift);
    }
    Ok(
        G8lS403ProviderInvocationObservationConsumerOutcome::ObservationConsumed(
            G8lS403ProviderInvocationObservationReceipt::new(taken),
        ),
    )
}

#[cfg(all(target_arch = "aarch64", target_os = "none", feature = "board-rpi5"))]
pub fn service_s403_provider_invocation_observation_consumer_on_cpu0() -> Result<
    G8lS403ProviderInvocationObservationConsumerOutcome,
    G8lS403ProviderInvocationObservationConsumerError,
> {
    use crate::g8l_runtime_contract::CPU0;

    if crate::percpu::try_current_cpu_id() != Some(CPU0) {
        return Err(G8lS403ProviderInvocationObservationConsumerError::WrongCpu);
    }
    let observation = crate::g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s402_provider_invocation_observation_publication::take_s402_provider_invocation_observation_on_cpu0()
        .map_err(G8lS403ProviderInvocationObservationConsumerError::S402)?;
    let Some(observation) = observation else {
        return Ok(G8lS403ProviderInvocationObservationConsumerOutcome::Idle);
    };
    if !validate_observation(&observation) {
        return Err(G8lS403ProviderInvocationObservationConsumerError::ObservationInvariantDrift);
    }
    Ok(
        G8lS403ProviderInvocationObservationConsumerOutcome::ObservationConsumed(
            G8lS403ProviderInvocationObservationReceipt::new(observation),
        ),
    )
}
snippet sha256: 72cc92fa8750file sha256: 72cc92fa8750
02 · Doğrulayan test kodu

Operations komutuna bağlı focused test

tam dosyaL1–L300
simulation/tests/g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s403_provider_invocation_observation_consumer.rs::S403 provider invocation observation consumer focused tests
#![recursion_limit = "256"]

use aselsan_microkernel_simulation::g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s244_whole_scheduler_exclusion_admission_request::{
    service_s245_exclusion_admission_request, G8lS245ExclusionAdmissionRequestOutcome,
    G8lS245WholeSchedulerExclusionAdmissionRequestState, S245_SOURCE_CPU0, S245_TARGET_CPU1,
};
use aselsan_microkernel_simulation::g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s246_whole_scheduler_read_access_guard::G8lS247WholeSchedulerAccessGate;
use aselsan_microkernel_simulation::g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s402_provider_invocation_observation_publication::{
    service_s402_model_provider_invocation_observation_publication,
    G8lS402ProviderInvocationObservationState, S402_DIRECT_SCHEDULER_ACCESS_SITES,
    S402_PRODUCTION_GUARDED_DIRECT_ACCESS_SITES, S402_SOURCE_AUDIT_UNITS,
    S402_SOURCE_MODEL_COVERED_DIRECT_ACCESS_SITES, S402_UNROUTED_DIRECT_ACCESS_SITES,
};
use aselsan_microkernel_simulation::g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s403_provider_invocation_observation_consumer::*;

fn published_observation(
    request_id: u64,
) -> (
    G8lS247WholeSchedulerAccessGate,
    G8lS402ProviderInvocationObservationState,
) {
    let gate = G8lS247WholeSchedulerAccessGate::new();
    let mut requests =
        G8lS245WholeSchedulerExclusionAdmissionRequestState::with_next_request_id(request_id);
    assert_eq!(
        service_s245_exclusion_admission_request(&mut requests, S245_SOURCE_CPU0, true, true),
        Ok(G8lS245ExclusionAdmissionRequestOutcome::RequestPublished(
            request_id
        ))
    );
    let mut observations = G8lS402ProviderInvocationObservationState::new();
    service_s402_model_provider_invocation_observation_publication(
        &mut observations,
        &gate,
        &mut requests,
        S245_TARGET_CPU1,
    )
    .unwrap();
    (gate, observations)
}

fn module_source() -> &'static str {
    include_str!("../../kernel/src/g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s403_provider_invocation_observation_consumer.rs")
}

fn exception_source() -> &'static str {
    include_str!("../../kernel/src/arch/aarch64/exceptions.rs")
}

fn kernel_main_source() -> &'static str {
    include_str!("../../kernel/src/main.rs")
}

fn simulation_lib_source() -> &'static str {
    include_str!("../src/lib.rs")
}

fn s404_source() -> &'static str {
    include_str!("../../kernel/src/g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s404_scoped_authority_request_publication.rs")
}

#[test]
fn constants_promote_only_the_cpu0_one_shot_observation_consumer() {
    assert_eq!(S403_SOURCE_AUDIT_UNITS, 7);
    assert_eq!(S403_DIRECT_SCHEDULER_ACCESS_SITES, 113);
    assert_eq!(S403_SOURCE_MODEL_COVERED_DIRECT_ACCESS_SITES, 113);
    assert_eq!(S403_PRODUCTION_GUARDED_DIRECT_ACCESS_SITES, 113);
    assert_eq!(S403_UNROUTED_DIRECT_ACCESS_SITES, 0);
    assert_eq!(S403_PRODUCTION_OBSERVATION_CONSUMER_CALLSITES, 1);
    assert_eq!(S403_PRODUCTION_ADMISSION_PUBLISHER_SITES, 0);
    assert_eq!(S403_SUPPORTED_PROFILE_RUNTIME_OBSERVATIONS, 0);
    assert!(S403_PROVIDER_INVOCATION_OBSERVATION_CONSUMER_COMPLETE);
    assert!(!S403_END_TO_END_EXCLUSION_ADMISSION_COMPLETE);
}

#[test]
fn s402_is_the_exact_publication_predecessor() {
    assert_eq!(S403_SOURCE_AUDIT_UNITS, S402_SOURCE_AUDIT_UNITS);
    assert_eq!(
        S403_DIRECT_SCHEDULER_ACCESS_SITES,
        S402_DIRECT_SCHEDULER_ACCESS_SITES
    );
    assert_eq!(
        S403_SOURCE_MODEL_COVERED_DIRECT_ACCESS_SITES,
        S402_SOURCE_MODEL_COVERED_DIRECT_ACCESS_SITES
    );
    assert_eq!(
        S403_PRODUCTION_GUARDED_DIRECT_ACCESS_SITES,
        S402_PRODUCTION_GUARDED_DIRECT_ACCESS_SITES
    );
    assert_eq!(
        S403_UNROUTED_DIRECT_ACCESS_SITES,
        S402_UNROUTED_DIRECT_ACCESS_SITES
    );
}

#[test]
fn cpu0_consumes_the_exact_observation_once_into_a_non_authoritative_receipt() {
    let (gate, mut observations) = published_observation(91);
    let outcome = service_s403_model_provider_invocation_observation_consumer(
        &mut observations,
        S245_SOURCE_CPU0,
    )
    .unwrap();
    let G8lS403ProviderInvocationObservationConsumerOutcome::ObservationConsumed(receipt) = outcome
    else {
        panic!("published observation must be consumed")
    };
    assert_eq!(receipt.request_id(), 91);
    assert_eq!(receipt.exclusive_token(), 1);
    assert!(receipt.observation_consumed());
    assert!(receipt.authority_was_released());
    assert!(!receipt.authority_live());
    assert!(!receipt.whole_scheduler_exclusion_proven());
    assert!(!receipt.admission_published());
    assert!(!observations.pending());
    assert_eq!(gate.active_exclusive_token(), None);
}

#[test]
fn empty_observation_slot_is_idle() {
    let mut observations = G8lS402ProviderInvocationObservationState::new();
    assert!(matches!(
        service_s403_model_provider_invocation_observation_consumer(
            &mut observations,
            S245_SOURCE_CPU0
        ),
        Ok(G8lS403ProviderInvocationObservationConsumerOutcome::Idle)
    ));
}

#[test]
fn wrong_cpu_fails_before_taking_the_observation() {
    let (_gate, mut observations) = published_observation(3);
    assert!(matches!(
        service_s403_model_provider_invocation_observation_consumer(
            &mut observations,
            S245_TARGET_CPU1
        ),
        Err(G8lS403ProviderInvocationObservationConsumerError::WrongCpu)
    ));
    assert_eq!(observations.pending_observation().unwrap().request_id(), 3);
}

#[test]
fn consumed_slot_allows_the_next_s402_publication() {
    let gate = G8lS247WholeSchedulerAccessGate::new();
    let mut requests = G8lS245WholeSchedulerExclusionAdmissionRequestState::new();
    let mut observations = G8lS402ProviderInvocationObservationState::new();
    for request_id in 1..=2 {
        assert!(matches!(
            service_s245_exclusion_admission_request(
                &mut requests,
                S245_SOURCE_CPU0,
                true,
                true
            ),
            Ok(G8lS245ExclusionAdmissionRequestOutcome::RequestPublished(id)) if id == request_id
        ));
        service_s402_model_provider_invocation_observation_publication(
            &mut observations,
            &gate,
            &mut requests,
            S245_TARGET_CPU1,
        )
        .unwrap();
        let outcome = service_s403_model_provider_invocation_observation_consumer(
            &mut observations,
            S245_SOURCE_CPU0,
        )
        .unwrap();
        let G8lS403ProviderInvocationObservationConsumerOutcome::ObservationConsumed(receipt) =
            outcome
        else {
            panic!("observation must be consumed")
        };
        assert_eq!(receipt.request_id(), request_id);
        assert_eq!(receipt.exclusive_token(), request_id);
    }
}

#[test]
fn consumer_receipt_is_non_copy_non_clone_and_contains_no_lease() {
    assert!(core::mem::needs_drop::<
        G8lS403ProviderInvocationObservationReceipt,
    >());
    let source = module_source();
    let start = source
        .find("pub struct G8lS403ProviderInvocationObservationReceipt")
        .unwrap();
    let derive = source[..start].rfind("#[derive").unwrap();
    assert_eq!(
        source[derive..start].trim(),
        "#[derive(Debug, PartialEq, Eq)]"
    );
    let body = &source[start..source[start..].find("}\n\nimpl").unwrap() + start];
    assert!(!body.contains("lease"));
    assert!(!body.contains("authority:"));
}

#[test]
fn model_consumer_validates_before_one_shot_take() {
    let source = module_source();
    let start = source
        .find("pub fn service_s403_model_provider_invocation_observation_consumer")
        .unwrap();
    let function: String = source[start..].split_whitespace().collect();
    let inspect = function.find("pending_observation()").unwrap();
    let validate = function.find("validate_observation").unwrap();
    let take = function.find("observations.take(caller_cpu)").unwrap();
    assert!(inspect < validate && validate < take);
}

#[test]
fn production_service_uses_the_exact_s402_one_shot_extractor() {
    let source = module_source();
    let start = source
        .find("pub fn service_s403_provider_invocation_observation_consumer_on_cpu0")
        .unwrap();
    let function = &source[start..];
    assert_eq!(
        function
            .matches("take_s402_provider_invocation_observation_on_cpu0")
            .count(),
        1
    );
    assert!(function.contains("validate_observation"));
}

#[test]
fn s404_successor_invokes_s403_and_owns_the_cpu0_timer_position() {
    let exceptions = exception_source();
    let s245 = exceptions
        .find("service_s245_exclusion_admission_request_on_cpu0")
        .unwrap();
    let s404 = exceptions
        .find("service_s404_scoped_authority_request_publication_on_cpu0")
        .unwrap();
    let cpu1 = exceptions[s404..]
        .find("if crate::percpu::current_cpu_id() == 1")
        .map(|offset| offset + s404)
        .unwrap();
    assert!(s245 < s404 && s404 < cpu1);
    assert!(!exceptions.contains("service_s403_provider_invocation_observation_consumer_on_cpu0"));
    assert_eq!(
        s404_source()
            .matches("service_s403_provider_invocation_observation_consumer_on_cpu0")
            .count(),
        1
    );
}

#[test]
fn s404_successor_accepts_only_idle_or_consumed_from_s403() {
    let source = s404_source();
    assert!(source.contains("G8lS403ProviderInvocationObservationConsumerOutcome::Idle"));
    assert!(
        source.contains("G8lS403ProviderInvocationObservationConsumerOutcome::ObservationConsumed")
    );
    assert!(source.contains("G8lS404ScopedAuthorityRequestServiceError::S403"));
}

#[test]
fn production_consumer_uses_exact_supported_profile_and_cpu0_identity() {
    let source = module_source();
    assert!(source.contains("target_arch = \"aarch64\""));
    assert!(source.contains("target_os = \"none\""));
    assert!(source.contains("feature = \"board-rpi5\""));
    assert!(source.contains("crate::percpu::try_current_cpu_id()"));
    assert!(source.contains("CPU0"));
}

#[test]
fn s403_does_not_consume_s242_s240_or_publish_admission() {
    let source = module_source();
    for forbidden in [
        "take_s242_returned_runtime_authorities_on_cpu0",
        "take_sgi_receipt_and_consume_s179_on_cpu0",
        "publish_s244",
        "service_s243_deferred_authority_receipt_join",
        "addr_of!(",
        "addr_of_mut!(",
    ] {
        assert!(
            !source.contains(forbidden),
            "forbidden promotion: {forbidden}"
        );
    }
}

#[test]
fn s403_and_its_exact_s404_successor_are_registered_separately() {
    let s403 = "g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s403_provider_invocation_observation_consumer";
    let s404 = "g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s404_scoped_authority_request_publication";
    assert!(kernel_main_source().contains(&format!("mod {s403};")));
    assert!(simulation_lib_source().contains(&format!("pub mod {s403};")));
    assert!(kernel_main_source().contains(&format!("mod {s404};")));
    assert!(simulation_lib_source().contains(&format!("pub mod {s404};")));
}
snippet sha256: 5d6cb9d16e60file sha256: 5d6cb9d16e60
03 · Kapı kimlik kaydı

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

tam Operations kaydıL134–L150
website/src/lib/operations.ts::g8l-s403-provider-invocation-observation-consumer-partial
  {
    id: "g8l-s403-provider-invocation-observation-consumer-partial",
    sequence: 403,
    slug: "provider_invocation_observation_consumer",
    title: "Provider invocation observation consumer",
    focusedTests: 14,
    sourceBytes: 6609,
    sourceSha256:
      "72cc92fa8750d51de7d8605c650614b8c2e0b0de878c608e119f4f9e5f330f29",
    testBytes: 11521,
    testSha256:
      "5d6cb9d16e60e71e3c7c2acc525bd709cdf2d3ff1f19c1eca78c61131bde0d0c",
    acceptance:
      "CPU0 exact S402 observation'ını one-shot tüketir, provider/request/token kimliklerini yeniden doğrular ve typed consumer receipt üretir.",
    retainedBoundary:
      "Consumer receipt tek başına scoped authority request veya S244 admission yayımlamaz.",
  },
snippet sha256: c517abd575a2file 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_s403_provider_invocation_observation_consumer -- --test-threads=1
proof: docs/M8.1-RPi5-G8l-S403-Provider-Invocation-Observation-Consumer-Proof.md
Registry schema v5 · generator website/scripts/generate-code-gates.mjs · Tam SHA-256: 91d38c7b6222f0b4c117be786454853543da55a160e543d9b951057cc20dcc06