Implementation Status

CambiOS Implementation Status

Living status doc. This file is the single source of truth for “what is currently built.” It is auto-refreshed when feature work lands (see CLAUDE.md § Post-Change Review Protocol Step 8). Pure intent and plans live in CambiOS.md and the design docs; this file is for current state.

If you’re trying to figure out “is X done yet?” — this is the doc to read. If you’re trying to figure out “should X be done a certain way?” — read the linked design doc instead.

At a glance

  • 447 unit tests passing on host (x86_64-apple-darwin)
  • x86_64: clean release build, boots in QEMU with 2 CPUs, 6 boot modules running (policy-service, key-store, fs-service, virtio-blk, compositor, shell). arcobj list/put/get works end-to-end; objects persist across reboots on virtio-blk. Compositor is the Phase Scanout-1 scaffold (ADR-014) — registers endpoint 28, enters headless mode, idles; no scanout-driver bound yet.
  • AArch64: clean release build, boots in QEMU virt, make img-aarch64 now builds + includes virtio-blk + compositor (same 6-module limine.conf as x86_64). Driver’s port-I/O init path is x86_64-specific — on AArch64 the driver enters no_device_loop() and ObjectStore stays RAM-backed until AArch64 device IRQ routing lands.
  • Bare metal: USB boot tooling complete (make img-usb builds GPT image; make usb DEVICE=/dev/diskN writes safely); not yet tested on target hardware (Dell Precision 3630)

Subsystem status

