ASELSANMicrokernel
S112 · SOURCE-BOUND GATE EVIDENCE

K2 temeli: ortak ABI, bounded IPC ve transactional endpoint otoritesi kaynakta kuruldu

Operations --test hedefi → focused test içindeki include_str!/#[path] bağı → kaynak kesiti Bu sayfa yalnız S112 kapısına aittir; komşu kapıların kaynakları bu kabulün içine katılmaz.

S112Focused kod testiOperations id exactsource SHA exacttest target exact

operation: k2-bounded-ipc-abi-foundations-partial

uygulama/model · focused test · Operations · 3 exact excerpt

sequence-bound=true · implementation-bound=false
01 · Testin bağlı olduğu uygulama/model kodu

Kapının yürüttüğü gerçek kaynak

tam Rust öğesiL608–L1305
kernel/src/ui/capability.rs::revoke_notification_provenance

impl CapabilityStore {
    pub const fn new() -> Self {
        Self {
            next_id: AtomicU64::new(1),
            entries: Vec::new(),
        }
    }

    /// Reserve a globally unique identity without publishing provenance.
    /// A failed transactional mint may consume an id, but that id is never
    /// reused or made visible through a CNode/registry entry.
    #[inline]
    fn allocate_id(&self) -> CapId {
        self.next_id.fetch_add(1, Ordering::Relaxed)
    }

    /// Endpoint publication reserves zero and `u64::MAX` as invalid/exhausted
    /// sentinels and therefore cannot wrap back to an already-issued id.
    #[inline]
    fn try_allocate_endpoint_id(&self) -> Result<CapId, EndpointMintError> {
        self.next_id
            .try_update(Ordering::Relaxed, Ordering::Relaxed, |current| {
                (current != 0 && current != u64::MAX).then(|| current + 1)
            })
            .map_err(|_| EndpointMintError::CapabilityIdExhausted)
    }

    #[inline]
    fn try_allocate_notification_id(&self) -> Result<CapId, NotificationMintError> {
        self.next_id
            .try_update(Ordering::Relaxed, Ordering::Relaxed, |current| {
                (current != 0 && current != u64::MAX).then(|| current + 1)
            })
            .map_err(|_| NotificationMintError::CapabilityIdExhausted)
    }

    /// Yeni bir capability kaydı oluştur (mint).
    /// V+W (Radikal): Artık sadece provenance kaydı düşer. Gerçek Capability CNode'a yazılır.
    pub fn mint(&mut self, owner: u64, kind: CapabilityKind) -> CapId {
        let id = self.allocate_id();
        self.entries
            .push(CapabilityEntry::new_minted(id, owner, None, kind));
        id
    }

    /// Mevcut bir capability'den kısıtlanmış türev üret (derive / restrict).
    /// M4.4 FramebufferCapability.restrict ile uyumlu çalışır.
    pub fn derive_framebuffer(
        &mut self,
        parent_id: CapId,
        new_owner: u64,
        restricted_rights: FramebufferRights,
        restricted_region: FramebufferRegion,
    ) -> Result<CapId, &'static str> {
        // Gerçek delegation'ı framebuffer katmanına yaptır (mapping + parent_grant_id)
        let new_grant_id =
            delegate_framebuffer_grant(parent_id, new_owner, restricted_rights, restricted_region)?;

        // V+W (Radikal): Store'a sadece provenance kaydı düşer.
        // Gerçek haklar ve nesne CNode'daki Capability'de tutulur.
        self.entries.push(CapabilityEntry::new_minted(
            new_grant_id,
            new_owner,
            Some(parent_id),
            CapabilityKind::Framebuffer,
        ));

