# 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. ## Rumpk Layer 1: The Reactive Dispatcher (The Tyrant) ## ## Implements the Silence Doctrine (SPEC-102). ## - No Tick. ## - No Policy. ## - Only Physics. {.push stackTrace: off, lineTrace: off.} import fiber # We might need to access the Fiber globals from fiber.nim # fiber.nim exports current_fiber, but we need to iterate them. # Currently kernel.nim manages the specific fibers variables (fiber_ion, fiber_ui, etc.) # We need a centralized registry or a way to iterate. # # For the first pass, we can replicate the logic in kernel.nim which explicitly checks # the known fibers, but structured as the Spectrum loop. # Or we can make kernel.nim pass the fibers to us. # # Let's keep it simple and stateless in sched.nim if possible, or have it manage the queue. # Since kernel.nim holds the variables, sched.nim should probably define the *Strategy* # and kernel.nim calls it, OR sched.nim should import kernel (circular!). # # Better: fiber.nim holds a linked list of fibers? # Or sched.nim is just a helper module that kernel.nim uses. # Let's define the Strategy here. # To avoid circular imports, kernel.nim will likely INCLUDE sched.nim or sched.nim # will act on a passed context. # BUT, SPEC-102 implies sched.nim *is* the logic. # # Let's define the Harmonic logic. # We need access to `current_fiber` (from fiber.nim) and `get_now_ns` (helper). proc sched_get_now_ns*(): uint64 {.importc: "rumpk_timer_now_ns", cdecl.} # Forward declaration for the tick function # Returns TRUE if a fiber was switched to (work done/found). # Returns FALSE if the system should sleep (WFI). proc sched_tick_spectrum*(fibers: openArray[ptr FiberObject]): bool = let now = sched_get_now_ns() # ========================================================= # Phase 1: PHOTON (Hard Real-Time / Hardware Driven) # ========================================================= # - V-Sync (Compositor) # - Audio Mix # - Network Polling (War Mode) var run_photon = false for f in fibers: if f != nil and f.getSpectrum() == Spectrum.Photon: if now >= f.sleep_until: if f != current_fiber: switch(f); return true else: run_photon = true if run_photon: return true # ========================================================= # Phase 2: MATTER (Interactive / Latency Sensitive) # ========================================================= # - Shell # - Editor var run_matter = false for f in fibers: if f != nil and f.getSpectrum() == Spectrum.Matter: if now >= f.sleep_until: if f != current_fiber: switch(f); return true else: run_matter = true if run_matter: return true # ========================================================= # Phase 3: GRAVITY (Throughput / Background) # ========================================================= # - Compiler # - Ledger Sync var run_gravity = false for f in fibers: if f != nil and f.getSpectrum() == Spectrum.Gravity: if now >= f.sleep_until: if f != current_fiber: switch(f); return true else: run_gravity = true if run_gravity: return true # ========================================================= # Phase 4: VOID (Scavenger) # ========================================================= # - Untrusted Code # - Speculative Execution for f in fibers: if f != nil and f.getSpectrum() == Spectrum.Void: if now >= f.sleep_until: if f != current_fiber: switch(f) return true else: return true # ========================================================= # THE SILENCE # ========================================================= # If we reached here, NO fiber is runnable. return false proc sched_get_next_wakeup*(fibers: openArray[ptr FiberObject]): uint64 = var min_wakeup: uint64 = 0xFFFFFFFFFFFFFFFF'u64 let now = sched_get_now_ns() for f in fibers: if f != nil and f.sleep_until > now: if f.sleep_until < min_wakeup: min_wakeup = f.sleep_until return min_wakeup # ========================================================= # THE RATCHET (Post-Execution Analysis) # ========================================================= proc console_write(p: pointer, len: csize_t) {.importc, cdecl.} proc sched_log(msg: string) = if msg.len > 0: console_write(unsafeAddr msg[0], csize_t(msg.len)) proc sched_demote(f: ptr FiberObject) = ## Demote a fiber to a lower Spectrum tier let current = f.getSpectrum() case current: of Spectrum.Photon: f.setSpectrum(Spectrum.Matter) console_write(cstring("[Ratchet] DEMOTED fiber to Matter\n"), 34) of Spectrum.Matter: f.setSpectrum(Spectrum.Gravity) console_write(cstring("[Ratchet] DEMOTED fiber to Gravity\n"), 35) of Spectrum.Gravity: f.setSpectrum(Spectrum.Void) console_write(cstring("[Ratchet] DEMOTED fiber to Void\n"), 32) of Spectrum.Void: discard # Already at the bottom proc sched_analyze_burst*(f: ptr FiberObject, burst_ns: uint64) = ## Analyze the burst duration of a fiber after it yields/switches ## Implements the 3-strike rule for budget violations if f == nil: return f.last_burst_ns = burst_ns # Update moving average (exponential: 75% old, 25% new) if f.avg_burst == 0: f.avg_burst = burst_ns else: f.avg_burst = (f.avg_burst * 3 + burst_ns) div 4 # Budget enforcement if f.budget_ns > 0 and burst_ns > f.budget_ns: f.violations += 1 console_write(cstring("[Ratchet] Violation: fiber exceeded budget\n"), 42) if f.violations >= 3: sched_demote(f) f.violations = 0 # Reset after demotion {.pop.}