SubsystemStatusNotesCodeDesign
Microkernel coreDoneHeap, frame allocator, page tables, GDT/IDT (x86), VBAR_EL1 (AArch64)src/microkernel/, src/memory/CambiOS.md § The Microkernel
Per-CPU SMP schedulerDonePer-CPU schedulers, 4 priority bands, O(1) scheduling, task migration, push-based load balancingsrc/scheduler/SCHEDULER.md, ADR-001
Voluntary context switchDoneyield_save_and_switch (x86_64 + AArch64), synthetic exception framesrc/arch/x86_64/mod.rs, src/arch/aarch64/mod.rs
Preemptive context switchDoneTimer ISR with full register save, context switch hint, TLB shootdownsrc/arch/*/mod.rsADR-001
Capability-based IPC (control path)Done256-byte fixed messages, three-layer enforcement, sender_principal stamping, sharded per-endpointsrc/ipc/ADR-000, ADR-002, ADR-005
Capability bulk path (channels)Done (Phase 3.2d)Shared-memory channels: ChannelManager, 5 syscalls (28-32), CreateChannel system capability, channel-aware process exit cleanup, TLB shootdown on close/revoke, libsys wrappers. Producer/Consumer/Bidirectional roles with MMU-enforced access (RW/RO).src/ipc/channel.rs, src/syscalls/dispatcher.rs, src/ipc/capability.rs, user/libsys/ADR-005
Capability revocationDone (Phase 3.1, bootstrap-only)SYS_REVOKE_CAPABILITY (#27), CapabilityManager::revoke(), revoke_all_for_process() wired into handle_exit. Authority = bootstrap Principal only; grantor/revoke-right paths defer to Phase 3.4. Audit emit, channel mapping cleanup, policy cache invalidation, and active holder notification are in-code stubs citing Phase 3.2/3.3/3.4.src/ipc/capability.rs, src/syscalls/dispatcher.rsADR-007
CreateProcess capabilityDone (Phase 3.2b)CapabilityKind::CreateProcess system capability. handle_spawn checks authority before allocation. Granted to kernel processes (0-2) and all boot modules at boot. revoke_all_for_process clears system caps on exit.src/ipc/capability.rs, src/syscalls/dispatcher.rs, src/microkernel/main.rsADR-008 § Migration Path
Boot-time-sized kernel object tablesDone (Phase 3.2a+3.2b+3.2c+3.2d)MAX_PROCESSES removed as compile-time constant. num_slots computed at boot from config::ACTIVE_POLICY and frame allocator’s tracked memory. Kernel object table region allocated via FrameAllocator::allocate_contiguous, HHDM-mapped, carries ProcessTable and CapabilityManager slot storage as &'static mut slices. Per-process heap region allocated on demand and reclaimed on exit. Phase 3.2b: CapabilityKind::CreateProcess system capability. Phase 3.2c: ProcessId generation counters. Phase 3.2d: shared-memory channels (ChannelManager, 5 syscalls, CreateChannel cap), full process lifecycle cleanup (VMA reclaim, page table frame reclaim on exit), lock hierarchy renumbered (CHANNEL_MANAGER at position 5). CapabilityHandle refactor deferred to post-v1 handle table.src/config/tier.rs, src/memory/object_table.rs, src/process.rs, src/ipc/capability.rs, src/ipc/mod.rs, src/syscalls/dispatcher.rs, src/loader/mod.rs, src/microkernel/main.rs, build.rsADR-008
Deployment tiers / scopeDesigned, policy-onlyThree tiers (Tier 1 CambiOS-Embedded, Tier 2 CambiOS-Standard, Tier 3 CambiOS-Full). Single kernel binary across tiers; tier selection is an install-time choice that decides which TableSizingPolicy and which user-space services are loaded. No code gate yet.ADR-009, GOVERNANCE.md
Audit infrastructureDone (Phase 3.3)Kernel→userspace event streaming for security observability. Per-CPU lock-free staging buffers → global audit ring (64 KiB, 1023 event slots). 16 event types, audit::emit() at 14 instrumentation points. IPC send/recv sampled 1-in-100. Drain via BSP timer ISR piggyback (100 Hz). SYS_AUDIT_ATTACH (33) maps ring RO into consumer. SYS_AUDIT_INFO (34) returns stats.src/audit/, src/syscalls/dispatcher.rs, user/libsys/ADR-007
Policy serviceDesigned, not implementedUser-space externalization of on_syscall decisionsADR-006
Cryptographic identityDone (Phase 1C, hardware-backed + load-bearing)Bootstrap Principal from compiled-in YubiKey pubkey, IPC sender stamping, BindPrincipal/GetPrincipal syscalls, identity gate in syscall dispatcher (unidentified processes can only Exit/Yield/GetPid/GetTime/Print/GetPrincipal), recv_verified in libsys (userspace services structurally reject anonymous IPC senders)src/ipc/, src/syscalls/, user/libsys/, bootstrap_pubkey.binidentity.md, ADR-003
Signed ELF loadingDoneARCSIG trailer, Ed25519 signature verification, SignedBinaryVerifiersrc/loader/ADR-004
Content-addressed ObjectStoreDone (Phase 1C, RAM-backed)CambiObject with Blake3, Ed25519, ACL; RamObjectStore (256 objects)src/fs/ADR-003, ADR-004
Persistent ObjectStoreDone (Phase 4b)DiskObjectStore<B: BlockDevice> — generic disk-backed impl of ObjectStore (Phase 4a.i). On-disk format in ADR-010: 4 KiB blocks, superblock + 2-block record slots, commit-by-header-magic-write crash consistency, bounded-iteration mount scan. Phase 4b restructured the lazy init: boot installs RamObjectStore; each SYS_OBJ_* handler calls ensure_disk_store() BEFORE acquiring OBJECT_STORE. The IPC handshake with virtio-blk happens lock-free, then the DiskObjectStore is swapped in under the lock. This closes the spinlock-while-yielding window that previously stalled arcobj. End-to-end arcobj list/put/get/delete verified across reboots on virtio-blk (disk superblock magic ARCOBJ00 survives power cycle). On AArch64 (no driver device yet), handshake fails fast and RAM store persists — arcobj works, objects don’t survive reboot until AArch64 virtio-blk lands.src/fs/disk.rs, src/fs/block.rs, src/fs/lazy_disk.rs, src/fs/virtio_blk_device.rs, src/fs/mod.rs, src/syscalls/dispatcher.rs, src/lib.rsADR-010, FS-and-ID-design-plan.md
BlockDevice abstractionDone (Phase 4a.i)BlockDevice trait (read_block/write_block/flush/capacity_blocks at 4 KiB granularity) + in-kernel MemBlockDevice. The trait is the seam between DiskObjectStore and any storage backend — memory (testing), virtio-blk (4a.iii), NVMe/AHCI (post-v1).src/fs/block.rsADR-010
Key-store serviceDoneUser-space, IPC endpoint 17, runs in degraded mode (no runtime YubiKey access yet)user/key-store-service/
FS serviceDoneUser-space, IPC endpoint 16, ObjectStore gateway with sender_principal enforcementuser/fs-service/
Virtio-net driverDoneUser-space, IPC endpoint 20, PCI discovery, TX/RX virtqueues, DMA bounce buffers. Shares the legacy-virtio queue-size bug fixed in virtio-blk (Phase 4a.ii) — driver clamps queue size to 32 but the device thinks it’s 256, so completions land at an offset the driver never reads. Re-enable in limine.conf after applying the virtio-blk fix (use device-reported queue size, bump MAX_QUEUE_SIZE to 256). Tracked as a known issue.user/virtio-net/
Virtio-blk driverDone (Phase 4b)User-space. Endpoint 24 (user clients) + endpoint 26 (kernel-only, no identity check — trust by endpoint choice, mirror of policy service at 22). PCI discovery (vendor 0x1AF4, device 0x1001 legacy / 0x1042 modern), single request virtqueue with 3-descriptor chains, DMA bounce buffers, DeviceValue<T> hostile-device validation. Kernel commands on 26: HANDSHAKE, READ_BLOCK, WRITE_BLOCK, FLUSH, CAPACITY. Responses flow to endpoint 25 via the handle_write intercept. Phase 4b: dual-endpoint service loop uses SYS_TRY_RECV_MSG = 37 (non-blocking) to poll both endpoints without parking on one — blocking on ep24 would miss wakes targeted at ep26. Now builds + runs on AArch64 too (make img-aarch64 includes it); driver falls through to no_device_loop when QEMU virt has no virtio-blk attached.user/virtio-blk/ADR-010
Intel I219-LM driverScaffolded, untested on hardwareUser-space, same IPC interface as virtio-net for bare-metal targetuser/i219-net/
UDP/IP stackDoneUser-space, IPC endpoint 21, ARP, IPv4, UDP, NTP demouser/udp-stack/
DHCP clientPre-work landed in udp-stack; client pausedUDP stack has CMD_SET_CONFIG and CMD_DHCP_SEND helpers; the client itself is paused pending channel architecturepartial in user/udp-stack/
DNS resolverPlannedStub resolver over UDP, caches results
TCP stackPlannedConnection state machine, retransmission, sliding window
ShellDoneInteractive shell over serial, command parsing. Phase 4a.iv adds arcobj put/get/list/delete (fs-service client, shell endpoint 18) — exercises the full SYS_OBJ_* → LazyDiskStore → VirtioBlkDevice → driver path end-to-end.user/shell/
Spawn / WaitTask syscallsDoneNew process creation from boot module by name; parent waits for child exitsrc/syscalls/dispatcher.rs, src/boot_modules.rs
PCI bus discoveryDoneBus 0 scan at boot, device table via DeviceInfo syscallsrc/pci/
Device syscallsDoneMapMmio, AllocDma, DeviceInfo, PortIosrc/syscalls/dispatcher.rs
Bootloader abstractionDone (Phase GUI-0)BootInfo + src/boot/ module isolates the kernel from Limine types (MemoryRegion, FramebufferInfo, ModuleInfo). boot::limine::populate is the only site that reads limine::* responses outside the one early HHDM read; every subsequent consumer uses boot::info(). Prepares for camBIOS firmware replacement without kernel-wide refactor. SMP/AP wakeup not yet abstracted (deeper coupling; deferred).src/boot/mod.rs, src/boot/limine.rs, src/microkernel/main.rsADR-011
SYS_MAP_FRAMEBUFFER + graphics capsDone (Phase GUI-0, unwired)SyscallNumber::MapFramebuffer = 35 returns a 32-byte FramebufferDescriptor to user-space (vaddr + geometry + pixel format). Capability-gated via CapabilityKind::MapFramebuffer. LegacyPortIo and LargeChannel capability kinds landed alongside; all three are unwired (granted to nobody today) awaiting Phase GUI-1+ consumers. libsys wrappers wait_irq + map_framebuffer added.src/syscalls/dispatcher.rs, src/ipc/capability.rs, user/libsys/src/lib.rsADR-011
Compositor scaffoldDone (Phase Scanout-1)user/compositor boot module: registers COMPOSITOR_ENDPOINT = 28, selects a ScanoutBackend (today always HeadlessBackend since no scanout-driver service exists), enters no-op render loop. The full ScanoutBackend trait surface + wire-format types (DisplayInfo, Geometry, Mode, PixelFormat, ScanoutBuffer, ScanoutError, ScanoutEvent, Rect) are present as the protocol contract; VirtioGpuBackend / IntelGpuBackend / LimineFbBackend implementors land Scanout-2 onward. Compositor has zero hardware syscall surface (no MapMmio, no MapFramebuffer, no AllocDma) — modular boundary per ADR-014 is load-bearing. Boots cleanly on x86_64 QEMU; aarch64 builds but compositor requires no arch-specific behavior.user/compositor/ADR-014
GIC + ARM Generic Timer (AArch64)DoneGICv3 (Distributor + Redistributor + ICC sysregs), CNTP at 100Hzsrc/arch/aarch64/gic.rs, src/arch/aarch64/timer.rs
APIC + I/O APIC (x86_64)DoneLocal APIC timer at 100Hz, I/O APIC for device IRQs, SMP IPIsrc/arch/x86_64/apic.rs, src/arch/x86_64/ioapic.rs
TLB shootdownDonex86_64 via vector 0xFE IPI; AArch64 via TLBI broadcastsrc/arch/*/tlb.rs
AArch64 SMP timer on APKnown issueAP timer PPI not firing in QEMU virt; single-CPU works fully
AArch64 device IRQ routingGapGIC enable_spi/set_spi_trigger exist but not wired into boot path
USB boot toolingDonemake img-usb builds GPT-partitioned UEFI image; make usb DEVICE=... writes safely with confirmationMakefile
Yggdrasil mesh networkingPlannedIdentity-routed overlay network (post-DNS/TCP)identity.md
TLS transportPlanned (post-v1)TLS 1.3 over TCP
VFS / mount infrastructurePlanned (post-v1)Mount table, path resolution, namespace isolation
USB HID driverPlanned (post-v1)XHCI host controller, HID device support; prerequisite for runtime YubiKey
DID resolutionPlanned (post-v1)did:key method per identity.mdidentity.md
Identity revocation (per identity.md)Planned (post-v1)Eventually-consistent revocation via signed objects in social logidentity.md
Process lifecycle cleanupDone (Phase 3.2d.ii)handle_exit performs full cleanup: capability revocation, channel revocation (unmap + TLB shootdown + frame free), VMA region reclaim, page table frame reclaim (PML4 + intermediates), heap reclaim. purge_task evicts exiting task from scheduler ready queues. Kernel stack dealloc deferred (bounded 32 KiB/process leak, requires scheduler-level deferred-free).src/syscalls/dispatcher.rs, src/process.rs, src/memory/paging.rs, src/memory/mod.rs
AArch64 user-space servicesDoneAll boot modules build for both targets via libsys shared syscall wrappers (x86_64 syscall + AArch64 svc)user/libsys/
RISC-V (riscv64gc) portIn progress (Phase R-2 done 2026-04-16)Third architecture backend, parity-targeted with x86_64/AArch64. Phase R-2 milestone: make run-riscv64 boots under OpenSBI, trampolines from physical 0x80200000 to higher-half VMA 0xffffffff80200000 via Sv48 paging, parses DTB for /memory region, brings up frame allocator (4 GiB tracked, ~4 GiB free) + 4 MiB kernel heap at phys 0x80400000, and Box::new(0xcab105deadbeef) round-trips cleanly. Implements: Sv48 boot page table in src/arch/riscv64/entry.rs (L3[0]+L3[256] via shared L2_IDENTITY, L3[511] via L2_KERNEL; gigapage leaves; HHDM at 0xffff800000000000); hand-rolled FDT parser in src/boot/riscv.rs (bounded iteration, /memory@* walk, OpenSBI/DTB/kernel reservations); overlay-aware init_kernel_heap (picks lowest-base non-Usable overlay first — handles the DTB “full RAM as one Usable + overlay reservations” model that would otherwise collide heap with OpenSBI’s PMP-protected range); non-Usable reservation pass in init_frame_allocator (portable improvement for any protocol delivering overlay reservations). Phase R-1 carry-forward: src/arch/riscv64/ skeleton (percpu via tp+sscratch, syscall/tlb/plic/timer stubs, _start asm), NS16550 UART, riscv64 arms across lib.rs/dispatcher/policy/platform/loader/audit, kmain_riscv64(hart_id, dtb_phys) entry. Phase R-2.d (shared paging module RISC-V PTE arm) deferred to R-3/R-4 where consumers land (early_map_mmio for PLIC in R-3, process page tables in R-4) — per feedback-skip-test-hooks: don’t build arms ahead of consumers. Bootloader = OpenSBI + custom S-mode _start (no Limine on RISC-V). Hardware target = TBD CambiOS-designed; QEMU virt for dev.src/arch/riscv64/, src/boot/riscv.rs, src/microkernel/main.rs (kmain_riscv64, init_kernel_heap, init_frame_allocator), linker-riscv64.ld, MakefileADR-013
AI pre-execution code analysisPlanned (post-v1)JIT analysis of ELF binaries before executionCambiOS.md § AI Integration
Behavioral anomaly detection (AI)Planned (post-v1)Runtime monitoring service consuming audit telemetryADR-007, PHILOSOPHY.md
AI compatibility layer (Win32)Planned (post-v1)Long-term vision item from CambiOS.mdCambiOS.md § Application Compatibility
Formal verification (Kani)Started 2026-04-16First proof live: BuddyAllocator::free rejects every offset inside the reserved prefix, for all prefix sizes in [16, 256] bytes (Kani 0.67.0, 150 checks pass in ~18s). Proof crate path-includes the kernel’s buddy_allocator.rs so the proven source is the same source the kernel compiles — no fork. Run via make verify. Next candidates: allocate-then-free roundtrip, non-overlapping allocations, double-free rejection; widen prefix bound from 256 to allocator-state size (~20 KiB) once mark_range unwind cost is measured.verification/buddy-proofs/

