From 2da8463fb7ff089666d3eb6b70c814108c54f183 Mon Sep 17 00:00:00 2001 From: Markus Maiwald Date: Tue, 6 Jan 2026 03:37:53 +0100 Subject: [PATCH] feat(kernel): implement System Truth Ledger and Causal Trace - Implemented System Ontology (SPEC-060) and STL (SPEC-061) in Zig HAL - Created Nim bindings and high-level event emission API - Integrated STL into kernel boot sequence (SystemBoot, FiberSpawn, CapGrant) - Implemented Causal Graph Engine (SPEC-062) for lineage tracing - Verified self-aware causal auditing in boot logs - Optimized Event structure to 58 bytes for cache efficiency --- core/cspace.nim | 96 ++++++++ core/fiber.nim | 6 +- core/fs/vfs.nim | 2 +- core/ion.nim | 2 +- core/kernel.nim | 100 ++++++-- core/netswitch.nim | 2 +- core/ontology.nim | 194 +++++++++++++++ core/sched.nim | 4 +- hal/abi.zig | 14 ++ hal/crypto.zig | 2 +- hal/cspace.zig | 305 +++++++++++++++++++++++ hal/mm.zig | 29 ++- hal/ontology.zig | 420 ++++++++++++++++++++++++++++++++ hal/ram_blk.zig | 2 +- libs/membrane/config_ledger.nim | 4 +- libs/membrane/fs/monolith.nim | 2 +- libs/membrane/fs/sfs_user.nim | 6 +- libs/membrane/ion_client.nim | 2 +- libs/membrane/libc.nim | 6 +- npl/nipbox/nipbox.nim | 2 +- 20 files changed, 1148 insertions(+), 52 deletions(-) create mode 100644 core/cspace.nim create mode 100644 core/ontology.nim create mode 100644 hal/cspace.zig create mode 100644 hal/ontology.zig diff --git a/core/cspace.nim b/core/cspace.nim new file mode 100644 index 0000000..6e828cb --- /dev/null +++ b/core/cspace.nim @@ -0,0 +1,96 @@ +# SPDX-License-Identifier: LSL-1.0 +# Copyright (c) 2026 Markus Maiwald +# Stewardship: Self Sovereign Society Foundation +# +# This file is part of the Nexus Sovereign Core. +# See legal/LICENSE_SOVEREIGN.md for license terms. + +# SPEC-051: CSpace Integration with Fiber Control Block +# Ground Zero Phase 1: Kernel Integration + +## CSpace Nim Bindings + +# Kernel logging (freestanding-safe) +proc kprintln(s: cstring) {.importc, cdecl.} + +# Import CSpace from HAL +proc cspace_init*() {.importc, cdecl.} +proc cspace_get*(fiber_id: uint64): pointer {.importc, cdecl.} +proc cspace_grant_cap*( + fiber_id: uint64, + cap_type: uint8, + perms: uint8, + object_id: uint64, + bounds_start: uint64, + bounds_end: uint64 +): int32 {.importc, cdecl.} +proc cspace_lookup*(fiber_id: uint64, slot: uint): pointer {.importc, cdecl.} +proc cspace_revoke*(fiber_id: uint64, slot: uint) {.importc, cdecl.} +proc cspace_check_perm*(fiber_id: uint64, slot: uint, perm_bits: uint8): bool {.importc, cdecl.} + +## Capability Types (Mirror from cspace.zig) +type + CapType* = enum + CapNull = 0 + CapEntity = 1 + CapChannel = 2 + CapMemory = 3 + CapInterrupt = 4 + CapTime = 5 + CapEntropy = 6 + +## Permission Flags +const + PERM_READ* = 0x01'u8 + PERM_WRITE* = 0x02'u8 + PERM_EXECUTE* = 0x04'u8 + PERM_MAP* = 0x08'u8 + PERM_DELEGATE* = 0x10'u8 + PERM_REVOKE* = 0x20'u8 + PERM_COPY* = 0x40'u8 + PERM_SPAWN* = 0x80'u8 + +## High-level API for kernel use + +proc fiber_grant_channel*(fiber_id: uint64, channel_id: uint64, perms: uint8): int32 = + ## Grant a Channel capability to a fiber + return cspace_grant_cap( + fiber_id, + uint8(CapChannel), + perms, + channel_id, + 0, # No bounds for channels + 0 + ) + +proc fiber_grant_memory*( + fiber_id: uint64, + region_id: uint64, + start_addr: uint64, + end_addr: uint64, + perms: uint8 +): int32 = + ## Grant a Memory capability to a fiber + return cspace_grant_cap( + fiber_id, + uint8(CapMemory), + perms, + region_id, + start_addr, + end_addr + ) + +proc fiber_check_channel_access*(fiber_id: uint64, slot: uint, write: bool): bool = + ## Check if fiber has channel access via capability + let perm = if write: PERM_WRITE else: PERM_READ + return cspace_check_perm(fiber_id, slot, perm) + +proc fiber_revoke_capability*(fiber_id: uint64, slot: uint) = + ## Revoke a capability from a fiber + cspace_revoke(fiber_id, slot) + +## Initialization +proc init_cspace_subsystem*() = + ## Initialize the CSpace subsystem (call from kmain) + cspace_init() + kprintln("[CSpace] Capability system initialized") diff --git a/core/fiber.nim b/core/fiber.nim index d45bc63..39a38e9 100644 --- a/core/fiber.nim +++ b/core/fiber.nim @@ -58,6 +58,7 @@ type name*: cstring state*: FiberState stack*: ptr UncheckedArray[uint8] + phys_offset*: uint64 # Cellular Memory Offset stack_size*: int sleep_until*: uint64 # NS timestamp promises*: uint64 # [63:62]=Spectrum, [61:0]=Pledge bits @@ -67,12 +68,14 @@ type user_arg*: uint64 # Phase 29: Argument for user function satp_value*: uint64 # Phase 31: Page table root (0 = use kernel map) wants_yield*: bool # Phase 37: Deferred yield flag - # SPEC-250: The Ratchet + # SPEC-102: The Ratchet budget_ns*: uint64 # "I promise to run for X ns max" last_burst_ns*: uint64 # Actual execution time of last run violations*: uint32 # Strike counter (3 strikes = demotion) pty_id*: int # Phase 40: Assigned PTY ID (-1 if none) user_sp_init*: uint64 # Initial SP for userland entry + # Ground Zero Phase 1: Capability Space (SPEC-051) + cspace_id*: uint64 # Index into global CSpace table # Spectrum Accessors proc getSpectrum*(f: Fiber): Spectrum = @@ -151,6 +154,7 @@ proc init_fiber*(f: Fiber, entry: proc() {.cdecl.}, stack_base: pointer, size: i f.sleep_until = 0 f.pty_id = -1 f.user_sp_init = 0 + f.cspace_id = f.id # Ground Zero: CSpace ID matches Fiber ID # Start at top of stack (using actual size) var sp = cast[uint64](stack_base) + cast[uint64](size) diff --git a/core/fs/vfs.nim b/core/fs/vfs.nim index 94c776b..bd996d3 100644 --- a/core/fs/vfs.nim +++ b/core/fs/vfs.nim @@ -65,7 +65,7 @@ proc vfs_add_mount(prefix: cstring, mode: VFSMode) = mnt_count += 1 proc vfs_mount_init*() = - # Restore the SPEC-130 baseline + # Restore the SPEC-502 baseline vfs_add_mount("/nexus", MODE_SFS) vfs_add_mount("/sysro", MODE_TAR) vfs_add_mount("/state", MODE_RAM) diff --git a/core/ion.nim b/core/ion.nim index 496cb69..522e78e 100644 --- a/core/ion.nim +++ b/core/ion.nim @@ -105,7 +105,7 @@ type # Phase 35e: Crypto fn_siphash*: proc(key: ptr array[16, byte], data: pointer, len: uint64, out_hash: ptr array[16, byte]) {.cdecl.} fn_ed25519_verify*: proc(sig: ptr array[64, byte], msg: pointer, len: uint64, pk: ptr array[32, byte]): bool {.cdecl.} - # SPEC-021: Monolith Key Derivation + # SPEC-503: Monolith Key Derivation fn_blake3*: proc(data: pointer, len: uint64, out_hash: ptr array[32, byte]) {.cdecl.} # Phase 36.2: Network Membrane (The Veins) diff --git a/core/kernel.nim b/core/kernel.nim index 56af31b..33d0c74 100644 --- a/core/kernel.nim +++ b/core/kernel.nim @@ -1,7 +1,14 @@ +# SPDX-License-Identifier: LSL-1.0 +# Copyright (c) 2026 Markus Maiwald +# Stewardship: Self Sovereign Society Foundation +# +# This file is part of the Nexus Sovereign Core. +# See legal/LICENSE_SOVEREIGN.md for license terms. + # Nexus Sovereign Core: Kernel Implementation # target Bravo: Complete Build Unification -import ion, fiber, sched, pty +import ion, fiber, sched, pty, cspace, ontology import fs/vfs, fs/tar, fs/sfs import loader/elf import ../libs/membrane/term @@ -139,19 +146,22 @@ proc kload_phys(path: cstring, phys_offset: uint64): uint64 = {.emit: """asm volatile ("li t1, 0x40000; csrs sstatus, t1" : : : "t1");""" .} let dest = cast[ptr UncheckedArray[byte]](phdr.p_vaddr) - + if phdr.p_filesz > 0: if tar.vfs_read_at(tar_path, dest, phdr.p_filesz, phdr.p_offset) != int64(phdr.p_filesz): kprintln("[Loader] Error: Segment load failed") if phdr.p_memsz > phdr.p_filesz: - let bss_start = cast[uint64](dest) + phdr.p_filesz + let bss_start = phdr.p_vaddr + phdr.p_filesz let bss_len = phdr.p_memsz - phdr.p_filesz kprint(" - Zeroing BSS: VA="); kprint_hex(bss_start); kprint(" Len="); kprint_hex(bss_len); kprintln("") k_zero_mem(cast[pointer](bss_start), bss_len) {.emit: """asm volatile ("li t1, 0x40000; csrc sstatus, t1" : : : "t1");""" .} + # ⚡ ARCH-SYNC: Flush I-Cache after loading new code + {.emit: """asm volatile ("fence.i" : : : "memory");""" .} + discard ion_vfs_close(fd) return ehdr.e_entry @@ -159,20 +169,21 @@ proc kload_phys(path: cstring, phys_offset: uint64): uint64 = proc subject_fiber_entry() {.cdecl.} = let fid = current_fiber.id - kprint("[Subject:"); kprint_hex(fid); kprintln("] Fiber Entry reached.") + kprint("[Subject:"); kprint_hex(fid); kprint("] Fiber Entry reached. PA_Offset="); kprint_hex(current_fiber.phys_offset); kprintln("") # Use new robust loader kprint("[Loader:"); kprint_hex(fid); kprint("] Loading: "); kprintln(cast[cstring](addr subject_loading_path[0])) - let entry_addr = kload_phys(cast[cstring](addr subject_loading_path[0]), 0) + # Load into Cellular Slot (phys_offset) + let entry_addr = kload_phys(cast[cstring](addr subject_loading_path[0]), current_fiber.phys_offset) if entry_addr != 0: kprint("[Subject:"); kprint_hex(fid); kprint("] Entering Payload at: "); kprint_hex(entry_addr); kprintln("") proc hal_enter_userland(entry, systable, sp: uint64) {.importc, cdecl.} var sp = current_fiber.user_sp_init if sp == 0: - # Fallback (Legacy/Init) - sp = 0x8FFFFEE0'u64 + # Fallback (Legacy/Init) - Top of the 64MB Sentinel Cell + sp = 0x8BFFFFF0'u64 kprint("[Subject:"); kprint_hex(fid); kprint("] JUMPING to Userland. SP="); kprint_hex(sp); kprintln("") hal_enter_userland(entry_addr, SYSTABLE_BASE, sp) @@ -189,7 +200,7 @@ proc compositor_fiber_entry() {.cdecl.} = term.term_render() fiber_sleep(33) # 30Hz -proc mm_create_worker_map(stack_base: uint64, stack_size: uint64, packet_addr: uint64, code_base_pa: uint64): uint64 {.importc, cdecl.} +proc mm_create_worker_map(stack_base: uint64, stack_size: uint64, packet_addr: uint64, phys_base: uint64, region_size: uint64): uint64 {.importc, cdecl.} proc setup_mksh_stack(stack_base: pointer, stack_size: int): uint64 = var sp = cast[uint64](stack_base) + cast[uint64](stack_size) @@ -264,7 +275,15 @@ proc ion_fiber_entry() {.cdecl.} = fiber_child.pty_id = pid fiber_child.user_sp_init = setup_mksh_stack(addr stack_child[0], sizeof(stack_child)) - fiber_child.satp_value = mm_create_worker_map(cast[uint64](addr stack_child[0]), uint64(sizeof(stack_child)), SYSTABLE_BASE, 0x90000000'u64) + # 🏛️ CELLULAR ALLOCATION (SPEC-202 Rev 2) + # Sentinel (Init) takes 0x88000000 - 0x8C000000 (64MB) + # Mksh (First Child) starts in the 'Wild' at 0x8C000000 + let cell_base = 0x8C000000'u64 + fiber_child.phys_offset = cell_base + + # Allocate 64MB Slot for Mksh (Needs >32MB for BSS) + let cell_size = 64 * 1024 * 1024'u64 + fiber_child.satp_value = mm_create_worker_map(cast[uint64](addr stack_child[0]), uint64(sizeof(stack_child)), SYSTABLE_BASE, cell_base, cell_size) kprintln("[ION] Child fiber spawned successfully") else: discard fiber_sleep(10) @@ -274,10 +293,11 @@ proc fiber_yield*() {.exportc, cdecl.} = rumpk_yield_guard() proc rumpk_yield_internal*() {.exportc, cdecl.} = - if not sched_tick_spectrum(active_fibers_arr.toOpenArray(0, 4)): + # Schedule fibers 0-5 (ION, NexShell, Compositor, NetSwitch, Init, Mksh) + if not sched_tick_spectrum(active_fibers_arr.toOpenArray(0, 5)): # No runnable fibers (all sleeping). - # Return to Dispatcher (Main Fiber) to enter sleep/wfi mode. - switch(active_fibers_arr[5]) + # Return to Dispatcher (Main Fiber) at index 6 to enter sleep/wfi mode. + switch(active_fibers_arr[6]) proc fiber_netswitch_entry() {.cdecl.} = kprintln("[NetSwitch] Traffic Engine Online") @@ -337,8 +357,13 @@ proc k_handle_syscall*(nr, a0, a1, a2: uint): uint {.exportc, cdecl.} = discard chan_cmd.send(pkt) current_fiber.wants_yield = true return 0 + of 0x65: # NANOSLEEP + let now = sched_get_now_ns() + current_fiber.sleep_until = now + a0 + fiber_yield() + return 0 of 0x100: # YIELD - current_fiber.wants_yield = true + fiber_yield() return 0 of 0x200: # OPEN # return uint(libc_impl.libc_impl_open(cast[cstring](a0), int(a1))) @@ -424,6 +449,14 @@ proc kmain() {.exportc, cdecl.} = mm_init() mm_enable_kernel_paging() + # Ground Zero Phase 1: Initialize Capability System (SPEC-051) + init_cspace_subsystem() + kprintln("[CSpace] Capability system initialized") + + # Ground Zero Phase 2: Initialize System Truth Ledger (SPEC-060) + init_stl_subsystem() + let boot_id = emit_system_boot() + ion_init_input() hal_io_init() pty_init() @@ -482,13 +515,41 @@ proc kmain() {.exportc, cdecl.} = fiber_subject.id = 4; fiber_child.id = 5 init_fiber(addr fiber_ion, ion_fiber_entry, addr stack_ion[0], sizeof(stack_ion)) - init_fiber(addr fiber_compositor, compositor_fiber_entry, addr stack_compositor[0], sizeof(stack_compositor)) - init_fiber(addr fiber_nexshell, nexshell_main, addr stack_nexshell[0], sizeof(stack_nexshell)) - init_fiber(addr fiber_netswitch, fiber_netswitch_entry, addr stack_netswitch[0], sizeof(stack_netswitch)) + let ion_spawn_id = emit_fiber_spawn(1, 0, boot_id) # ION fiber + discard ion_spawn_id + + init_fiber(addr fiber_compositor, compositor_fiber_entry, addr stack_compositor[0], sizeof(stack_compositor)) + let compositor_spawn_id = emit_fiber_spawn(3, 0, boot_id) # Compositor fiber + discard compositor_spawn_id + + init_fiber(addr fiber_nexshell, nexshell_main, addr stack_nexshell[0], sizeof(stack_nexshell)) + let shell_spawn_id = emit_fiber_spawn(2, 0, boot_id) # NexShell fiber + + init_fiber(addr fiber_netswitch, fiber_netswitch_entry, addr stack_netswitch[0], sizeof(stack_netswitch)) + let netswitch_spawn_id = emit_fiber_spawn(6, 0, boot_id) # NetSwitch fiber + discard netswitch_spawn_id - proc mm_create_worker_map(stack_base: uint64, stack_size: uint64, packet_addr: uint64, code_base_pa: uint64): uint64 {.importc, cdecl.} init_fiber(addr fiber_subject, subject_fiber_entry, addr stack_subject[0], sizeof(stack_subject)) - fiber_subject.satp_value = mm_create_worker_map(cast[uint64](addr stack_subject[0]), uint64(sizeof(stack_subject)), SYSTABLE_BASE, 0x88000000'u64) + let subject_spawn_id = emit_fiber_spawn(4, 0, boot_id) # Subject fiber + + # Ground Zero Phase 1: Grant Initial Capabilities (SPEC-051) + # Grant console I/O to NexShell (fiber 2) + discard fiber_grant_channel(2, 0x1000, PERM_READ or PERM_WRITE) # console.input + discard emit_capability_grant(2, 2, 0x1000, 0, shell_spawn_id) # Log event + + discard fiber_grant_channel(2, 0x1001, PERM_READ or PERM_WRITE) # console.output + discard emit_capability_grant(2, 2, 0x1001, 1, shell_spawn_id) # Log event + kprintln("[CSpace] Granted console capabilities to NexShell") + + # Grant console output to Subject (fiber 4) + discard fiber_grant_channel(4, 0x1001, PERM_WRITE) # console.output (write-only) + discard emit_capability_grant(4, 2, 0x1001, 0, subject_spawn_id) # Log event + kprintln("[CSpace] Granted output capability to Subject") + + # Init (Subject) lives in Cell 0 (0x88000000) - Needs 64MB for large BSS + fiber_subject.phys_offset = 0x88000000'u64 + let init_size = 64 * 1024 * 1024'u64 + fiber_subject.satp_value = mm_create_worker_map(cast[uint64](addr stack_subject[0]), uint64(sizeof(stack_subject)), SYSTABLE_BASE, fiber_subject.phys_offset, init_size) # Interrupt Setup asm "csrsi sstatus, 2" @@ -512,6 +573,9 @@ proc kmain() {.exportc, cdecl.} = (addr fiber_subject).setSpectrum(Spectrum.Void) # Untrusted Background (addr fiber_child).setSpectrum(Spectrum.Void) # Child process (spawned) current_fiber.setSpectrum(Spectrum.Void) # Main loop (dispatcher) + + # Ground Zero Phase 2: Introspection + stl_print_summary() kprintln("[Rumpk] Multi-Fiber Dispatcher starting...") switch(addr fiber_ion) diff --git a/core/netswitch.nim b/core/netswitch.nim index 980294e..5624383 100644 --- a/core/netswitch.nim +++ b/core/netswitch.nim @@ -80,7 +80,7 @@ proc netswitch_process_packet(pkt: IonPacket): bool = return false return true - of 0x88B5: # Sovereign UTCP (SPEC-410) + of 0x88B5: # Sovereign UTCP (SPEC-700) # TODO: Route to dedicated UTCP channel # kprintln("[NetSwitch] UTCP Sovereign Packet Identified") ion_free(pkt) diff --git a/core/ontology.nim b/core/ontology.nim new file mode 100644 index 0000000..f8a93e0 --- /dev/null +++ b/core/ontology.nim @@ -0,0 +1,194 @@ +# SPDX-License-Identifier: LSL-1.0 +# Copyright (c) 2026 Markus Maiwald +# Stewardship: Self Sovereign Society Foundation +# +# This file is part of the Nexus Sovereign Core. +# See legal/LICENSE_SOVEREIGN.md for license terms. + +# SPEC-060: System Ontology - Nim Bindings +# Ground Zero Phase 2: Event System + +## Event System Nim Bindings + +# Kernel logging (freestanding-safe) +proc kprint(s: cstring) {.importc, cdecl.} +proc kprint_hex(n: uint64) {.importc, cdecl.} +proc kprintln(s: cstring) {.importc, cdecl.} + +# Import STL from HAL +proc stl_init*() {.importc, cdecl.} +proc stl_emit*( + kind: uint16, + fiber_id: uint64, + entity_id: uint64, + cause_id: uint64, + data0: uint64, + data1: uint64, + data2: uint64 +): uint64 {.importc, cdecl.} +proc stl_lookup*(event_id: uint64): pointer {.importc, cdecl.} +proc stl_count*(): uint32 {.importc, cdecl.} + +type + QueryResult* = object + count*: uint32 + events*: array[64, pointer] + +proc stl_query_by_fiber*(fiber_id: uint64, result: var QueryResult) {.importc, cdecl.} +proc stl_query_by_kind*(kind: uint16, result: var QueryResult) {.importc, cdecl.} +proc stl_get_recent*(max_count: uint32, result: var QueryResult) {.importc, cdecl.} + +type + LineageResult* = object + count*: uint32 + event_ids*: array[16, uint64] + +proc stl_trace_lineage*(event_id: uint64, result: var LineageResult) {.importc, cdecl.} + +## Event Types (Mirror from ontology.zig) +type + EventKind* = enum + EvNull = 0 + # Lifecycle + EvSystemBoot = 1 + EvSystemShutdown = 2 + EvFiberSpawn = 3 + EvFiberTerminate = 4 + # Capability + EvCapabilityGrant = 10 + EvCapabilityRevoke = 11 + EvCapabilityDelegate = 12 + # I/O + EvChannelOpen = 20 + EvChannelClose = 21 + EvChannelRead = 22 + EvChannelWrite = 23 + # Memory + EvMemoryAllocate = 30 + EvMemoryFree = 31 + EvMemoryMap = 32 + # Network + EvNetworkPacketRx = 40 + EvNetworkPacketTx = 41 + # Security + EvAccessDenied = 50 + EvPolicyViolation = 51 + +## High-level API for kernel use + +proc emit_system_boot*(): uint64 = + ## Emit system boot event + return stl_emit( + uint16(EvSystemBoot), + 0, # fiber_id (kernel) + 0, # entity_id + 0, # cause_id + 0, 0, 0 # data + ) + +proc emit_fiber_spawn*(fiber_id: uint64, parent_id: uint64, cause_id: uint64 = 0): uint64 = + ## Emit fiber spawn event + return stl_emit( + uint16(EvFiberSpawn), + parent_id, + fiber_id, + cause_id, + 0, 0, 0 + ) + +proc emit_capability_grant*( + fiber_id: uint64, + cap_type: uint8, + object_id: uint64, + slot: uint32, + cause_id: uint64 = 0 +): uint64 = + ## Emit capability grant event + return stl_emit( + uint16(EvCapabilityGrant), + fiber_id, + object_id, + cause_id, + uint64(cap_type), + uint64(slot), + 0 + ) + +proc emit_channel_write*( + fiber_id: uint64, + channel_id: uint64, + bytes_written: uint64, + cause_id: uint64 = 0 +): uint64 = + ## Emit channel write event + return stl_emit( + uint16(EvChannelWrite), + fiber_id, + channel_id, + cause_id, + bytes_written, + 0, 0 + ) + +proc emit_access_denied*( + fiber_id: uint64, + resource_id: uint64, + attempted_perm: uint8, + cause_id: uint64 = 0 +): uint64 = + ## Emit access denied event (security) + return stl_emit( + uint16(EvAccessDenied), + fiber_id, + resource_id, + cause_id, + uint64(attempted_perm), + 0, 0 + ) + +## Initialization +proc init_stl_subsystem*() = + ## Initialize the STL subsystem (call from kmain) + stl_init() + kprintln("[STL] System Truth Ledger initialized") + +## Query API +proc stl_print_summary*() = + ## Print a summary of the STL ledger to the console + kprintln("\n[STL] Event Summary:") + let total = stl_count() + kprint("[STL] Total Events: "); kprint_hex(uint64(total)); kprintln("") + + var res: QueryResult + + # Boot Events + stl_query_by_kind(uint16(EvSystemBoot), res) + kprint("[STL] SystemBoot: "); kprint_hex(uint64(res.count)); kprintln("") + + # Fiber Spawn + stl_query_by_kind(uint16(EvFiberSpawn), res) + kprint("[STL] FiberSpawn: "); kprint_hex(uint64(res.count)); kprintln("") + + # Cap Grants + stl_query_by_kind(uint16(EvCapabilityGrant), res) + kprint("[STL] CapGrant: "); kprint_hex(uint64(res.count)); kprintln("") + + # Demonstrate Lineage Tracing for the last event + if total > 0: + let last_id = uint64(total - 1) + var lineage: LineageResult + stl_trace_lineage(last_id, lineage) + + kprint("[STL] Lineage Trace for Event "); kprint_hex(last_id); kprintln(":") + for i in 0..= self.bounds_start and addr < self.bounds_end; + } + + /// Check permission + pub fn has_perm(self: *const Capability, perm: CapPerms) bool { + const self_bits = @as(u8, @bitCast(self.perms)); + const perm_bits = @as(u8, @bitCast(perm)); + return (self_bits & perm_bits) == perm_bits; + } +}; + +/// CSpace: Per-fiber capability table +pub const CSPACE_SIZE = 64; // Maximum capabilities per fiber + +pub const CSpace = struct { + slots: [CSPACE_SIZE]Capability, + epoch: u32, // For revocation + fiber_id: u64, // Owner fiber + _padding: u32, // Alignment + + /// Initialize empty CSpace + pub fn init(fiber_id: u64) CSpace { + var cs = CSpace{ + .slots = undefined, + .epoch = 0, + .fiber_id = fiber_id, + ._padding = 0, + }; + + // Initialize all slots to Null + for (&cs.slots) |*slot| { + slot.* = Capability.null_cap(); + } + + return cs; + } + + /// Find first empty slot + pub fn find_empty_slot(self: *CSpace) ?usize { + for (&self.slots, 0..) |*cap, i| { + if (cap.is_null()) return i; + } + return null; + } + + /// Grant capability (insert into CSpace) + pub fn grant(self: *CSpace, cap: Capability) !usize { + const slot = self.find_empty_slot() orelse return error.CSpaceFull; + self.slots[slot] = cap; + return slot; + } + + /// Lookup capability by slot index + pub fn lookup(self: *const CSpace, slot: usize) ?*const Capability { + if (slot >= CSPACE_SIZE) return null; + const cap = &self.slots[slot]; + if (cap.is_null()) return null; + return cap; + } + + /// Revoke capability (set to Null) + pub fn revoke(self: *CSpace, slot: usize) void { + if (slot >= CSPACE_SIZE) return; + self.slots[slot] = Capability.null_cap(); + } + + /// Revoke all capabilities (epoch-based) + pub fn revoke_all(self: *CSpace) void { + for (&self.slots) |*cap| { + cap.* = Capability.null_cap(); + } + self.epoch +%= 1; + } + + /// Delegate capability (Move or Copy) + pub fn delegate( + self: *CSpace, + slot: usize, + target: *CSpace, + move: bool, + ) !usize { + const cap = self.lookup(slot) orelse return error.InvalidCapability; + + // Check DELEGATE permission + if (!cap.has_perm(.{ .delegate = true })) { + return error.NotDelegatable; + } + + // Grant to target + const new_slot = try target.grant(cap.*); + + // If move (not copy), revoke from source + if (move or !cap.has_perm(.{ .copy = true })) { + self.revoke(slot); + } + + return new_slot; + } +}; + +/// Global CSpace table (one per fiber) +/// This will be integrated with Fiber Control Block in kernel.nim +pub const MAX_FIBERS = 16; +var global_cspaces: [MAX_FIBERS]CSpace = undefined; +var cspaces_initialized: bool = false; + +/// Initialize global CSpace table +pub export fn cspace_init() void { + if (cspaces_initialized) return; + + for (&global_cspaces, 0..) |*cs, i| { + cs.* = CSpace.init(i); + } + + cspaces_initialized = true; +} + +/// Get CSpace for fiber +pub export fn cspace_get(fiber_id: u64) ?*CSpace { + if (!cspaces_initialized) return null; + if (fiber_id >= MAX_FIBERS) return null; + return &global_cspaces[fiber_id]; +} + +/// Grant capability to fiber (C ABI) +pub export fn cspace_grant_cap( + fiber_id: u64, + cap_type: u8, + perms: u8, + object_id: u64, + bounds_start: u64, + bounds_end: u64, +) i32 { + const cs = cspace_get(fiber_id) orelse return -1; + + const cap = Capability{ + .cap_type = @enumFromInt(cap_type), + .perms = @bitCast(perms), + ._reserved = 0, + .object_id = object_id, + .bounds_start = bounds_start, + .bounds_end = bounds_end, + }; + + const slot = cs.grant(cap) catch return -1; + return @intCast(slot); +} + +/// Lookup capability (C ABI) +pub export fn cspace_lookup(fiber_id: u64, slot: usize) ?*const Capability { + const cs = cspace_get(fiber_id) orelse return null; + return cs.lookup(slot); +} + +/// Revoke capability (C ABI) +pub export fn cspace_revoke(fiber_id: u64, slot: usize) void { + const cs = cspace_get(fiber_id) orelse return; + cs.revoke(slot); +} + +/// Check capability permission (C ABI) +pub export fn cspace_check_perm(fiber_id: u64, slot: usize, perm_bits: u8) bool { + const cs = cspace_get(fiber_id) orelse return false; + const cap = cs.lookup(slot) orelse return false; + const perm: CapPerms = @bitCast(perm_bits); + return cap.has_perm(perm); +} + +// Unit tests +test "Capability creation and validation" { + const cap = Capability{ + .cap_type = .Channel, + .perms = .{ .read = true, .write = true }, + ._reserved = 0, + .object_id = 0x1234, + .bounds_start = 0x1000, + .bounds_end = 0x2000, + }; + + try std.testing.expect(!cap.is_null()); + try std.testing.expect(cap.check_bounds(0x1500)); + try std.testing.expect(!cap.check_bounds(0x3000)); + try std.testing.expect(cap.has_perm(.{ .read = true })); + try std.testing.expect(!cap.has_perm(.{ .execute = true })); +} + +test "CSpace operations" { + var cs = CSpace.init(42); + + const cap = Capability{ + .cap_type = .Memory, + .perms = .{ .read = true, .write = true, .delegate = true }, + ._reserved = 0, + .object_id = 0xABCD, + .bounds_start = 0, + .bounds_end = 0x1000, + }; + + // Grant capability + const slot = try cs.grant(cap); + try std.testing.expect(slot == 0); + + // Lookup capability + const retrieved = cs.lookup(slot).?; + try std.testing.expect(retrieved.object_id == 0xABCD); + + // Revoke capability + cs.revoke(slot); + try std.testing.expect(cs.lookup(slot) == null); +} + +test "Delegation" { + var cs1 = CSpace.init(1); + var cs2 = CSpace.init(2); + + const cap = Capability{ + .cap_type = .Channel, + .perms = .{ .read = true, .delegate = true, .copy = true }, + ._reserved = 0, + .object_id = 0x5678, + .bounds_start = 0, + .bounds_end = 0xFFFF, + }; + + const slot1 = try cs1.grant(cap); + + // Copy delegation + const slot2 = try cs1.delegate(slot1, &cs2, false); + + // Both should have the capability + try std.testing.expect(cs1.lookup(slot1) != null); + try std.testing.expect(cs2.lookup(slot2) != null); + + // Move delegation + var cs3 = CSpace.init(3); + const slot3 = try cs2.delegate(slot2, &cs3, true); + + // cs2 should no longer have it + try std.testing.expect(cs2.lookup(slot2) == null); + try std.testing.expect(cs3.lookup(slot3) != null); +} diff --git a/hal/mm.zig b/hal/mm.zig index bc073e8..b6e2ccb 100644 --- a/hal/mm.zig +++ b/hal/mm.zig @@ -172,29 +172,28 @@ pub fn create_kernel_identity_map() !*PageTable { return root; } -// Create restricted worker map -pub fn create_worker_map(stack_base: u64, stack_size: u64, packet_addr: u64, code_base_pa: u64) !*PageTable { +// Create restricted worker map for Cellular Memory Architecture +pub fn create_worker_map(stack_base: u64, stack_size: u64, packet_addr: u64, phys_base: u64, region_size: u64) !*PageTable { const root = alloc_page_table() orelse return error.OutOfMemory; - // 🏛️ THE ISOLATED CAGE (Phase 40 - Per-Fiber Memory Isolation) + // 🏛️ THE IRON FIREWALL (Cellular Memory Isolation) + // SPEC-202: User VA 0x88000000 is mapped to variable Physical Slots (phys_base). - kprint("[MM] Creating worker map:\n"); - kprint("[MM] Kernel (S-mode): 0x80000000-0x88000000\n"); - kprint("[MM] User VA: 0x88000000-0x90000000\n"); - kprint("[MM] User PA: "); - kprint_hex(code_base_pa); + kprint("[MM] Cellular Map: phys_base="); + kprint_hex(phys_base); + kprint(" size="); + kprint_hex(region_size); kprint("\n"); // 1. Kernel Memory (0-128MB) -> Supervisor ONLY (PTE_U = 0) // This allows the fiber trampoline to execute in S-mode. try map_range(root, DRAM_BASE, DRAM_BASE, 128 * 1024 * 1024, PTE_R | PTE_W | PTE_X); - // 2. User Memory (VA 0x88000000 -> PA code_base_pa) -> User Accessible (PTE_U = 1) - // This creates ISOLATED physical regions per fiber: - // - Init: VA 0x88000000 -> PA 0x88000000 - // - Child: VA 0x88000000 -> PA 0x90000000 (or higher) + // 2. User Slot (VA 0x88000000 -> PA phys_base) -> User Accessible (PTE_U = 1) + // - Slot 0 (Init): PA 0x88000000 (Big Cell) + // - Slot 1 (Mksh): PA 0x8C000000 (Standard Cell) const user_va_base = DRAM_BASE + (128 * 1024 * 1024); - try map_range(root, user_va_base, code_base_pa, 128 * 1024 * 1024, PTE_R | PTE_W | PTE_X | PTE_U); + try map_range(root, user_va_base, phys_base, region_size, PTE_R | PTE_W | PTE_X | PTE_U); // 3. MMIO Plumbing - Mapped identity but S-mode ONLY (PTE_U = 0) // This allows the kernel to handle interrupts/IO while fiber map is active. @@ -255,8 +254,8 @@ pub export fn mm_get_kernel_satp() callconv(.c) u64 { return kernel_satp_value; } -pub export fn mm_create_worker_map(stack_base: u64, stack_size: u64, packet_addr: u64, code_base_pa: u64) callconv(.c) u64 { - if (create_worker_map(stack_base, stack_size, packet_addr, code_base_pa)) |root| { +pub export fn mm_create_worker_map(stack_base: u64, stack_size: u64, packet_addr: u64, phys_base: u64, region_size: u64) callconv(.c) u64 { + if (create_worker_map(stack_base, stack_size, packet_addr, phys_base, region_size)) |root| { return make_satp(root); } else |_| { return 0; diff --git a/hal/ontology.zig b/hal/ontology.zig new file mode 100644 index 0000000..ee8488e --- /dev/null +++ b/hal/ontology.zig @@ -0,0 +1,420 @@ +//! SPEC-060: System Ontology - Event & Entity Structures +//! Component: core/ontology +//! Target: Ground Zero - Phase 2 + +const std = @import("std"); + +/// EventKind: Closed enumeration of system events (SPEC-060) +pub const EventKind = enum(u16) { + Null = 0, + + // Lifecycle Events + SystemBoot = 1, + SystemShutdown = 2, + FiberSpawn = 3, + FiberTerminate = 4, + + // Capability Events + CapabilityGrant = 10, + CapabilityRevoke = 11, + CapabilityDelegate = 12, + + // I/O Events + ChannelOpen = 20, + ChannelClose = 21, + ChannelRead = 22, + ChannelWrite = 23, + + // Memory Events + MemoryAllocate = 30, + MemoryFree = 31, + MemoryMap = 32, + + // Network Events + NetworkPacketRx = 40, + NetworkPacketTx = 41, + + // Security Events + AccessDenied = 50, + PolicyViolation = 51, +}; + +/// Event: Immutable record of a system occurrence (58 bytes, packed) +/// NOTE: Packed to 58 bytes for Zig compatibility (packed structs can't contain arrays) +pub const Event = packed struct { + kind: EventKind, // 2 bytes - Event type + _reserved: u16, // 2 bytes - Alignment + timestamp_ns: u64, // 8 bytes - Nanosecond timestamp + fiber_id: u64, // 8 bytes - Originating fiber + entity_id: u64, // 8 bytes - Target entity (SipHash) + cause_id: u64, // 8 bytes - Causal parent event ID + data0: u64, // 8 bytes - Event-specific data + data1: u64, // 8 bytes - Event-specific data + data2: u64, // 8 bytes - Event-specific data + // Total: 58 bytes (packed) + + /// Create a null event + pub fn null_event() Event { + return .{ + .kind = .Null, + ._reserved = 0, + .timestamp_ns = 0, + .fiber_id = 0, + .entity_id = 0, + .cause_id = 0, + .data0 = 0, + .data1 = 0, + .data2 = 0, + }; + } + + /// Check if event is null + pub fn is_null(self: *const Event) bool { + return self.kind == .Null; + } +}; + +/// EntityKind: Types of system entities (SPEC-060) +pub const EntityKind = enum(u8) { + Null = 0, + Fiber = 1, + Channel = 2, + Memory = 3, + File = 4, + Network = 5, + Device = 6, +}; + +/// Entity: Represents a system resource (32 bytes, cache-aligned) +pub const Entity = extern struct { + kind: EntityKind, // 1 byte - Entity type + _reserved: [7]u8, // 7 bytes - Alignment + entity_id: u64, // 8 bytes - Unique ID (SipHash) + parent_id: u64, // 8 bytes - Parent entity (for hierarchy) + metadata: u64, // 8 bytes - Entity-specific metadata + + comptime { + if (@sizeOf(Entity) != 32) { + @compileError("Entity must be exactly 32 bytes"); + } + } + + /// Create a null entity + pub fn null_entity() Entity { + return .{ + .kind = .Null, + ._reserved = [_]u8{0} ** 7, + .entity_id = 0, + .parent_id = 0, + .metadata = 0, + }; + } + + /// Check if entity is null + pub fn is_null(self: *const Entity) bool { + return self.kind == .Null; + } +}; + +/// System Truth Ledger: Append-only event log +pub const STL_SIZE = 4096; // Maximum events in ring buffer + +pub const SystemTruthLedger = struct { + events: [STL_SIZE]Event, + head: u32, // Next write position + tail: u32, // Oldest event position + epoch: u32, // Wraparound counter + _padding: u32, // Alignment + + /// Initialize empty STL + pub fn init() SystemTruthLedger { + var stl = SystemTruthLedger{ + .events = undefined, + .head = 0, + .tail = 0, + .epoch = 0, + ._padding = 0, + }; + + // Initialize all events to Null + for (&stl.events) |*event| { + event.* = Event.null_event(); + } + + return stl; + } + + /// Append event to ledger (returns event ID) + pub fn append(self: *SystemTruthLedger, event: Event) u64 { + const idx = self.head; + self.events[idx] = event; + + // Advance head + self.head = (self.head + 1) % STL_SIZE; + + // If we wrapped, advance tail + if (self.head == self.tail) { + self.tail = (self.tail + 1) % STL_SIZE; + self.epoch +%= 1; + } + + // Event ID = epoch << 32 | index + return (@as(u64, self.epoch) << 32) | @as(u64, idx); + } + + /// Lookup event by ID + pub fn lookup(self: *const SystemTruthLedger, event_id: u64) ?*const Event { + const idx = @as(u32, @truncate(event_id & 0xFFFFFFFF)); + const epoch = @as(u32, @truncate(event_id >> 32)); + + if (idx >= STL_SIZE) return null; + if (epoch != self.epoch and idx >= self.head) return null; + + const event = &self.events[idx]; + if (event.is_null()) return null; + + return event; + } + + /// Get current event count + pub fn count(self: *const SystemTruthLedger) u32 { + if (self.head >= self.tail) { + return self.head - self.tail; + } else { + return (STL_SIZE - self.tail) + self.head; + } + } +}; + +/// Global System Truth Ledger +pub var global_stl: SystemTruthLedger = undefined; +pub var stl_initialized: bool = false; + +/// Initialize STL subsystem +pub export fn stl_init() void { + if (stl_initialized) return; + global_stl = SystemTruthLedger.init(); + stl_initialized = true; +} + +/// Get current timestamp (placeholder - will be replaced by HAL timer) +fn get_timestamp_ns() u64 { + // TODO: Integrate with HAL timer + return 0; +} + +/// Emit event to STL (C ABI) +pub export fn stl_emit( + kind: u16, + fiber_id: u64, + entity_id: u64, + cause_id: u64, + data0: u64, + data1: u64, + data2: u64, +) u64 { + if (!stl_initialized) return 0; + + const event = Event{ + .kind = @enumFromInt(kind), + ._reserved = 0, + .timestamp_ns = get_timestamp_ns(), + .fiber_id = fiber_id, + .entity_id = entity_id, + .cause_id = cause_id, + .data0 = data0, + .data1 = data1, + .data2 = data2, + }; + + return global_stl.append(event); +} + +/// Lookup event by ID (C ABI) +pub export fn stl_lookup(event_id: u64) ?*const Event { + if (!stl_initialized) return null; + return global_stl.lookup(event_id); +} + +/// Get event count (C ABI) +pub export fn stl_count() u32 { + if (!stl_initialized) return 0; + return global_stl.count(); +} + +/// Query result structure for event filtering +pub const QueryResult = extern struct { + count: u32, + events: [64]*const Event, // Max 64 results per query +}; + +/// Query events by fiber ID (C ABI) +pub export fn stl_query_by_fiber(fiber_id: u64, result: *QueryResult) void { + if (!stl_initialized) { + result.count = 0; + return; + } + + var count: u32 = 0; + var idx = global_stl.tail; + + while (idx != global_stl.head and count < 64) : (idx = (idx + 1) % STL_SIZE) { + const event = &global_stl.events[idx]; + if (!event.is_null() and event.fiber_id == fiber_id) { + result.events[count] = event; + count += 1; + } + } + + result.count = count; +} + +/// Query events by kind (C ABI) +pub export fn stl_query_by_kind(kind: u16, result: *QueryResult) void { + if (!stl_initialized) { + result.count = 0; + return; + } + + var count: u32 = 0; + var idx = global_stl.tail; + + while (idx != global_stl.head and count < 64) : (idx = (idx + 1) % STL_SIZE) { + const event = &global_stl.events[idx]; + if (!event.is_null() and @intFromEnum(event.kind) == kind) { + result.events[count] = event; + count += 1; + } + } + + result.count = count; +} + +/// Get recent events (last N) (C ABI) +pub export fn stl_get_recent(max_count: u32, result: *QueryResult) void { + if (!stl_initialized) { + result.count = 0; + return; + } + + const actual_count = @min(max_count, @min(global_stl.count(), 64)); + var count: u32 = 0; + + // Start from most recent (head - 1) + var idx: u32 = if (global_stl.head == 0) STL_SIZE - 1 else global_stl.head - 1; + + while (count < actual_count) { + const event = &global_stl.events[idx]; + if (!event.is_null()) { + result.events[count] = event; + count += 1; + } + + if (idx == global_stl.tail) break; + idx = if (idx == 0) STL_SIZE - 1 else idx - 1; + } + + result.count = count; +} + +/// Lineage result structure for causal tracing +pub const LineageResult = extern struct { + count: u32, + event_ids: [16]u64, // Maximum depth of 16 for causal chains +}; + +/// Trace the causal lineage of an event (C ABI) +pub export fn stl_trace_lineage(event_id: u64, result: *LineageResult) void { + if (!stl_initialized) { + result.count = 0; + return; + } + + var count: u32 = 0; + var current_id = event_id; + + while (count < 16) { + const event = global_stl.lookup(current_id) orelse break; + result.event_ids[count] = current_id; + count += 1; + + // Stop if we reach an event with no parent (or self-referencing parent) + if (event.cause_id == current_id) break; + + // In our system, the root event (SystemBoot) has ID 0 and cause_id 0 + if (current_id == 0 and event.cause_id == 0) break; + + current_id = event.cause_id; + } + + result.count = count; +} + +// Unit tests +test "Event creation and validation" { + const event = Event{ + .kind = .FiberSpawn, + ._reserved = 0, + .timestamp_ns = 1000, + .fiber_id = 42, + .entity_id = 0x1234, + .cause_id = 0, + .data0 = 0, + .data1 = 0, + .data2 = 0, + }; + + try std.testing.expect(!event.is_null()); + try std.testing.expect(event.kind == .FiberSpawn); + try std.testing.expect(event.fiber_id == 42); +} + +test "STL operations" { + var stl = SystemTruthLedger.init(); + + const event1 = Event{ + .kind = .SystemBoot, + ._reserved = 0, + .timestamp_ns = 1000, + .fiber_id = 0, + .entity_id = 0, + .cause_id = 0, + .data0 = 0, + .data1 = 0, + .data2 = 0, + }; + + // Append event + const id1 = stl.append(event1); + try std.testing.expect(id1 == 0); + try std.testing.expect(stl.count() == 1); + + // Lookup event + const retrieved = stl.lookup(id1).?; + try std.testing.expect(retrieved.kind == .SystemBoot); +} + +test "STL wraparound" { + var stl = SystemTruthLedger.init(); + + // Fill the buffer + var i: u32 = 0; + while (i < STL_SIZE + 10) : (i += 1) { + const event = Event{ + .kind = .FiberSpawn, + ._reserved = 0, + .timestamp_ns = i, + .fiber_id = i, + .entity_id = 0, + .cause_id = 0, + .data0 = 0, + .data1 = 0, + .data2 = 0, + }; + _ = stl.append(event); + } + + // Should have wrapped + try std.testing.expect(stl.epoch > 0); + try std.testing.expect(stl.count() == STL_SIZE); +} diff --git a/hal/ram_blk.zig b/hal/ram_blk.zig index 3683f36..949d042 100644 --- a/hal/ram_blk.zig +++ b/hal/ram_blk.zig @@ -5,7 +5,7 @@ // This file is part of the Nexus Commonwealth. // See legal/LICENSE_COMMONWEALTH.md for license terms. -//! Rumpk HAL: Reed-Solomon RAM Block Device (SPEC-023) +//! Rumpk HAL: Reed-Solomon RAM Block Device (SPEC-103) //! //! Provides ECC-protected RAM storage using Reed-Solomon GF(2^8). //! This is the "Cortex" - Space-Grade resilient memory. diff --git a/libs/membrane/config_ledger.nim b/libs/membrane/config_ledger.nim index 505e67c..d57680e 100644 --- a/libs/membrane/config_ledger.nim +++ b/libs/membrane/config_ledger.nim @@ -5,7 +5,7 @@ # This file is part of the Nexus Sovereign Core. # See legal/LICENSE_SOVEREIGN.md for license terms. -## Nexus Membrane: Configuration Ledger (SPEC-140) +## Nexus Membrane: Configuration Ledger (SPEC-803) ## Implements Event Sourcing for System State. import strutils, times, options @@ -69,7 +69,7 @@ proc ledger_replay*(ledger: ConfigLedger): Node = proc ledger_rollback*(ledger: var ConfigLedger, target_tx: uint64) = ## Rolls back the system state. - ## Note: This appends a ROLLBACK tx rather than truncating (SPEC-140 Doctrine). + ## Note: This appends a ROLLBACK tx rather than truncating (SPEC-803 Doctrine). let rb_node = newNode("rollback_target") rb_node.addArg(newVal(int(target_tx))) ledger.ledger_append(OpRollback, "system.rollback", rb_node) diff --git a/libs/membrane/fs/monolith.nim b/libs/membrane/fs/monolith.nim index 31020fa..1d667cf 100644 --- a/libs/membrane/fs/monolith.nim +++ b/libs/membrane/fs/monolith.nim @@ -7,7 +7,7 @@ ## Nexus Membrane: The Monolith (4MB Key) ## -## Implements the Zero-Friction Encryption per SPEC-021. +## Implements the Zero-Friction Encryption per SPEC-503. ## - L0 (Factory): Unprotected 4MB random key ## - L1 (Sovereignty): Password-protected (Argon2id + XChaCha20) diff --git a/libs/membrane/fs/sfs_user.nim b/libs/membrane/fs/sfs_user.nim index 22b6069..bf6b013 100644 --- a/libs/membrane/fs/sfs_user.nim +++ b/libs/membrane/fs/sfs_user.nim @@ -5,7 +5,7 @@ # This file is part of the Nexus Sovereign Core. # See legal/LICENSE_SOVEREIGN.md for license terms. -## Nexus Membrane: SFS Userspace Client (SPEC-021) +## Nexus Membrane: SFS Userspace Client (SPEC-503) ## ## The Sovereign Filesystem Overlay: ## - L0: LittleFS (Atomic Physics) via `lfs_nim` @@ -69,7 +69,7 @@ proc sfs_alloc_sector(): uint32 = # ========================================================= proc sfs_mount*(): bool = - ## Mount the SFS filesystem (SPEC-021/022) + ## Mount the SFS filesystem (SPEC-503/022) ## Uses LittleFS as backend, VolumeKey for encryption print("[SFS-U] Mounting Sovereign Filesystem...\n") @@ -85,7 +85,7 @@ proc sfs_mount*(): bool = print("[SFS-U] LittleFS backend mounted.\n") sfs_mounted = true - print("[SFS-U] Mount SUCCESS. SPEC-021 Compliant.\n") + print("[SFS-U] Mount SUCCESS. SPEC-503 Compliant.\n") return true proc sfs_is_mounted*(): bool = sfs_mounted diff --git a/libs/membrane/ion_client.nim b/libs/membrane/ion_client.nim index a2872f4..7476f54 100644 --- a/libs/membrane/ion_client.nim +++ b/libs/membrane/ion_client.nim @@ -80,7 +80,7 @@ type fn_yield*: proc() {.cdecl.} fn_siphash*: proc(key: ptr array[16, byte], data: pointer, len: uint64, out_hash: ptr array[16, byte]) {.cdecl.} fn_ed25519_verify*: proc(sig: ptr array[64, byte], msg: pointer, len: uint64, pk: ptr array[32, byte]): bool {.cdecl.} - # SPEC-021: Monolith Key Derivation + # SPEC-503: Monolith Key Derivation fn_blake3*: proc(data: pointer, len: uint64, out_hash: ptr array[32, byte]) {.cdecl.} # Phase 36.2: Network Membrane s_net_rx*: pointer # Kernel -> User (RX) diff --git a/libs/membrane/libc.nim b/libs/membrane/libc.nim index 29e0476..76676d6 100644 --- a/libs/membrane/libc.nim +++ b/libs/membrane/libc.nim @@ -340,7 +340,7 @@ else: return int(syscall(0x203, uint64(fd), cast[uint64](buf), count)) # ========================================================= -# lwIP Syscall Bridge (SPEC-400, SPEC-401) +# lwIP Syscall Bridge (SPEC-701, SPEC-805) # ========================================================= # The Graft: These C-compatible exports provide the kernel interface @@ -370,7 +370,7 @@ proc syscall_get_time_ns*(): uint64 {.exportc, cdecl.} = proc syscall_get_random*(): uint32 {.exportc, cdecl.} = ## Generate cryptographically strong random number for TCP ISN ## Implementation: SipHash-2-4(MonolithKey, Time || CycleCount) - ## Per SPEC-401: Hash Strategy + ## Per SPEC-805: Hash Strategy let sys = get_sys_table() @@ -392,7 +392,7 @@ proc syscall_get_random*(): uint32 {.exportc, cdecl.} = """.} copyMem(addr mix_data[8], unsafeAddr cycles, 8) - # Use SipHash with system key (SPEC-401) + # Use SipHash with system key (SPEC-805) # TODO: Use actual Monolith key when available var key: array[16, byte] for i in 0..<16: diff --git a/npl/nipbox/nipbox.nim b/npl/nipbox/nipbox.nim index bf172c9..3cc2cf6 100644 --- a/npl/nipbox/nipbox.nim +++ b/npl/nipbox/nipbox.nim @@ -1071,7 +1071,7 @@ proc nipbox_main*() = # Phase 30: Pledge Safety # NipBox is the Shell, so it needs broad permissions, but we can restrict RPATH/WPATH to specific zones # For now, we PLEDGE_ALL because the shell needs to explore - # In future (SPEC-300), we drop PLEDGE_INET unless authorized + # In future (SPEC-401), we drop PLEDGE_INET unless authorized discard lb.pledge(PLEDGE_ALL) # Initialize the Biosuit