        Ok(new_grant_id)
    }

    /// Capability'yi registry'den kaldır (revoke) — **sadece provenance temizliği**.
    ///
    /// # E Adımı Uyarısı (V+W Radikal Model)
    /// Bu metod **düşük seviyeli** bir araçtır.
    /// Normal kullanımda **asla doğrudan çağırmayın**.
    ///
    /// **Tek tavsiye edilen revoke yolu:**
    /// ```ignore
    /// my_capability.revoke(revoker_id);           // Capability
    /// framebuffer_cap.revoke(revoker_id);         // FramebufferCapability
    /// ```
    ///
    /// Bu üst seviye metodlar:
    /// 1. CNode'dan yetkili revoke + generation bump yapar
    /// 2. FB grant + unmap + cascade yapar
    /// 3. Store provenance'ını temizler
    ///
    /// Direkt Store::revoke kullanmak CNode ile tutarsızlık yaratabilir.
    pub fn revoke(&mut self, id: CapId, revoker: Option<u64>) -> Result<(), &'static str> {
        // FB revoke'u dene. Zaten temizlenmişse (Capability::revoke içinden önce çağrıldığı için)
        // hata verebilir. Radikal modelde Store sadece provenance olduğu için hatayı yutup
        // devam ediyoruz — önemli olan registry'yi temizlemek.
        let _ = fb_revoke(id, revoker);

        // Registry'den sil (kendi çocuklarını da sil) — Store sadece provenance tutar
        let mut to_remove = alloc::vec![id];
        let mut i = 0;
        while i < to_remove.len() {
            let cur = to_remove[i];
            for e in &self.entries {
                if e.parent == Some(cur) && !to_remove.contains(&e.id) {
                    to_remove.push(e.id);
                }
            }
            i += 1;
        }

        // M5.2: Silmeden ÖNCE etkilenen entry'lerin revoke meta'sını işle ve
        // tek satırlık audit log bas — provenance forensik için (kim, ne zaman).
        let now_tick =
            crate::arch::aarch64::exceptions::TICKS.load(core::sync::atomic::Ordering::Relaxed);
        for e in self
            .entries
            .iter_mut()
            .filter(|e| to_remove.contains(&e.id))
        {
            e.mark_revoked(revoker);
            crate::kprintln!(
                "[CAP-REVOKE] cap#{} owner={} kind={:?} parent={:?} life={}t revoker={:?}",
                e.id,
                e.owner,
                e.kind,
                e.parent,
                now_tick.saturating_sub(e.creation_tick),
                revoker
            );
        }

        let _before = self.entries.len();
        self.entries.retain(|e| !to_remove.contains(&e.id));

        // Idempotent revoke: zaten temizlenmişse hata değil.
        Ok(())
    }

    /// Remove endpoint provenance without allocating or touching unrelated
    /// framebuffer teardown. Endpoint objects have no CapabilityStore child
    /// derivation path; kernel-shared grants live only in task CNodes. Keeping
    /// this operation exact lets CALL rollback, REPLY consumption and peer
    /// teardown remain usable when the heap is exhausted.
    pub(crate) fn revoke_endpoint_provenance(&mut self, id: CapId, revoker: Option<u64>) -> usize {
        let now_tick =
            crate::arch::aarch64::exceptions::TICKS.load(core::sync::atomic::Ordering::Relaxed);
        let mut removed = 0;

        for entry in self
            .entries
            .iter_mut()
            .filter(|entry| entry.id == id && entry.kind == CapabilityKind::Endpoint)
        {
            entry.mark_revoked(revoker);
            removed += 1;
            crate::kprintln!(
                "[CAP-REVOKE] endpoint cap#{} owner={} life={}t revoker={:?}",
                entry.id,
                entry.owner,
                now_tick.saturating_sub(entry.creation_tick),
                revoker
            );
        }
        self.entries
            .retain(|entry| !(entry.id == id && entry.kind == CapabilityKind::Endpoint));
        removed
    }

    pub(crate) fn revoke_notification_provenance(
        &mut self,
        id: CapId,
        revoker: Option<u64>,
    ) -> usize {
        let now_tick =
            crate::arch::aarch64::exceptions::TICKS.load(core::sync::atomic::Ordering::Relaxed);
        let mut removed = 0;
        for entry in self
            .entries
            .iter_mut()
            .filter(|entry| entry.id == id && entry.kind == CapabilityKind::Notification)
        {
            entry.mark_revoked(revoker);
            removed += 1;
            crate::kprintln!(
                "[CAP-REVOKE] notification cap#{} owner={} life={}t revoker={:?}",
                entry.id,
                entry.owner,
                now_tick.saturating_sub(entry.creation_tick),
                revoker
            );
        }
        self.entries
            .retain(|entry| !(entry.id == id && entry.kind == CapabilityKind::Notification));
        removed
    }

    /// Lookup by CapId (global fast path for provenance).
    ///
    /// V+W (Radikal): Bu metod store'un provenance kaydını döndürür.
    /// Gerçek yetki durumu (haklar, generation) için lütfen CNode veya
    /// `get_live_capability` benzeri yardımcıları kullanın.
    pub fn lookup(&self, id: CapId) -> Option<&CapabilityEntry> {
        self.entries.iter().find(|e| e.id == id)
    }

    /// V+W (Radikal): Verilen grant_id için mümkün olan en canlı `Capability` nesnesini döndürmeye çalışır.
    /// Önce ilgili task'in CNode'una, sonra store'a bakar.
    pub fn get_live_capability(&self, id: CapId) -> Option<Capability> {
        if let Some(entry) = self.lookup(id) {
            if let Some(caps) = crate::task::get_task_cnode_capabilities(entry.owner) {
                if let Some(live) = caps.into_iter().find(|c| c.id == id) {
                    return Some(live);
                }
            }
        }
        None
    }

    /// Bir capability'nin delegation zincirini döndürür.
    pub fn delegation_chain(&self, id: CapId) -> Vec<CapId> {
        // Önce framebuffer'ın chain'ini al (en doğru kaynak)
        let fb_chain = fb_get_chain(id);
        // Registry'deki parent bilgisiyle zenginleştir (ileride tamamen buraya taşınacak)
        fb_chain
    }

    /// Sahibine ait tüm capability'leri listele (Store tarafı).
    pub fn capabilities_of(&self, owner: u64) -> Vec<&CapabilityEntry> {
        self.entries.iter().filter(|e| e.owner == owner).collect()
    }

    /// V+W (Radikal): Bir task'in sahip olduğu capability'leri döndürür.
    /// **CNode birincil ve otoriter kaynaktır**.
    /// CapabilityStore sadece provenance + global arama için ikincil registry olarak kullanılır.
    pub fn capabilities_of_task(&self, task_id: u64) -> Vec<Capability> {
        // CNode birincil kaynak
        if let Some(cnode_caps) = crate::task::get_task_cnode_capabilities(task_id) {
            return cnode_caps;
        }

        // İkincil fallback (sadece CNode erişilemiyorsa)
        self.entries
            .iter()
            .filter(|e| e.owner == task_id)
            .map(|e| {
                // Fallback sırasında hakları FULL varsayıyoruz (gerçek hak CNode'da)
                Capability::new(e.id, 1, CapabilityRights::FULL, e.kind, e.owner, e.parent)
            })
            .collect()
    }

    /// V+W (Radikal): Task'in bu capability'ye sahip olup olmadığını kontrol eder.
    /// **CNode birincil kaynaktır**. Store sadece fallback olarak kullanılır.
    pub fn task_has_capability(&self, task_id: u64, cap_id: CapId) -> bool {
        // Önce CNode'a sor
        if let Some(caps) = crate::task::get_task_cnode_capabilities(task_id) {
            return caps.iter().any(|c| c.id == cap_id);
        }

        // Fallback: Store
        self.entries
            .iter()
            .any(|e| e.owner == task_id && e.id == cap_id)
    }

    pub fn debug_dump(&self) {
        crate::kprintln!(
            "[CAPSTORE] {} provenance entries (CNode birincil kaynaktır)",
            self.entries.len()
        );
        for e in &self.entries {
            crate::kprintln!(
                "[CAPSTORE]   Cap#{} owner={} kind={:?} parent={:?}",
                e.id,
                e.owner,
                e.kind,
                e.parent
            );
        }
    }

    // =================================================================
    // K adımı: Basit mint + derive API (generic Capability odaklı)
    // =================================================================

    /// Yeni bir capability "mint" eder ve hazır `Capability` nesnesi döndürür.
    ///
    /// V+W (Radikal — C adımı):
    ///   CNode, canlı yetkinin **tek otoriter kaynağı**dır.
    ///   Bu fonksiyon:
    ///   1. Önce CNode'a insert yapar → gerçek generation CNode tarafından atanır.
    ///   2. Dönen generation ile nihai Capability nesnesini oluşturur.
    ///   3. Store'a yalnızca hafif provenance kaydı (id, owner, parent, kind) düşer.
    ///
    /// Artık hiçbir yerde "generation=1 hardcoded" veya "dışarıdan generation geçme" yoktur.
    pub fn mint_capability(
        &mut self,
        owner: u64,
        rights: CapabilityRights,
        kind: CapabilityKind,
    ) -> Capability {
        let id = self.mint(owner, kind); // Store sadece provenance id üretir

        // Geçici nesne (generation CNode tarafından ezilecek)
        let provisional = Capability::new(id, 0, rights, kind, owner, None);

        // CNode insert — generation burada kesin olarak atanır (otoriter adım)
        let real_gen = match crate::task::insert_cap_for_task(owner, provisional) {
            Ok((_slot, gen)) => gen,
            Err(e) => {
                // "Task not found" sahte task ID (smoke test 100/200) için
                // beklenen davranış — sessizce fallback. Diğer hatalar uyarı verir.
                if e != "Task not found" {
                    crate::kprintln!("[CAP-MINT] CNode insert başarısız: {} — fallback gen=1", e);
                }
                1
            }
        };

        // Nihai Capability, CNode'un atadığı gerçek generation ile
        let cap = Capability::new(id, real_gen, rights, kind, owner, None);

        // Store: sadece provenance (CNode yetkiyi tutar)
        self.entries
            .push(CapabilityEntry::new_minted(id, owner, None, kind));

        cap
    }

    /// Mevcut bir `Capability`'den kısıtlı bir türev üretir (derive / delegate).
    ///
    /// V+W (Radikal — C adımı):
    ///   - `new_generation` parametresi kaldırıldı. Generation **her zaman CNode tarafından atanır**.
    ///   - Önce CNode insert → gerçek generation al.
    ///   - Sonra Capability'yi o generation ile oluştur.
    ///   - Store'a yalnızca {id, owner, parent, kind} provenance yazılır.
    ///
    /// Çağıranlar (framebuffer grant/delegate) artık generation üretmek zorunda değildir.
    pub fn derive_capability(
        &mut self,
        parent: &Capability,
        new_owner: u64,
        new_id: CapId,
        restricted_rights: CapabilityRights,
    ) -> Result<Capability, &'static str> {
        let effective = parent.rights.intersect(restricted_rights);
        if effective.as_u8() == 0 {
            return Err("No effective rights after restriction");
        }
        if parent.kind != CapabilityKind::Framebuffer && parent.kind != CapabilityKind::Endpoint {
            return Err("Only Framebuffer and Endpoint derivation is supported in this build");
        }

        // Geçici nesne — generation CNode insert'inde belirlenecek
        let provisional = Capability::new(
            new_id,
            0,
            effective,
            parent.kind,
            new_owner,
            Some(parent.id),
        );

        // CNode insert (otoriter) — gerçek generation burada döner
        let real_gen = match crate::task::insert_cap_for_task(new_owner, provisional) {
            Ok((_slot, gen)) => gen,
            Err(e) => {
                if e != "Task not found" {
                    crate::kprintln!(
                        "[CAP-DERIVE] CNode insert başarısız: {} — fallback gen=1",
                        e
                    );
                }
                1
            }
        };

        // Nihai Capability: CNode'un atadığı generation ile
        let cap = Capability::new(
            new_id,
            real_gen,
            effective,
            parent.kind,
            new_owner,
            Some(parent.id),
        );

        // Store'a yalnızca hafif provenance kaydı
        self.entries.push(CapabilityEntry::new_minted(
            new_id,
            new_owner,
            Some(parent.id),
            parent.kind,
        ));

        Ok(cap)
    }

    // =================================================================
    // M5.4 — Memory / Tcb / Untyped Capability mint helper'ları
    //
    // Hâlâ minimum impl (kernel object pointer / phys range henüz tutulmuyor),
    // ama generic Capability sistemine basit factory'ler sunuyor: CNode'a
    // doğru kind + ownership ile insert + provenance kaydı + log. M6.4 IPC
    // server'ları benzer pattern kullanmak istediğinde aynı yolu çağıracak.
    // =================================================================

    /// Memory capability (RAM frame veya bellek aralığı).
    /// `phys_base` ve `size` şu an log için; ilerideki impl bunları
    /// `CapabilityEntry` extension'ında veya ayrı `MemoryRegion` registry'sinde
    /// tutacak.
    pub fn mint_memory(&mut self, owner: u64, phys_base: u64, size: u64) -> Capability {
        let id = self.mint(owner, CapabilityKind::Memory);
        let provisional = Capability::new(
            id,
            0,
            CapabilityRights::FULL,
            CapabilityKind::Memory,
            owner,
            None,
        );
        let real_gen = match crate::task::insert_cap_for_task(owner, provisional) {
            Ok((_, gen)) => gen,
            Err(_) => 1,
        };
        let cap = Capability::new(
            id,
            real_gen,
            CapabilityRights::FULL,
            CapabilityKind::Memory,
            owner,
            None,
        );
        self.entries.push(CapabilityEntry::new_minted(
            id,
            owner,
            None,
            CapabilityKind::Memory,
        ));
        crate::kprintln!(
            "[M5.4] Memory cap mint: id={} owner={} phys=0x{:x} size={}",
            id,
            owner,
            phys_base,
            size
        );
        cap
    }

    /// TCB (Thread Control Block) capability — bir task'i kontrol etme yetkisi.
    /// `target_task_id` ileride suspend/resume/configure işlemleri için kullanılacak.
    pub fn mint_tcb(&mut self, owner: u64, target_task_id: u64) -> Capability {
        let id = self.mint(owner, CapabilityKind::Tcb);
        let provisional = Capability::new(
            id,
            0,
            CapabilityRights::FULL,
            CapabilityKind::Tcb,
            owner,
            None,
        );
        let real_gen = match crate::task::insert_cap_for_task(owner, provisional) {
            Ok((_, gen)) => gen,
            Err(_) => 1,
        };
        let cap = Capability::new(
            id,
            real_gen,
            CapabilityRights::FULL,
            CapabilityKind::Tcb,
            owner,
            None,
        );
        self.entries.push(CapabilityEntry::new_minted(
            id,
            owner,
            None,
            CapabilityKind::Tcb,
        ));
        crate::kprintln!(
            "[M5.4] TCB cap mint: id={} owner={} target=task#{}",
            id,
            owner,
            target_task_id
        );
        cap
    }

    /// Untyped capability — ham bellek bloğu. `retype` ile başka kind'lara
    /// dönüştürülecek (M5.5 yol haritasında).
    pub fn mint_untyped(&mut self, owner: u64, phys_base: u64, size_log2: u8) -> Capability {
        let id = self.mint(owner, CapabilityKind::Untyped);
        let provisional = Capability::new(
            id,
            0,
            CapabilityRights::FULL,
            CapabilityKind::Untyped,
            owner,
            None,
        );
        let real_gen = match crate::task::insert_cap_for_task(owner, provisional) {
            Ok((_, gen)) => gen,
            Err(_) => 1,
        };
        let cap = Capability::new(
            id,
            real_gen,
            CapabilityRights::FULL,
            CapabilityKind::Untyped,
            owner,
            None,
        );
        self.entries.push(CapabilityEntry::new_minted(
            id,
            owner,
            None,
            CapabilityKind::Untyped,
        ));
        crate::kprintln!(
            "[M5.4] Untyped cap mint: id={} owner={} phys=0x{:x} size=2^{} bytes",
            id,
            owner,
            phys_base,
            size_log2
        );
        cap
    }

    // =================================================================
    // M6.1 — Endpoint Capability Desteği
    // =================================================================

    /// Yeni bir Endpoint capability mint eder.
    ///
    /// M6.1: Henüz sadece kimlik + badge taşıyan boş bir endpoint oluşturur.
    /// Gerçek IPC kuyruğu ve send/recv mantığı sonraki adımlarda eklenecek.
    ///
    /// V+W radikal modele uygun: Önce CNode'a insert yapılır, gerçek generation alınır.
    fn mint_endpoint(&mut self, owner: u64, badge: u64) -> Result<Capability, EndpointMintError> {
        if owner == 0 {
            return Err(EndpointMintError::InvalidOwner);
        }
        self.mint_endpoint_inner(owner, badge, false, true, None)
    }

    /// Mint a reply object already linked to the normal endpoint rendezvous
    /// that owns its call record. Publication remains transactional with the
    /// caller CNode exactly like the generic reply path.
    fn mint_reply_endpoint_for_call(
        &mut self,
        owner: u64,
        target_endpoint: CapId,
    ) -> Result<Capability, EndpointMintError> {
        if owner == 0 || target_endpoint == 0 {
            return Err(EndpointMintError::InvalidOwner);
        }
        self.mint_endpoint_inner(owner, 0xCAFE_BABE, true, true, Some(target_endpoint))
    }

    /// Explicit kernel-owned shared endpoint path.  These objects are not
    /// inserted into a task CNode and therefore remain distinguishable from
    /// task authority; syscall callers cannot request this path.
    fn mint_kernel_shared_endpoint(&mut self, badge: u64) -> Result<Capability, EndpointMintError> {
        self.mint_endpoint_inner(0, badge, false, false, None)
    }

    fn mint_endpoint_inner(
        &mut self,
        owner: u64,
        badge: u64,
        is_reply: bool,
        require_cnode: bool,
        reply_target: Option<CapId>,
    ) -> Result<Capability, EndpointMintError> {
        // Preflight every fallible allocation before publishing authority.
        // Once these reservations succeed, the two following Vec::push calls
        // cannot allocate and the CNode insert is the only fallible commit.
        self.entries
            .try_reserve(1)
            .map_err(|_| EndpointMintError::ProvenanceCapacityExhausted)?;
        let mut registry = ENDPOINT_REGISTRY.lock();
        registry
            .try_reserve(1)
            .map_err(|_| EndpointMintError::RegistryCapacityExhausted)?;

        let id = self.try_allocate_endpoint_id()?;

        // Geçici Capability (generation CNode tarafından belirlenecek)
        let provisional = Capability::new(
            id,
            0,
            CapabilityRights::FULL,
            CapabilityKind::Endpoint,
            owner,
            None,
        );

        // A task endpoint becomes visible only after its authoritative CNode
        // accepts it. Kernel-shared endpoints use the explicit owner=0 path
        // above and never masquerade as a task capability.
        let real_gen = if require_cnode {
            let (_slot, generation) =
                crate::task::scheduler::insert_cap_for_task_under_ipc_transaction(
                    owner,
                    provisional,
                )
                .map_err(EndpointMintError::from_cnode)?;
            generation
        } else {
            0
        };

        let cap = Capability::new(
            id,
            real_gen,
            CapabilityRights::FULL,
            CapabilityKind::Endpoint,
            owner,
            None,
        );

        // Commit exactly one provenance record, then the endpoint object.
        self.entries.push(CapabilityEntry::new_minted(
            id,
            owner,
            None,
            CapabilityKind::Endpoint,
        ));

        // Reply cap'ler için kısıtlı hak (sadece reply için kullanılabilir)
        let rights = if is_reply {
            EndpointRights(EndpointRights::REPLY)
        } else {
            EndpointRights::default()
        };

        registry.push(Endpoint {
            id,
            badge,
            owner,
            pending_messages: crate::ipc_queue::BoundedQueue::new(),
            expecting_reply: false,
            rights,
            is_reply_cap: is_reply,
            rendezvous: crate::ipc_rendezvous::EndpointRendezvous::new(),
            reply_target,
        });

        crate::kprintln!(
            "[M6] Endpoint#{} mint edildi (badge={}, owner={}, reply_cap={})",
            id,
            badge,
            owner,
            is_reply
        );

        Ok(cap)
    }

    /// M6.1 — Belirli bir CapId'ye karşılık gelen Endpoint nesnesini döndürür.
    ///
    /// Multi-core hazırlığı: Artık `Endpoint` kopyasını döndürüyor (clone).
    /// Bu sayede lock guard dışarı sızmaz.
    pub fn lookup_endpoint(&self, id: CapId) -> Option<Endpoint> {
        ENDPOINT_REGISTRY
            .lock()
            .iter()
            .find(|e| e.id == id)
            .cloned()
    }

    /// M6.1 — Bir task'in sahip olduğu Endpoint capability'lerini (CNode öncelikli) listeler.
    pub fn endpoints_of_task(&self, task_id: u64) -> Vec<Capability> {
        self.capabilities_of_task(task_id)
            .into_iter()
            .filter(|c| c.kind == CapabilityKind::Endpoint)
            .collect()
    }

    /// M6.1 — Badge'e göre Endpoint arama (filtreleme için faydalı).
    ///
    /// SMP hazırlığı: Vec<&Endpoint> yerine Vec<Endpoint> (clone) veya closure döndürür.
    pub fn lookup_endpoints_by_badge(&self, badge: u64) -> Vec<Endpoint> {
        ENDPOINT_REGISTRY
            .lock()
            .iter()
            .filter(|e| e.badge == badge)
            .cloned()
            .collect()
    }

    /// M6.1 — Task'in Endpoint'lerini badge ile filtreleyerek döndürür.
    pub fn endpoints_of_task_filtered(&self, task_id: u64, badge: Option<u64>) -> Vec<Capability> {
        let mut caps = self.endpoints_of_task(task_id);
        if let Some(b) = badge {
            caps.retain(|c| self.lookup_endpoint(c.id).map_or(false, |ep| ep.badge == b));
        }
        caps
    }
}
snippet sha256: a423d1e39dd7file sha256: 304e1227daf9
02 · Doğrulayan test kodu