Phase markers

CambiOS uses informal phases to mark identity/storage milestones. These phases are referenced from identity.md and FS-and-ID-design-plan.md.

PhaseGoalStatus
Phase 0Identity primitives in kernel + RAM-backed ObjectStore. Stamps unforgeable identity on every IPC message; gives every stored object an author and owner.Done
Phase 1Real cryptography. Blake3 hashing, Ed25519 signature verification on objects, signed ELF modules, key store as user-space service.Done
Phase 1BHardware-backed bootstrap identity. YubiKey-derived public key compiled into kernel; private key never enters kernel memory.Done
Phase 1CKey-store service degraded mode + signed ObjectStore puts. fs-service requests signing from key-store before ObjPutSigned; no unsigned fallback — objects cannot be stored without a valid signature. Identity is load-bearing: kernel identity gate + userspace recv_verified create structural dependency on the security model.Done
Phase 2AFirst user-space hardware driver. Virtio-net with PCI discovery, virtqueues, DMA bounce buffers, hostile-device validation.Done
Phase 2BFirst user-space network service. Stateless UDP/IP over virtio-net, with NTP demo.Done
Phase 3Architecture: bulk data path (channels) + externalized policy + capability revocation + audit infrastructure. The substrate that real workloads (video, file I/O, AI inference) need.In progress: 3.1 (revocation primitive) landed; 3.2a (boot-time-sized object tables) landed; 3.2b (CreateProcess capability) landed; 3.2c (ProcessId generation counter) landed; 3.2d (shared-memory channels + process lifecycle cleanup) landed; 3.3 (audit infrastructure) landed — see ADR-007. 3.4 (policy service) pending
Phase 4Persistent storage. Virtio-blk driver, disk-backed ObjectStore, CambiObject CLI in shell.Done (Phase 4a: disk-format + driver + kernel adapter + arcobj CLI; Phase 4b: boot-cleanup pass + closed the IPC stall that prevented arcobj from actually completing). Phase 4b specifically landed: hello.elf removed from the boot chain (print-and-exit canary that masked the exit-path scheduler bug once, now eclipsed); [Tick] idle heartbeat removed (noise-only); AArch64 img-aarch64 now builds virtio-blk; SYS_TRY_RECV_MSG = 37 syscall (non-blocking recv for services polling multiple endpoints); REPLY_ENDPOINT registry fixes the msg.from_endpoint() routing bug (replies now land on the sender’s registered endpoint, not their pid slot); LazyDiskStoreensure_disk_store() — lazy init moved outside the OBJECT_STORE spinlock. End-to-end arcobj list/put/get/delete verified across reboots. The originally-planned Phase 4b (“ObjectStore ownership into fs-service + bulk channel IPC”) is a separate, later piece of work — not required for v1 arcobj, deferred.
Phase 5Identity-routed networking. Yggdrasil peer service, Ed25519→IPv6 mapping, mesh routing without DNS.Planned
Phase 6Biometric commitment + key recovery. Retinal/facial ZKP enrollment, social attestation, key rotation protocol.Planned (post-v1)
Phase 7SSB bridge. Cross-instance capability grants and identity attestations over append-only logs.Planned (post-v1)

RISC-V port phases (parallel track — see ADR-013)

PhaseGoalStatus
R-0Build infrastructure: rust-toolchain target, .cargo/config.toml block, linker-riscv64.ld, Makefile targets including make check-all tri-arch gate. Verify cargo build --target riscv64gc-unknown-none-elf resolves.Done (2026-04-15)
R-1First serial output. OpenSBI hand-off, S-mode _start boot stub, NS16550 UART, minimal kmain_riscv64(hart_id, dtb_phys) reaches println.Done (2026-04-16) — kernel boots in QEMU virt, prints banner, halts. Sv48 boot trampoline + DTB parser pulled forward into R-2 per ADR-013 Decision 3 fallback (R-1 ran at 0x80200000 physical=virtual with paging off).
R-2Memory management. Sv48 boot trampoline, higher-half kernel at 0xffffffff80000000, hand-rolled DTB parser for /memory, frame-allocator init with overlay-aware reservations (OpenSBI, DTB, kernel image), kernel heap, Box::new end-to-end.Done (2026-04-16) — milestone: Sv48 higher-half boot + DTB parse + 4 MiB heap + Box::new(0xcab105deadbeef) round-trips. Fixed a pre-existing FDT field-order bug (size_dt_strings/size_dt_struct at offsets 32/36) surfaced by fresh DTB integration. R-2.d (shared paging module RISC-V PTE arm) deferred to R-3/R-4 consumers — no early compile-only arms.
R-3Interrupts + preemptive scheduling. Single trap vector, scause dispatch, SBI timer, PLIC driver, context switch (callee-saved + sepc/sstatus), GDT shim.Planned
R-4User space. ELF EM_RISCV (0xF3), libsys ecall stubs, hello-riscv64 program, U/S privilege transition via sscratch/tp swap.Planned
R-5SMP. Hart enumeration from DTB, sbi_hart_start, SBI IPI for remote TLB shootdown (probe Svinval). Triggers BootProtocol-trait factoring decision.Planned
R-6Full service parity. PCI ECAM MMIO, virtio-mmio transport, boot modules via -initrd, all user-space services (policy, ks, fs, virtio-blk, shell).Planned