Operations komutuna bağlı focused test

tam Rust öğesiL22–L61
simulation/tests/capability_mint_source.rs::endpoint_mint_commits_only_after_capacity_and_cnode_preflight

#[test]
fn endpoint_mint_commits_only_after_capacity_and_cnode_preflight() {
    let mint = squash(between(
        CAPABILITY,
        "fn mint_endpoint_inner(",
        "/// M6.1 — Belirli bir CapId'ye karşılık gelen Endpoint nesnesini döndürür.",
    ));

    assert!(mint.contains("->Result<Capability,EndpointMintError>"));
    assert!(mint.contains("self.entries.try_reserve(1)"));
    assert!(mint.contains("registry.try_reserve(1)"));
    assert!(mint.contains("self.try_allocate_endpoint_id()?"));
    assert!(!mint.contains("fallback gen=1"));
    assert!(!mint.contains("self.mint(owner, CapabilityKind::Endpoint)"));
    assert_eq!(mint.matches("CapabilityEntry::new_minted(").count(), 1);

    let provenance_capacity = mint
        .find("self.entries.try_reserve(1)")
        .expect("provenance capacity preflight");
    let registry_capacity = mint
        .find("registry.try_reserve(1)")
        .expect("registry capacity preflight");
    let cnode_insert = mint
        .find(
            "crate::task::scheduler::insert_cap_for_task_under_ipc_transaction(owner,provisional,",
        )
        .expect("authoritative CNode insert");
    let provenance_commit = mint
        .find("self.entries.push(CapabilityEntry::new_minted(")
        .expect("single provenance commit");
    let registry_commit = mint
        .find("registry.push(Endpoint{")
        .expect("endpoint registry commit");

    assert!(provenance_capacity < registry_capacity);
    assert!(registry_capacity < cnode_insert);
    assert!(cnode_insert < provenance_commit);
    assert!(provenance_commit < registry_commit);
}
snippet sha256: 804a6f7bb9d3file sha256: ecc7845cc165
03 · Kapı kimlik kaydı

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