v1 Roadmap progress

The v1 milestone is “interactive, network-capable, identity-rooted OS running on real hardware with persistent storage.” Items in dependency order:

#ItemStatus
1ShellDone
2USB boot tooling (Dell 3630)Done (untested on target hardware)
3Intel I219-LM NIC driverScaffolded (untested on target hardware)
4DHCP clientPaused (pre-work landed in udp-stack; pending Phase 3 architecture)
5DNS resolverPlanned
6TCP stackPlanned
7Virtio-blk driverDone (Phase 4a.ii + 4b cross-arch build)
8Persistent ObjectStoreDone (Phase 4b: end-to-end arcobj via ensure_disk_store() + REPLY_ENDPOINT registry + SYS_TRY_RECV_MSG)
9CambiObject CLIDone (Phase 4a.iv — arcobj put/get/list/delete in the shell)
10Yggdrasil peer servicePlanned

Currently blocking the v1 sequence: Phase 3.4 (policy service). Revocation (Phase 3.1), channels (Phase 3.2d), and audit infrastructure (Phase 3.3) are done. Once the policy service exists, items 4-10 sit on top of it and proceed in order.

Test coverage

SubsystemTestsNotes
Scheduler35Creation, init, lifecycle, schedule, time slice, block/wake, IRQ/message wake, idle immutability, migration primitives, invariants
Capability manager40Grant, verify, delegation, escalation prevention, capacity limits, Principal bind/get, revocation authority checks, revoke_all_for_process cleanup, system capability (CreateProcess + CreateChannel) grant/check/revoke/idempotency/independence/cleanup, ProcessId generation counter stale-reference rejection, ProcessId encoding round-trip, error-path coverage
IPC interceptor13Payload validation, bounds, self-send, delegation policy, syscall filtering, custom interceptors
ELF verifier14W^X, kernel space rejection, overlapping segments, memory limits, entry point boundary cases, signed binary verifier
IPC sender_principal4Default None, kernel stamping, no-principal path, direct send bypass
ObjectStore types + crypto21Principal equality, Blake3 hashing, Ed25519 sign/verify, CambiObject creation/author immutability/owner/lineage, ObjectCapSet
RamObjectStore12Put/get, idempotency, invalid hash rejection, delete, list, capacity, slot reuse, author/owner preservation
BlockDevice abstraction (Phase 4a.i)11MemBlockDevice zero-init, read/write round-trip, block isolation, out-of-bounds, flush no-op, full-pattern sweep, error Display
DiskObjectStore (Phase 4a.i)30Superblock encode/decode + blank/wrong-magic/corrupt-checksum classification, record-header encode/decode + torn-write treated as free + oversized-content rejection, FreeMap ops, format+put+get, idempotent put, delete + slot reuse, capacity exhaustion, list, reboot preserves objects, reboot preserves signed-and-verified object, reboot after delete, reboot with store at capacity, generation counter bump on mount, corrupt-superblock rejection, torn-header invisible after remount, orphan-content-block is reusable (crash between content and header write), undersized device fails, LBA math
Memory subsystem~37Buddy allocator, frame allocator (including Phase 3.2a free_contiguous round-trip + atomicity tests), heap, paging primitives; allocate_contiguous at HEAP_PAGES (Phase GUI-0 bounds bump, ADR-011)
Tier configuration (Phase 3.2a)16TableSizingPolicy field bounds, num_slots_from clamp behavior, realistic memory sizes (256 MB / 4 GB / 8 GB / 32 GB / 1 TB) per tier, monotonicity, binding_constraint_for per clamp, slot-clamp-shadows-budget-clamp invariant
Kernel object table region (Phase 3.2a)5region_bytes_for page-aligned and monotonic, init produces disjoint valid slices with None initialization, rejects zero slots, propagates frame-alloc failure
Channel manager (Phase 3.2d)29ChannelId encoding, ChannelRole permissions, create/attach/close/revoke state machine, table full, principal mismatch, stale generation, slot reuse, revoke_all_for_process, preserve-bystander; create-at-MAX_CHANNEL_PAGES ceiling test (Phase GUI-0 bounds bump, ADR-011)
Process lifecycle cleanup (Phase 3.2d.ii)3VMA reclaim (empty, drains tracker, kernel task noop)
Audit staging buffer (Phase 3.3)14SPSC ring: push, drain, wrap-around, overflow, interleaved, capacity cycles, take_dropped
Audit event types (Phase 3.3)18Event kind discriminants, wire format size, builder round-trips for all 16 event types, timestamp/sequence encoding
Audit ring + drain (Phase 3.3)12Ring header magic/capacity, write/wrap, drain from staging, staging drop reporting, batch bound, consumer attach/detach, capacity math
AArch64 portable logic12PerCpu offsets, GIC register math, page table descriptor flags
Other~70Timer, IPC sync channel, ProcessTable, VMA tracker, syscall args, etc.
Total447All passing on x86_64-apple-darwin

Run with: RUST_MIN_STACK=8388608 cargo test --lib --target x86_64-apple-darwin

Known issues

  • AArch64 SMP timer on AP: PPI 30 (ARM Generic Timer) does not fire on the second CPU in QEMU virt. Single-CPU mode works fully. Investigation pending; may be a QEMU configuration issue or a missing GIC redistributor configuration step on the AP path.
  • AArch64 device IRQ routing: GIC enable_spi() / set_spi_trigger() exist as functions but are not called from the boot path or handle_wait_irq(). Device IRQs (virtio, PL011 RX) are not yet functional on AArch64. Affects virtio-blk polling-mode viability too — deferred.
  • Legacy-virtio queue-size clamping (virtio-net): user/virtio-net/src/main.rs caps the virtqueue at 32 entries, but the device advertises more (QEMU: 256) and legacy virtio’s Queue Size register is read-only — the driver MUST use the device-reported size. The mismatch puts avail/used rings at different offsets on the two sides, so completions never arrive. Diagnosed during Phase 4a.ii. Fix: bump MAX_QUEUE_SIZE to 256 and drop the clamp (the virtio-blk driver does this). Re-enable the network drivers in limine.conf only after fixing this.
  • fb-demo (Phase GUI-1) blocks Phase 4a services when both are enabled: When fb-demo is in limine.conf alongside the Phase 4a modules (fs-service, virtio-blk, shell), fb-demo’s SYS_MAP_FRAMEBUFFER call completes kernel-side (kernel prints [fb-syscall] write_user_buffer rc=Ok(32)) but fb-demo’s userspace never prints [FB-DEMO] after syscall, and the subsequent boot modules (fs-service, virtio-blk, shell) never reach their service loops. Root cause undiagnosed; likely an issue in the framebuffer syscall’s return path or fb-demo’s expectations about the mapping. Temporarily disabling fb-demo.elf in limine.conf lets the Phase 4a chain come up cleanly. Not a Phase 4a bug — it’s a Phase GUI-1 concern — but listed here because it affects the arcobj interactive demo.
  • Boot module ordering is non-deterministic Resolved. Sequential boot-time module loading landed: SYS_MODULE_READY = 36 + BlockReason::BootGate + BOOT_MODULE_ORDER static. Each boot module’s _start calls sys::module_ready() after endpoint registration; modules boot in dependency order (policy → ks → fs → virtio-blk → shell → hello.elf). limine.conf reordered accordingly.
  • Intermittent kernel page fault in Scheduler::schedule during task-exit cleanup Resolved. Root cause was two interacting bugs: (1) handle_exit did not purge the exiting task from the scheduler’s ready queues, leaving a stale TaskId that later dereferenced a freed slot; (2) ChannelManager::revoke_all_for_process returned a [Option<ChannelRecord>; MAX_CHANNELS] (~36 KiB) on the 8 KiB kernel stack, overflowing into adjacent task stacks and corrupting the BSP scheduler’s data. Fixes: Scheduler::purge_task(tid) helper added (called from handle_exit before yield_save_and_switch), revoke_all_for_process changed to return Vec<ChannelRecord>, and KERNEL_STACK_SIZE bumped from 8 KiB to 32 KiB.
  • ELF loader doesn’t merge overlapping segment permissions: If two PT_LOAD segments share a page with different permissions, the first segment’s permissions win. Worked around in user-space linker scripts via ALIGN(4096) before .data. Loader fix is roadmap item 20.
  • Kernel stack not freed on process exit: handle_exit now performs full cleanup (capabilities, channels, VMAs, page table frames, heap) as of Phase 3.2d.ii. The 32 KiB kernel stack per task is the remaining leak — freeing it requires a deferred-dealloc mechanism (can’t free the stack you’re running on). The leak is bounded by num_slots × 32 KiB (~6.4 MiB worst case). Scheduled for a dedicated cleanup pass.
  • Pre-existing user-space driver warnings: cargo build on the user/virtio-net/ and user/i219-net/ crates emits dead_code / unused_imports warnings for scaffolded driver state (PCI field metadata, unused transport constants, phy_read/phy_write stubs, DmaBuf::zero, etc.). These are excluded from the main kernel workspace (Cargo.toml exclude list) so they do not affect kernel builds, but surface when make run invokes them. Not a correctness issue — the fields/methods are staged for future use. Tracking here so they get cleaned up when the respective drivers get their next real-hardware bring-up pass.
  • Virtio-net TX completion may require yield to idle on QEMU TCG: QEMU TCG defers virtio TX processing to its event loop, which runs during guest hlt. The driver yields and the idle task hlts, which works for small bursts but the UDP stack’s ARP retry/timeout logic doesn’t yet exploit this fully.
  • Clippy warnings (~125 remaining, down from 164): Auto-fixable suggestions applied; doc formatting and module-level comment style fixed. Remaining breakdown: ~67 multiple_unsafe_ops_per_block (unsafe block splitting in arch code — debatable in hardware-adjacent code), ~25 missing // SAFETY: comments, ~12 static_mut_refs (Rust 2024 edition migration — IDT/GDT/TSS patterns need UnsafeCell or addr_of!), ~20 new_without_default suggestions. Scheduled for a dedicated cleanup pass between Phase 3.2d (channels) and Phase 3.3 (telemetry), before the static mut deprecation becomes a hard error.

Cross-references

  • CambiOS.md — source-of-truth architecture document
  • identity.md — identity architecture (Phases 0-7 are defined here)
  • FS-and-ID-design-plan.md — settled decisions for the identity + storage layer
  • SECURITY.md — enforcement status table (security-specific subset of this document)
  • GOVERNANCE.md — project governance, deployment tiers, scope boundaries (companion to ADR-009)
  • ASSUMPTIONS.md — catalog of every numeric bound in kernel code with SCAFFOLDING / ARCHITECTURAL / HARDWARE / TUNING category
  • README.md — public-facing summary
  • SCHEDULER.md — scheduler implementation reference
  • docs/adr/ — architecture decision records (ADRs 000-013)
  • CLAUDE.md — kernel technical reference and required-reading map