tam Operations kaydıL27477–L27520
website/src/lib/operations.ts::k2-bounded-ipc-abi-foundations-partial
  {
    id: "k2-bounded-ipc-abi-foundations-partial",
    date: "2026-08-22",
    sequence: 112,
    status: "passed",
    umbrella_status: "partial",
    title:
      "K2 temeli: ortak ABI, bounded IPC ve transactional endpoint otoritesi kaynakta kuruldu",
    summary:
      "Kernel ile iki userspace örneğinin syscall/capability/message sözleşmesi yeni no_std `aselsan_abi` crate'inde tek kaynağa indirildi. Endpoint başına sekiz elemanlı allocation-free FIFO, taşmada pre-mint `QueueFull`, one-shot reply authority ve revoke/rollback sırasında bekleyen çağrıyı uyandıran temizlik yolu uygulandı. 23 Ağustos source-only amendment'ında task endpoint/reply mint yolu typed error döndüren fail-closed transaction'a çevrildi: capacity preflight ve canlı CNode commit'i geçmeden provenance/registry yayımlanmıyor, provenance exact bir kez kaydediliyor, owner eşleşmesi CNode authority yerine kullanılamıyor ve kernel-shared endpoint ayrı açık API'den geçiyor. Ayrı bounded wait-table çekirdeği finite deadline, deterministic timeout sırası ve task/peer iptalini; notification çekirdeği ise büyümeyen coalescing u64 bitset'i modelliyor. Bu bir K2 temel taşıdır, tam IPC servisi değildir: wait/timeout ve notification politikası henüz scheduler/syscall yoluna bağlanmadı; capability transfer, shared-memory loan ve servis katmanı açık kalır.",
    evidence: [
      "Yeni workspace üyesi `abi`: no_std ortak syscall numaraları, `CapId`, `IpcError`, sabit IPC payload sözleşmesi ve endpoint queue capacity=8; crate unit testleri 2/2 PASS.",
      "IPC queue host davranış testleri 3/3, source-contract testleri 4/4 ve bounded wait/notification host testleri 3/3 PASS.",
      "Transactional endpoint mint kaynak kabulü düzeltme öncesi beklenen RED 0/3, düzeltme sonrası GREEN 3/3 verdi; odak ABI/IPC matrisi 17/17 PASS.",
      "CNode/task-not-found/full hatası artık typed `EndpointMintError` döndürür; görünür endpoint/reply nesnesi üretmez. Checked capability id, provenance ve registry capacity preflight'ı CNode commit'inden önce; exact tek provenance ve registry publish commit'ten sonradır.",
      "CALL authority yalnız current task CNode'undaki canlı endpoint capability veya explicit kernel-owned owner=0 endpoint ile geçer; `target_ep.owner == current_id` ghost-authority kısa yolu kaldırıldı.",
      "QueueFull reply-cap mint edilmeden döner; başarılı CALL için reply authority tek kullanımlıdır ve queued revoke/rollback caller wake + reply-cap cleanup yapar.",
      "WaitTable finite deadline'ları bounded kapasitede tutar, task/reply uniqueness uygular ve eşit deadline'da task ID ile deterministic seçim yapar; notification state büyüyen kuyruk yerine coalescing 64-bit maskedir.",
      "`hello` release build ve `ipc_demo --target aarch64-unknown-none --release` ortak ABI crate'iyle PASS; QEMU smoke ile QEMU/RPi4/RPi5 kernel build denetimleri IPC değişikliklerinden sonra PASS raporlandı.",
      "Amendment sonrası current serialized workspace 422/422 ve 67 grup PASS; board-qemu, board-rpi5, board-qemu+smp ve board-rpi5+smp AArch64 compile profilleri 4/4 PASS; QEMU hello+IPC+SEC5 smoke fault marker olmadan PASS.",
      "Kalıcı source-only özet: `docs/K2-Transactional-Endpoint-Mint-Proof.md`.",
      "Bu kaynak/yazılım amendment'ı fiziksel G8h zincirini ilerletmez: son boot/runtime PASS S92 BOOT8G, storage PASS S119, S123 physical raw REJECTED ve S124 archive/promotion STOP kalır.",
    ],
    commands: [
      "cargo test -p aselsan_abi",
      "cargo test -p aselsan_microkernel_simulation --test abi_contract_source --test ipc_queue_host --test ipc_queue_source --test ipc_wait_host",
      "cargo test -p aselsan_microkernel_simulation --test capability_mint_source -- --test-threads=1",
      "cargo test --workspace -- --test-threads=1",
      "cargo build --manifest-path userspace/hello/Cargo.toml --release",
      "cargo build --manifest-path userspace/ipc_demo/Cargo.toml --target aarch64-unknown-none --release",
      "make verify-qemu",
      "cargo check -p aselsan_kernel --target aarch64-unknown-none --no-default-features --features board-qemu",
      "cargo check -p aselsan_kernel --target aarch64-unknown-none --no-default-features --features board-rpi4",
      "cargo check -p aselsan_kernel --target aarch64-unknown-none --no-default-features --features board-rpi5",
      "cargo check -p aselsan_kernel --target aarch64-unknown-none --no-default-features --features board-qemu,smp",
      "cargo check -p aselsan_kernel --target aarch64-unknown-none --no-default-features --features board-rpi5,smp",
    ],
    limitations: [
      "Wait/timeout ve notification policy core henüz syscall dispatcher ve scheduler wake yoluna bağlanmış değildir.",
      "Capability transfer, timeout syscall ABI'si, shared-memory loan, init/servicemgr ve tam provenance teardown uygulanmış kabul edilmez; generic non-endpoint capability factory'leri ayrıca aynı transactional mint/teardown audit'ini bekler.",
      "K2 COMPLETE değildir; bu kayıt ortak ABI ve bounded IPC/lifecycle temelleri için PARTIAL'dır.",
      "Bu 23 Ağustos K2 amendment'ında DEVICE/DISK/UART/POWER/RAW işlemi 0'dır; tarihsel storage ve physical sayaçları yeniden yorumlanmaz. PHYSICAL_BOOT8H hâlâ NO_PASS ve S124 STOP'tur.",
    ],
  },
snippet sha256: 77566607e5c3file sha256: 9726dbf00f84
Focused test komutu
cargo test -p aselsan_microkernel_simulation --test capability_mint_source -- --test-threads=1
Registry schema v5 · generator website/scripts/generate-code-gates.mjs · Tam SHA-256: 3050638b71a684d8f8f947a8a6faa237a17fa8db5dc0db04fb207b668b462af9