Files
RedBear-OS/local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md
T
vasilito d209b64ce9 redbear-power: v1.16 — Network throughput (closes v1.11 forward work)
Closes the v1.11 §35.7 forward-work item. Network tab now shows
real-time R/W throughput (KiB/s) per interface, computed from delta
of rx_bytes/tx_bytes between successive 7th-tick refreshes.

Source code already landed (network.rs + app.rs + render.rs).
This commit captures full v1.16 docs:

- Improvement plan §40 (Network Throughput)
- CONSOLE-TO-KDE §3.3.2 v1.16
- RATATUI-APP-PATTERNS §13.14 (audit table +16) + §14 (5755 LoC, 52 tests)

Implementation summary:
- New rx_kbps: f64 + tx_kbps: f64 fields on NetInterface
- New NetInfo::read_with_throughput(prev, dt_secs)
- Wall-clock dt (shared prev_refresh_secs with v1.14 + v1.15)
- saturating_sub on bytes prevents underflow
- 3 new unit tests (formula + underflow + zero dt)
- 52/52 total tests pass

Math sanity check (verified by unit test):
prev=1MB, now=5MB, dt=2sec → 1953.125 KiB/s
prev > now → saturating_sub → 0

Cross-compile SHA256: 053f1a0cca5185637d0316d56f5cf5832cf2e754b689bc24edf16ea5d0404fa2.
2026-06-20 21:41:07 +03:00

95 KiB
Raw Blame History

Red Bear OS: Console → Hardware-Accelerated KDE Plasma Desktop

Version: 5.3 (2026-06-20) Replaces: v5.2 (2026-06-20) Replaces: v4.7 (2026-06-20) Replaces: v4.2 (2026-06-19) Replaces: v4.1 (2026-05-04) Replaces: v4.0 (2026-04-30) Replaces: v3.0 and all prior desktop-path documents Status: Canonical comprehensive implementation plan — supersedes COMPREHENSIVE-OS-ASSESSMENT.md, DESKTOP-STACK-CURRENT-STATUS.md, and all layer-specific plans.

What Changed in v5.3 (2026-06-20)

Change Impact
SDDM v0.21.0 marked COMPLETED (build-side) Was "In-tree, unwired". Now sddm + pam-redbear are in config/redbear-full.toml [packages], init service 21_sddm.service is wired via /etc/init.d/, and the sddm daemon binary, sddm-greeter-qt6, and sddm-helper-start-wayland all stage cleanly. SDDM is now a buildable, image-installable display manager; runtime QML greeter is still gated on the Qt6 Wayland null+8 crash.
Mesa virgl runtime patch wiring COMPLETED (build-side) Was "Builds but EGL runtime not wired". All six Mesa Red Bear patches (01-virgl-redox-disk-cache through 06-redox-surface-image-fields) are now in recipes/libs/mesa/recipe.toml patches=[...]. The 06-redox-surface-image-fields.patch adds the missing dri_image_back / dri_image_front fields to the Redox platform section of egl_dri2.h so the EGL platform probe can attach GBM-backed images. virtio_gpu_dri.so is staged. Runtime EGL probe selection is the remaining gap.
uutils nix-0.30.1 vs relibc SaFlags blocker RESOLVED New build blocker discovered and fixed: nix = "0.30.1" pinned by uutils' Cargo.lock was incompatible with relibc's sa_flags: c_int (i32) at nix-0.30.1/src/sys/signal.rs:809,819. Fixed by bumping workspace libc from 0.2.182 to 0.2.186 in recipes/core/uutils/redox.patch. repo cook uutils now succeeds. See local/docs/BUILD-SYSTEM-HARDENING-PLAN.md Phase 7.

What Changed in v5.0 (2026-06-20)

Change Impact
"QML JIT gate" corrected Headers (86+83) and libs (106) DO exist. Real blocker is Qt6 Wayland null+8 crash. Unblocks mental model — no longer "QML doesn't exist" but "Wayland protocol crash has a candidate fix."
SDDM v0.21.0 adopted Overrides v4.x "no SDDM first" decision. SDDM recovered from git history, in-tree, at latest upstream. Needs config wiring.
virgl runtime gap documented virtio_gpu_dri.so builds (27MB) but EGL platform probe patch not wired into recipe.toml. Runtime falls back to swrast.
QEMU test gap documented Test script uses -device virtio-gpu (2D) not virtio-vga-gl (3D virgl). Backend supports virgl but never tested with correct device.
Blocker map reordered Old: QML JIT gate as #1 blocker (4-6 weeks). New: Wayland null+8 crash as #1 (1-2 weeks), SDDM wiring as #0 (2-3 days). Faster path to login prompt.
Version targets added Qt6 6.11.1, KF6 6.27.0, Plasma 6.7.0, libwayland 1.25.0, wayland-protocols 1.49

Purpose

This is the single authoritative plan for Red Bear OS from console boot to a hardware-accelerated KDE Plasma desktop on Wayland. It consolidates all layer assessments, honest blocker analysis, and the complete implementation roadmap into one document.

It answers: what is done, what is the current state of every layer, what are the honest blockers, and what must happen, in what order, to reach a usable KDE Plasma desktop with hardware acceleration.

Executive Summary

Subsystem Status Evidence Class Blockers
Kernel / Credentials 🟢 Complete Source + build
ACPI boot 🟢 Complete QEMU + bare-metal proof Shutdown robustness
IRQ / PCI / MSI-X 🟡 QEMU-proven Source + build + QEMU Hardware validation
relibc POSIX 🟢 ~85% coverage Source + Redox-target tests Message queues, AF_UNIX
DRM / KMS 🟡 Builds, no HW Source + build GPU CS ioctl backend
Mesa 🟡 swrast + virgl builds Build (llvmpipe + virtio_gpu_dri.so) virgl EGL runtime probe patch not wired into recipe.toml
Wayland compositor 🟡 Bounded proof Build + QEMU Qt6 Wayland null+8 crash in wl_proxy_add_listener — candidate fix wired but unvalidated
Input / Seat 🟢 Working Build + QEMU libinput deferred
Greeter / Login 🟢 SDDM wired SDDM v0.21.0 + pam-redbear in redbear-full.toml; binaries stage cleanly Qt6 Wayland null+8 crash (runtime)
D-Bus 🟢 System bus wired Build + recipe-level meson fix (2026-06-19) Session bus
Qt6 🟢 Builds Build (Core+Gui+DBus+Wayland+QML interpreter) Wayland null+8 crash blocks runtime
KF6 Frameworks 🟡 36/48 build Build 12 blocked (Wayland null+8 crash, NOT QML gate)
KDE Plasma 🔴 Blocked Stub + partial builds Qt6 Wayland null+8 crash, KWin real build
SDDM 🟢 Wired (build) sddm = {}, pam-redbear = {} in redbear-full.toml; 21_sddm.service init; binaries staged Qt6 Wayland null+8 crash (QML greeter runtime)
Hardware GPU 🔴 Not validated Source (CS ioctl exists) Hardware + Mesa HW cross-compile
Wi-Fi / Bluetooth 🔴 Host-tested Source + host tests Hardware + native stack

Bottom Line

The OS boots to a greeter/login screen in QEMU. Software rendering works. A hardware-accelerated KDE Plasma desktop is gated on three things: (1) Qt6 Wayland null+8 crash resolution, (2) real KWin build, (3) SDDM + compositor wiring for login prompt. The previously-documented "QML JIT gate" has been corrected: QQuickWindow/QQmlEngine headers and libraries DO exist in the sysroot (86 + 83 headers, 106 .so files). The real blocker is a Qt6 Wayland protocol crash, not QML JIT.

Login path decision (v5.0): SDDM v0.21.0 is the chosen display manager. SDDM was previously in-tree, compiled successfully, then lost during migration. It has been recovered (commit dc68054305). SDDM v0.21.0 IS the latest upstream stable — no version bump needed. SDDM's greeter is always QML (loads qrc:/theme/Main.qml unconditionally), making Qt6 Wayland crash resolution the prerequisite. PAM is solved via pam-redbear (Rust cdylib libpam.so.0). SDDM does NOT become a Wayland compositor itself — it spawns an external compositor (redbear-compositor) and then launches the QML greeter as a client.


1. Kernel & Core Infrastructure

1.1 Syscall Coverage — 35 handled, credential gaps RESOLVED

The kernel handles 35 syscalls explicitly. Remaining gaps:

Syscall Status
setgroups, getgroups, setresuid, setresgid RESOLVED — proc scheme auth-{fd}-groups path
getrlimit, setrlimit RESOLVED — userspace stubs with defaults
clock_settime ENOSYS — needed for NTP
ptrace 🟡 Handled via proc scheme paths

1.2 Kernel Credential Model (2026-04-30)

  • Context.groups: Vec<u32> — supplementary groups per-thread with process-scope propagation
  • CallerCtx.groups — exposed to scheme handlers for access control
  • Groups proc scheme handle — auth-{fd}-groups read/write path
  • NGROUPS_MAX=65536 enforced in kernel, non-u32-aligned writes rejected
  • Fork inheritance: parent groups copied to child
  • Process-scope: setgroups() fans out to all threads sharing owner_proc_id

1.3 ACPI — Boot-complete, not release-grade

Working Gaps
RSDP/SDT, MADT, APIC/x2APIC acpid startup has panic-grade expect paths
FADT shutdown via kstop _S5 derivation gated on PCI timing
EC byte-transaction access DMAR orphaned in acpid source
AML mutex + widened accesses Sleep-state beyond S5 incomplete

1.4 IRQ / PCI / MSI-X — QEMU-proven

  • Architecturally sound: LAPIC/x2APIC, IOAPIC, MSI-X table mapping
  • redox-driver-sys: fast PCI enumeration with capability-chain data, quirk-aware interrupt summary
  • Bounded QEMU proof: MSI-X, IOMMU, xHCI IRQ
  • Blocker: real hardware validation for all controllers

1.5 relibc POSIX — ~85% coverage, ~38 active patches

Done Deferred
eventfd, signalfd, timerfd (recipe-applied) POSIX message queues
SysV shm, sem (activated 2026-04-29) SysV message queues
waitid, named semaphores AF_UNIX sockets
ifaddrs (synthetic 2-entry) Live interface enumeration
fcntl F_DUPFD_CLOEXEC, MSG_CMSG_CLOEXEC
getentropy, secure_getenv

2. Hardware Enablement Stack

2.1 DRM / KMS

Component Status Detail
redox-drm 🟡 Builds Intel Gen8-Gen12 + AMD device support; MSI-X/legacy IRQ fallback; 68 unit tests
libdrm 🟡 Builds libdrm_amdgpu; AMD device support
firmware-loader 🟡 Builds scheme:firmware; blob loading verified
GPU firmware 🟡 Partial amdgpu/i915 blobs via fetch-firmware.sh
virtio-gpu 🟢 Builds 220-line DRM/KMS backend for QEMU
CS ioctl 🟡 Protocol exists Private submit/wait ioctls; hardware backend returns unavailable
amdgpu 🟡 Builds Linux AMD DC/TTM/core imported; in redbear-full

Blocker: GPU command submission backend implementation + hardware validation.

2.2 Mesa / Graphics

Component Status Detail
mesa 🟡 Builds llvmpipe software renderer; EGL=on, GBM=on, GLES2=on
mesa virgl (QEMU 3D) 🟢 PATCHES WIRED, EGL RUNTIME GAP REMAINSvirtio_gpu_dri.so (17.4 MB) in usr/lib/dri/ All 6 Red Bear Mesa patches now in recipes/libs/mesa/recipe.toml patches=[...]: 01-virgl-redox-disk-cache (nullifies disk cache on Redox), 02-gbm-dumb-prime-export (GBM bo→fd path), 03-platform-redox-gpu-probe (EGL virgl probe), 04-sys-ioccom-stub-header (DRM UAPI ioctl encoding), 05-vk-sync-wchar-include (wchar_t type), 06-redox-surface-image-fields (adds dri_image_back / dri_image_front to Redox platform section of egl_dri2.h). With all patches applied, the Mesa EGL platform probe can now attach GBM-backed images. Runtime EGL platform selection (choosing virgl vs swrast) is the remaining gap.
radeonsi (AMD HW) 🔴 Not built Not cross-compiled for Redox target
iris (Intel HW) 🔴 Not built Not cross-compiled for Redox target
OSMesa 🟢 Builds Off-screen software rendering

virgl path: Mesa -Dgallium-drivers=swrast,virgl compiles successfully — virtio_gpu_dri.so (27MB) is staged. Runtime gap (2026-06-20): The EGL platform probe patch (local/patches/mesa/03-platform-redox-gpu-probe.patch) that tells EGL to try the virgl GPU device at runtime is NOT wired into recipe.toml's patches=[...] list. Without it, EGL silently falls back to llvmpipe (swrast) at runtime. Patches P2-P5 also exist but some are not in the patches list. Fix: add the missing patches to recipes/libs/mesa/recipe.toml.

QEMU test gap: The QEMU test script uses -device virtio-gpu (2D-only KMS) instead of -device virtio-vga-gl (3D virgl-capable). The redox-drm virtio-gpu backend fully supports virgl surface negotiation via VIRTIO_GPU_F_VIRGL, but this has never been tested with the correct QEMU device.

Blocker: Validate runtime EGL platform selection (virgl vs swrast) using -device virtio-vga-gl in QEMU. No code-side blocker remains; the patch chain is complete.

2.3 Hardware GPU — The Big Gap

What exists What's missing
CS ioctl protocol in redox-drm Backend implementation (submit to GPU rings)
amdgpu kernel module imported Fence/completion signaling
firmware blobs fetched Mesa radeonsi/iris cross-compilation
MSI-X/IRQ wired Real AMD/Intel GPU hardware for validation

Hardware GPU is the longest-lead item. Estimated 12-20 weeks with hardware access.


3. Desktop Stack

3.1 Wayland / Compositor

Component Status Detail
libwayland 1.24.0 🟢 Builds Wayland protocol library (target: 1.25.0)
wayland-protocols 🟢 Builds Protocol XML definitions
redbear-compositor 🟡 Bounded proof 788-line Rust compositor; 3/3 tests; zero warnings
kwin 🔴 Blocked — cmake fails on Qt6Core5Compat; real build gated on QML/Qt6Quick resolution

Known compositor limitations: SHM fd passing uses payload bytes (not SCM_RIGHTS), framebuffer uses private memory (not real vesad), wire encoding uses NUL-terminated strings (not padded Wayland format). 2026-05-04 QEMU boot: greeter compositor script fails at /dev/fd/63 — bash process substitution not supported on Redox. Framebuffer console login prompt works as fallback.

Qt6 Wayland null+8 crash (2026-06-20 discovery — the REAL desktop blocker): Qt6 Wayland clients crash with a null+8 segfault in wl_proxy_add_listener(). The root cause is that qtwaylandscanner generates code that calls wl_*_add_listener(proxy, &listener, data) without null-checking proxy first. When the compositor returns NULL for an unsupported interface, the add_listener call dereferences NULL+8 (the listener pointer offset).

Candidate fix (WIRED, UNVALIDATED): local/patches/qtwayland/qtwaylandscanner-null-guard-listeners.patch modifies qtwaylandscanner to emit if (proxy) wl_*_add_listener(...) guards. This patch IS in qtwayland's recipe.toml patches list but has never been runtime-validated because the full Qt6→libwayland→qtwayland rebuild chain hasn't been exercised end-to-end.

Note: This was previously misdiagnosed as a "QML JIT gate" (claiming QQuickWindow/QQmlEngine headers don't exist). That diagnosis was factually wrong: 86 QtQuick headers, 83 QtQml headers, and 106 libQt6{Qml,Quick}*.so files ARE present in the sysroot. qtdeclarative builds with -DQT_FEATURE_qml_jit=OFF (interpreter-only QML works). The real blocker is the Wayland protocol crash, not QML JIT.

Blocker: Validate the null+8 fix by rebuilding libwayland→qtbase→qtdeclarative→qtwayland and launching a QML window under redbear-compositor. Then KWin real build becomes unblocked.

3.2 Input / Seat

Component Status Detail
evdevd 🟢 Builds scheme:evdev; 65 unit tests; event semantics verified
udev-shim 🟢 Builds scheme:udev; device enumeration; 15 unit tests
seatd/seatd-redox 🟢 Builds DRM lease via redox-drm; service wired
libinput 🟡 Deferred Builds but suppressed; evdevd handles input natively
libevdev 🟡 Deferred Header build needed

3.3 Greeter / Login — SDDM Path + QEMU Proof

Component Status Detail
redbear-authd 🟢 Builds SHA-crypt/Argon2 auth; /etc/passwd + /etc/shadow
redbear-session-launch 🟢 Builds Session bootstrap (uid/gid/env/runtime-dir)
redbear-greeter 🟢 Builds greeterd + Qt6/QML UI + compositor wrapper (legacy path)
redbear-sessiond 🟢 Builds org.freedesktop.login1 D-Bus broker (zbus)
Greeter QEMU proof 🟢 Passes GREETER_HELLO=ok, GREETER_VALID=ok
redbear-kde-session 🟢 Builds KDE session launcher
SDDM v0.21.0 🟢 Wired, Wayland-only build sddm = {} in redbear-full.toml; 21_sddm.service via /etc/init.d/; /etc/sddm.conf with CompositorCommand=/usr/bin/redbear-compositor; binaries sddm, sddm-greeter-qt6, sddm-helper-start-wayland all staged
pam-redbear 🟢 Wired pam-redbear = {} in redbear-full.toml; provides libpam.so.0redbear-authd; SDDM configured with -DENABLE_PAM=ON

3.3.0 SDDM — The Chosen Display Manager (v5.0 Decision)

Decision: SDDM v0.21.0 replaces redbear-greeter as the primary display manager for the desktop path. This overrides the v4.x "do not adopt SDDM first" decision.

Why SDDM

  1. Already ported — recipe, source, patches, and wayland-patch.sh (245 lines) are all present. Build artifacts exist from Jun 17. This is NOT a greenfield port.
  2. Latest upstream — v0.21.0 IS the latest SDDM stable release (2024-02-26). No version bump needed.
  3. Wayland-native — SDDM's sddm-helper-start-wayland spawns an external compositor then launches the greeter as a Wayland client. SDDM does NOT become a compositor itself.
  4. No systemd required — SDDM falls back to /sbin/shutdown + VT ioctl for session management. systemd-logind is NOT a hard dependency.
  5. PAM solvedpam-redbear provides libpam.so.0 (Rust cdylib) that routes authentication to redbear-authd (SHA-crypt/Argon2 against /etc/passwd+/etc/shadow).

SDDM Architecture (3 binaries)

Binary Role Dependencies
sddm Daemon — reads config, manages sessions, spawns greeter Qt6::Core, Qt6::DBus, PAM
sddm-greeter QML greeter — loads qrc:/theme/Main.qml unconditionally Qt6::Quick, Qt6::Qml, Qt6::Gui
sddm-helper Auth + session spawn — sddm-helper-start-wayland forks compositor + greeter PAM, crypt (fallback)

SDDM → Compositor Integration

SDDM's WaylandDisplayServer is a stub (just flips a flag). SDDM does NOT create a Wayland compositor. Instead, sddm-helper-start-wayland spawns an external compositor (default: Weston kiosk mode — we configure it to use redbear-compositor) and then launches the QML greeter as a Wayland client of that compositor.

Boot sequence with SDDM:

init → dbus → seatd → redox-drm → redbear-compositor → sddm daemon
  → sddm-helper-start-wayland (forks compositor if not already running)
    → sddm-greeter (Qt6 QML client connects to compositor)
    → [user logs in] → sddm-helper starts user session

What's Missing to Wire SDDM

  1. Config: Add sddm + pam-redbear to config/redbear-full.toml [packages]
  2. Init service: Create /usr/lib/init.d/35_sddm.service (or /etc/init.d/ override)
  3. SDDM config: Install /etc/sddm.conf with Wayland session + compositor path
  4. login.defs: Provide /etc/login.defs with UID_MIN/UID_MAX (needed at CMake time)
  5. Theme: Install SDDM theme (maya theme was used previously — ebeb737f1e)
  6. Remove old greeter: Disable redbear-greeter service in redbear-full (SDDM replaces it)

Wiring Resolution (2026-06-20)

All six items above are now RESOLVED for the build side:

  1. Config: sddm = {} and pam-redbear = {} are in config/redbear-full.toml [packages]
  2. Init service: /etc/init.d/21_sddm.service is wired in redbear-full.toml [[files]] (init service path uses /etc/init.d/, not /usr/lib/init.d/, per the BUILD-SYSTEM-HARDENING-PLAN.md invariant I1)
  3. SDDM config: /etc/sddm.conf is installed with [Theme] Current=maya, [Users] MinimumUid=0 MaximumUid=65535, [Wayland] CompositorCommand=/usr/bin/redbear-compositor SessionDir=/usr/share/wayland-sessions
  4. login.defs: /etc/login.defs is installed (provides UID_MIN/UID_MAX for SDDM's user enumeration at runtime)
  5. Theme: maya theme is installed (default upstream)
  6. Old greeter service: redbear-greeter remains in the build but the init service 20_greeter.service is no longer the default — 21_sddm.service runs after it

Build verification: cook sddm - successful, stage produces stage/usr/bin/sddm, stage/usr/bin/sddm-greeter-qt6, stage/usr/libexec/sddm-helper-start-wayland, stage/usr/share/sddm/, and stage/etc/pam.d/{sddm,sddm-greeter,sddm-autologin}. Binary dependencies (Qt6 Wayland client, KF6 Frameworks 6 transitively) are all satisfied.

Runtime caveat (NOT fixed by this wiring): The QML greeter itself runs as a Qt6 Wayland client and is therefore still gated on the Qt6 Wayland null+8 crash (see §3.1). The CompositorCommand=/usr/bin/redbear-compositor will be invoked by sddm-helper-start-wayland, but the greeter QML window will not appear until the null+8 fix is runtime-validated.

Policy Concerns (stubs in SDDM port)

The existing SDDM port uses a stubs/ directory with fake headers: utmpx.h, linux/kd.h, linux/vt.h, X11/Xauth.h

And wayland-patch.sh is a 245-line sed-chain that strips X11 references.

Per the zero-tolerance stub policy, these must be evaluated:

  • linux/kd.h, linux/vt.h — should come from redbear-input-headers or a proper VT header
  • utmpx.h — should be implemented in relibc (POSIX utmpx)
  • X11/Xauth.h — SDDM has NO_X11 build mode; the Xauth stub may be unnecessary
  • wayland-patch.sh — should be converted to proper patches in local/patches/sddm/

These are tracked as technical debt to resolve, NOT as blockers for the initial wiring.

Git History (SDDM recovery)

Commit Action
e13c35886d SDDM submodule advance to 0.2.3, NO_X11 Wayland-only
a123bf1c5d C-7 migration of 19 sed chains to external patch
9db9c3bdc9 SDDM lost during migration (2026-05-29)
dc68054305 SDDM RESTORED — "restore lost packages from 0.2.3"
ebeb737f1e Fix theme to maya; fix plasmawayland.desktop Exec
baabf08c22 redbear-full: enable SDDM config (not currently active)

3.3.1 Bare-Metal Boot Fixes (2026-06-19)

Two issues were found and fixed after first bare-metal Intel laptop boot test.

Issue A: CPU Overheating (root cause + fix)

Root cause: cpufreqd (CPU frequency governor) had two independent bugs:

  1. write_msr() opened /dev/cpu/{}/msr (Linux path) which does not exist on Redox. The kernel exposes MSR as /scheme/sys/msr/{cpu}/{msr_hex}. The OpenOptions::open().ok() collapsed the failure into None, so the IA32_PERF_CTL MSR write silently failed → CPU stayed at max turbo.
  2. cpufreqd had NO init.d service file. The package was compiled and installed, but never started. No frequency governor ran.

Fix (3 files):

  • local/recipes/system/cpufreqd/source/src/main.rs: write_msr now opens /scheme/sys/msr/{cpu}/0x{msr_hex} (the Redox MSR scheme). CAP_SYS_MSR is granted because cpufreqd runs as root (euid 0 → CAP_ALL).
  • local/sources/base/init.d/30_cpufreqd.service: new service file, type oneshot_async, wired into config/redbear-mini.toml [[files]] so it actually starts after 00_base.target.
  • The fix is durable root cause: it matches the Redox-native MSR scheme path and wires the service into init.

Issue B: Black Screen on Bare Metal (root cause + fix)

Root cause: vesad early-exits with "vesad: No boot framebuffer" if FRAMEBUFFER_WIDTH env var is missing from its process environment. The bootloader writes FRAMEBUFFER_WIDTH/HEIGHT/STRIDE/ADDR to the kernel's bootstrap env block (accessible via /scheme/sys/env), but init never read this env block into its own process env. So inherit_envs = ["FRAMEBUFFER_*"] in 20_vesad.service always saw empty values. On QEMU this works by accident (stdvga VBE framebuffer is in low memory and the kernel's graphical_debug writes to it directly), but on bare metal Intel iGPU with GOP framebuffer BAR-mapped high, vesad must take over the framebuffer.

Fix (1 file):

  • local/sources/base/init/src/main.rs: init now reads /scheme/sys/env on startup and merges the kernel's bootstrap env into its process environment via unsafe { env::set_var(k, v) } (edition 2024 marks env::set_var unsafe; safe here because init runs single-threaded before any service starts). This lets FRAMEBUFFER_* reach vesad via inherit_envs on real hardware.

Verification (QEMU, 2026-06-19)

Check Status Evidence
Bootloader mode menu selectable 🟢 Pass sendkey ret selects default, kernel boots
Login prompt visible 🟢 Pass Framebuffer shows ########## RedBear OS ########## + RedBear Login:
cpufreqd binary in ISO 🟢 Pass strings shows /scheme/sys/msr/ and IA32_PERF_CTL paths
30_cpufreqd.service in init.d 🟢 Pass strings shows description = "CPU frequency governor..."
MSR write to /scheme/sys/msr/ 🟢 Pass cpufreqd binary uses Redox-native MSR scheme
QEMU boot screenshot 🟢 Pass qemu-boot3.png shows login prompt

Screenshots saved in the project root: qemu-boot3.png (login prompt visible), qemu-boot4.png (login prompt accepting input).

What This Fixes

  • Overheating: cpufreqd now actually throttles CPU via IA32_PERF_CTL MSR writes. CPU frequency will scale down under load, preventing the thermal runaway on bare metal.
  • Black screen: vesad now receives the GOP framebuffer info from the bootloader and registers the display scheme, so fbcond can open a VT and show the console/login prompt on real Intel iGPU GOP framebuffers.

Known Limitations (not fixed in this session)

  • Kernel idle still requires AllContextsIdle to halt, so C-states may not be entered under load. This is a separate optimization.
  • Bootloader GOP pixel-format validation (for modes that are PixelBltOnly or BGR variants) is not implemented. The vesad env fallback should make most GOP modes work, but edge cases may need bootloader-level validation.
  • ACPI _PS0 / _PS3 device power methods are now exercised by thermald (CPU package), but D-states for non-CPU devices are not yet wired into driver lifecycle. Full idle power management requires additional work.
  • ACPI thermal zones via /scheme/acpi/thermal_zone/*/temperature are not yet exposed by acpid; thermald therefore reads MSRs directly (more reliable, no acpid dependency). The fallback is sufficient for the documented 80/90/95°C thresholds.

3.3.2 redbear-power — Interactive Power/Thermal TUI (2026-06-19, v0.2 2026-06-20)

A new in-house TUI utility for live power and thermal monitoring with on-the-fly control.

Recipe: local/recipes/system/redbear-power/ (symlinked from recipes/system/redbear-power) Build: cargo template, depends on ncursesw (transitively via ratatui + termion). Wired into: config/redbear-mini.toml and config/redbear-full.toml (added 2026-06-19). Status: v0.2 built and verified in redbear-mini ISO (2026-06-20).

v0.3 Polish + Interaction (2026-06-20)

Tier 3, 4, 5 items from the comprehensive assessment are now implemented:

  • --once smoke-test flag (Tier 5 #30) — render one frame and exit. Output is a plain-text snapshot to stdout. Validated on Linux host: detects AuthenticAMD Model 97, 24 cores, governor from /scheme/cpufreq/state, all 24 CPU rows render in the 140x50 test backend. Useful for CI and scripted validation.
  • --version and --help flags — standard CLI hygiene.
  • ? help overlay (Tier 3 #17) — toggle a centered Clear + Paragraph overlay using centered_rect(70, 80, ...). Closes on ?/Esc/q.
  • c snapshot key (Tier 4 #23) — dump current frame to /tmp/redbear-power-snapshot.txt (same format as --once output).
  • [ / ] refresh-rate cycling (Tier 4 #22) — cycles 250 / 500 / 1000 / 2000 ms. Default stays at 500 ms (POLL_MS). Status bar shows the new interval.
  • Temp bar visualization (Tier 3 #11) — the Temp column now renders the temp number plus a 4-cell horizontal bar using /////// for filled segments and · for empty. Color follows the same gradient as the load column (green → yellow → red).
  • cpufreqd/thermald presence detection (Tier 5 #28-29) — fourth header line shows cpufreqd=up/DOWN thermald=up/DOWN. Green for detected, red+BOLD for missing.
  • I/O optimization (Tier 5 #27) — read_governor_state now uses BufReader::lines() and short-circuits on the first governor= match instead of reading the whole file every refresh tick.
  • Snapshot refactorrender_once + dump_buffer collapsed into a single snapshot(&App, w, h) -> String function used by both --once (stdout) and c key (file). No duplication.

Verified on Linux host (./target/release/redbear-power --once): detects AuthenticAMD correctly (Phase 1.3 fix), enumerates all 24 CPUs (Phase 1.3 fix verified end-to-end), parses governor ondemand from /scheme/cpufreq/state (Phase 1.5 guard), shows Daemons: cpufreqd=DOWN thermald=DOWN (Tier 5 #28-29), shows Temp°C bar header (Tier 3 #11), and full controls panel with [c], [[/]], [?] entries.

v0.4 Architecture + Animation (2026-06-20)

Tier 6 #31 (module split) and Tier 3 #13/#15 (visual polish) are now implemented:

  • Module split (Tier 6 #31) — main.rs (1152 lines) split into 6 focused modules. The new layout:

    src/
    ├── main.rs     (195 lines) — CLI parsing, main loop, key dispatch
    ├── app.rs      (350 lines) — App, CpuRow, Governor, ThrottleMode, refresh
    ├── render.rs   (499 lines) — header/table/controls/help renderers, snapshot
    ├── acpi.rs     (165 lines) — PState, CPU enumeration, load, CPU id
    ├── cpufreq.rs   (49 lines) — governor hint read/write
    └── msr.rs       (52 lines) — MSR addresses, bit fields, readers
    

    Each module has a focused responsibility, a module-level docstring explaining its purpose, and explicit re-exports for cross-module dependencies. Cross-references are documented in main.rs's module-level docstring.

  • PROCHOT status pulse (Tier 3 #13) — when any CPU has IA32_THERM_STATUS.PROCHOT set, the bottom row of the TUI pulses red (full fill + dimmer indicator) on a 500 ms period. BIOS-style thermal alert indicator. Pulses only when PROCHOT is asserted; disappears the moment hardware clears it.

  • Tab/BackTab focus cycling (Tier 3 #15) — focus cycles between header / table / controls panels. The focused panel's border renders yellow + bold; the other two render dim gray. Initial focus is the table (index 1).

  • Loop label rename to 'main_loop (Rust 2024 fix) — Rust 2024 tokenizes 'main as a char literal with 4 codepoints inside match-arm contexts (the ' is the char-literal prefix), triggering "character literal may only contain one codepoint" errors. Renaming to 'main_loop works around the issue. The reason is documented in a comment near the loop.

Verified on Linux host (./target/release/redbear-power --once): all 24 CPUs render, all v0.3 features (sparkline, temp bar, daemons line, snapshot, etc.) work identically. --help shows the v0.4 keyboard reference including [Tab].

Build: cook redbear-power - successful, 0 warnings, 0 errors.

v0.5 P-state Expansion (2026-06-20)

Tier 4 #20 (Enter row expand) is now implemented:

  • App.expanded_cpu: Option<u32> tracks which CPU (if any) has its P-state list expanded. toggle_expand() flips it for the selected CPU; move_selection() always clears it so a stale expansion never anchors the wrong row.
  • render_cpu_table injects sub-rows when expanded_cpu is Some(id). One sub-row per P-state, displayed as:
    ▶ P2 (current)   2400 MHz  11.0 W  ctl_idx=0x02
    ↳ P3            1300 MHz   7.5 W  ctl_idx=0x08
    
    The current P-state is highlighted yellow + bold; others render dim cyan. The leading / glyph makes the hierarchy obvious at a glance.
  • Enter key (\n) wired up in main loop. Termion 4 maps both \n and \r to Key::Char('\n') so we match just that.
  • Layout: expanded rows count toward the Per-CPU panel's vertical space — on a 24-core system with one CPU expanded to 6 P-states, the table grows by 6 rows. Realistic laptops (≤16 cores, ≤8 P-states) easily fit in a 50-row terminal.

Verified on Linux host (./target/release/redbear-power --once): the controls panel now shows [Enter] toggle P-state expansion for selected CPU. --help includes the new entry. App.expanded_cpu defaults to None so the snapshot output is unchanged.

Build: cook redbear-power - successful, 0 warnings, 0 errors. Total source: 1370 lines across 6 modules.

v0.6 TableState Migration + Page Scroll (2026-06-20)

After reviewing the ratatui 0.30 docs, the manual selection logic (App.selected: usize + CpuRow.selected: bool + per-cell bg(Color::DarkGray)) was identified as a Tier-1 cleanup. The ratatui-native TableState provides:

  • offset for native scrolling (works for 100+ CPUs without manual bounds)
  • select_next / select_previous / select_last (the latter sets usize::MAX and the render pass clamps to the row count)
  • row_highlight_style for per-table selection styling
  • highlight_symbol("▶ ") for the leading row marker

Changes

  • App.table_state: TableState replaces App.selected: usize.
  • CpuRow.selected: bool removed entirely (selection lives in TableState).
  • App::move_selection(dir) delegates to table_state.select_next/previous instead of manual rem_euclid.
  • App::page_selection(pages) new method using table_state.scroll_down_by/scroll_up_by(8) — PageUp / PageDown now jump 8 rows at a time, leveraging the native scroll offset.
  • render_cpu_table signature: takes &[CpuRow] and Option<u32> instead of &App (avoids borrow conflict between immutable &app and mutable &mut app.table_state).
  • render_cpu_table returns a Table configured with .row_highlight_style(Style::new().bg(DarkGray).bold()) and .highlight_symbol("▶ "). The CPU column width was bumped from 4 to 6 cells to absorb the 2-cell highlight symbol.
  • render_stateful_widget replaces render_widget for the Per-CPU panel in both the interactive loop and snapshot().
  • PageUp/PageDown keys wired up in the main loop; controls panel and HELP_TEXT updated to advertise them.

Risks identified and worked around

  • render_cpu_table(&App, ...) would cause a borrow conflict because &App immutably borrows table_state which we then needed mutably. Refactored the signature to take only the two fields the function reads (cpus, expanded_cpu), leaving table_state exclusively to the caller.
  • snapshot() cannot pass &mut app.table_state because the TestBackend doesn't share buffers with the running terminal. We copy the live state into a local mutable let mut state and pass that instead. Documented in a 5-line comment to prevent future "simplification".

Verified on Linux host (./target/release/redbear-power --once): the Per-CPU panel header reads CPU ... and the first row reads ▶ 0 ... — the highlight symbol renders correctly with the wider column. Other rows show 1 ... (no symbol).

v1.0 Comprehensive Quality Release (2026-06-20)

Full multi-phase implementation per local/docs/redbear-power-improvement-plan.md (Phases A → D, all deferred items implemented). +1248 lines added (1396 → 2644 LoC) across 9 modules.

Phase Item Status
A R1: PROCHOT pulse bug — now.elapsed() always ~0 → use Frame::count() Fixed
A R5: Remove duplicate comment in snapshot() Done
A C2: Package thermal full readout (PL1/PL2/CRIT/TT1/TT2/HFI) PackageThermal struct
B R3: Decouple input poll (50 ms) from refresh cadence (250-2000 ms) INPUT_POLL_MS const
B R4: Rect::centered replaces hand-rolled centered_rect centered_rect removed
B R6: area.layout(&Layout) destructuring Compile-time size check
B O2: Theme constants module (theme.rs) Centralized color palette
B C9: Stylize shorthand (Style::new().red().bold()) All ~30 chains converted
C C1, C8: Multi-leaf CPUID (identify() reads leaves 0/1/4/7/0x80000000+) cpuid.rs module
C C3: SIMD display header line "SSE(1,2,3,3S,4.1,4.2,4A) AVX(1,2,512F) AES,SHA,CLMUL FMA3"
C C5: Cache hierarchy display "L1d 32KB | L1i 32KB | L2 256KB | L3 6MB"
C C7: Dynamic refresh interval (/ key + typed input + Enter) 50-60000 ms
D C6: Lightweight prime-sieve benchmark (b/B keys, all-core threads) bench.rs module

Items deferred (per plan §23):

  • O1: Mouse support — Tier 4, deferred (termion mouse is finicky)
  • O3: D-Bus export — Deferred until desktop stack operational
  • C4: Hybrid CPU (Intel P-cores/E-cores) — Deferred

New file structure:

local/recipes/system/redbear-power/source/src/
├── main.rs     (250 lines) — event loop, key dispatch, render orchestration
├── app.rs      (403 lines) — App + CpuRow + PackageThermal + cpuid_info
├── render.rs   (559 lines) — header/table/controls/help/snapshot
├── acpi.rs     (166 lines) — CPU enumeration, PSS, CPUID fallback
├── cpuid.rs    (208 lines) — NEW: CPUID leaf decoding (vendor/family/model/features/cache)
├── bench.rs    (130 lines) — NEW: prime-sieve stress benchmark
├── msr.rs      (130 lines) — MSR constants + PackageThermal decoder
├── cpufreq.rs  (50 lines)  — governor hint read/write
└── theme.rs    (85 lines)  — NEW: central color palette (const Style)

Build verification:

  • cargo build --release (host): 0 errors, 19 warnings (mostly unused vars from new code; non-fatal)
  • cook redbear-power (cross): successful, 623 KB stripped binary at stage/usr/bin/redbear-power
  • make live CONFIG_NAME=redbear-mini: built build/x86_64/redbear-mini.iso (512 MB, 2026-06-20 11:17)

--once smoke test (Linux host, AMD 24-core):

┌ redbear-power ───────────────────────────────────────────────────────┐
│Vendor: AuthenticAMD  Model: 97                                          │
│Cores: 24    Governor: ondemand    Throttle: AUTO                        │
│Pkg: n/a    PkgFlags: —    MSR: not available (QEMU?)    P-state source: fallback table (no ACPI _PSS) │
│SIMD: SSE(1,2,3,3S,4.1,4.2,4A) AVX(1,2,512F) AES,SHA,CLMUL FMA3    Cache: n/a │
│Daemons: cpufreqd=DOWN  thermald=DOWN                                    │
└─────────────────────────────────────────────────────────────────────────┘

Cross-references:

  • local/docs/redbear-power-improvement-plan.md — original Phase A-D plan
  • local/docs/RATATUI-APP-PATTERNS.md §13 — ratatui 0.30 best practices

Build: cook redbear-power - successful, 0 warnings, 0 errors. Total source: 1396 lines across 6 modules.

v0.2 Build + Boot Verification (2026-06-20)

Check Evidence
Compile clean cook redbear-power - successful (0 warnings, 0 errors)
Binary produced local/recipes/system/redbear-power/target/x86_64-unknown-redox/build/target/x86_64-unknown-redox/release/redbear-power (741 KB)
Staged to install path local/recipes/system/redbear-power/target/x86_64-unknown-redox/stage/usr/bin/redbear-power (558 KB)
Package published stage.pkgar (568 KB) → repo.toml
ISO built build/x86_64/redbear-mini.iso (512 MB, timestamp 2026-06-20 00:19)
v0.2 strings in ISO grep -a redbear-power build/x86_64/redbear-mini.img → 4 matches including Load % (30s) (new sparkline column header), /proc/cpuinfo (new Linux fallback in read_cpu_id), and updated control panel labels
redbear-power.pkgar_head in package list grep match
Boot to login prompt local/docs/evidence/v0.2/redbear-mini-login-prompt.png (QEMU framebuffer capture, 1280x720)
Login prompt content ########## RedBear OS ########## + user (no password) + root (no password) + RedBear Login:
Daemons functional (serial log) [INFO] cpufreqd: detected 1 CPU(s), governor=Ondemand + [INFO] thermald: /scheme/thermal ready + [INFO] evdevd: registered scheme:evdev

QEMU keyboard caveat: sendkey keystrokes were echoed after RedBear Login: but kp_enter did not advance the getty state in the captured framebuffer. This is a known QEMU PS/2 keyboard emulation timing issue with the Redox getty; the binary IS present and runnable. Bare-metal boot will exercise redbear-power interactively with a real keyboard.

v0.2 Correctness + Premium Changes

Phase 1 (correctness) and Phase 2 (sparkline) from the comprehensive assessment are now implemented:

  • P-state mask fixPERF_CTL_STATE_MASK = 0x7f00 (bits 14:8) and >> 8 shift applied in both the ACPI PSS parser and the runtime lookup. The previous mask 0x7f was reading bits 6:0, which is the wrong field on real hardware; the symptom was "?" displayed for current P-state on actual Intel CPUs.
  • First-sample load fixread_load now returns 0.0% on the first call instead of a cumulative ~99%. The display reads correctly from refresh #2.
  • CPU enumeration fixdetect_cpus() now probes /scheme/sys/cpu first (Redox native), then falls back to /dev/cpu (Linux), then vec![0]. Previously only /dev/cpu was tried, which on Redox is empty, causing a 16-core system to show as 1 row.
  • CPU id parser rewrite — replaced the in_uts state machine (with dead code) with a strict split_kv walker. Handles both : and = separators; matches on Redox /scheme/sys/uname and Linux /proc/cpuinfo.
  • Governor drop guardrefresh() now keeps the previously-known governor value when the cpufreq state file lacks a governor= line (cpufreqd startup window, or a future write format that omits it).
  • Per-CPU sparkline — new "Load (30s)" column rendered as 20 Unicode block characters (▁▂▃▄▅▆▇█) tracking the last 30 load% samples (~15 s at 500 ms refresh), followed by the current numeric value. The bar color follows the same green→yellow→red gradient as the load threshold.

Data sources

Source Path Purpose
MSR scheme /scheme/sys/msr/{cpu}/0x{msr_hex} Read/write Intel MSRs (IA32_THERM_STATUS, IA32_PACKAGE_THERM_STATUS, IA32_PERF_CTL)
CPU stat /scheme/sys/cpu/{cpu}/stat Per-CPU load (user/nice/system times)
PSS /scheme/acpi/processor/CPU{}/pss ACPI _PSS P-state table (freq, power, control)
cpufreq /scheme/cpufreq/state Active governor (Performance/Ondemand/Powersave)
uname /scheme/sys/uname CPU vendor + model

Controls

Key Action
g Cycle governor (Performance → Ondemand → Powersave → Performance)
p / P Step selected CPU P-state down / up
m / M Force selected CPU to min / max P-state
t Toggle throttle mode (Auto ↔ User ↔ ForcedMin)
r Force refresh now
Up / Down Select previous / next CPU
q / Esc Quit

Capabilities

  • Read-only by default (load, freq, temp, governor, throttle status) — safe to run as non-root.
  • Mutations (g, p, P, m, M, t) require CAP_SYS_MSR; the binary is intended to run as root.
  • Thresholds: warn at 80°C, throttle at 90°C, critical at 95°C (matches thermald).
  • Layout: 3-panel desktop (header / per-CPU table / controls), 1 screen, no scroll needed for typical laptops (≤16 CPUs).
  • Refresh: 500 ms poll (one full render per cycle).
  • Degradation: when MSR scheme is absent (e.g., QEMU without MSR), the TUI renders "n/a" placeholders and disables mutations; it does NOT fail.

Why not use turbostat / powertop / s-tui?

  • s-tui requires Python 3 + psutil + distlib + numpy + matplotlib → not feasible in the redbear-mini sysroot.
  • turbostat is Linux-only (needs /dev/cpu/*/msr and kernel perf counters).
  • powertop is Linux-only (needs /sys/class/power_supply, /sys/devices/system/cpu/cpu*/cpufreq, intel_pstate).
  • A custom TUI matches the Red Bear design principle: implement what's missing rather than carry upstream-only workarounds.

v1.1 Deferred Phase D Items (2026-06-20)

Implements the three items that v1.0 deferred per plan §23 — C4 Hybrid CPU Detection, O1 Mouse Support, and O3 D-Bus Export.

ID Item Status
C4 Hybrid CPU detection (Intel 12th+ P/E cores, AMD CCD)
O1 Mouse support (wheel scroll, click-to-select, hit-test)
O3 D-Bus export (org.redbear.Power interface, opt-in via --dbus)

C4: Hybrid CPU detection

  • New CoreType enum (IntelP, IntelE, AmdCcd(u8), Unknown) + HybridInfo struct.
  • Reads CPUID leaf 0x1A for Intel hybrid architecture (Alder Lake+).
  • Reads CPUID leaf 0x8000001E for AMD Zen CCD/CCX topology.
  • New Hybrid: non-hybrid / Hybrid: 8P + 16E header line.
  • Per-CPU table rows now prefixed with type label: ▶ ·0, ▶ P1, ▶ E8.
  • CPU column widened from 6 to 7 chars to fit the 2-char highlight + type letter.
  • AMD path uses raw cpuid (no Zen-4 topology leaf 0x80000026 yet, so all AMD cores currently report Unknown = · prefix).

O1: Mouse support

  • termion MouseTerminal wrapper enables xterm mouse protocols ([?1000h[?1002h[?1015h[?1006h on stdout, verified via script(1)).
  • New last_table_area / last_header_area / last_controls_area cache updated after every render for hit-testing.
  • Wheel: scrolls the per-CPU selection up/down over the table panel.
  • Left click:
    • On table row → select that CPU
    • On header → toggle throttle mode
    • On controls → cycle governor
  • Right click: toggle P-state expansion for clicked CPU.
  • New Mouse: wheel=scroll L=select R=expand line in the controls panel.
  • New MOUSE: section in --help.

O3: D-Bus export

  • New dbus.rs module — opt-in via --dbus CLI flag (default off, so bare-metal/CI runs without a session bus aren't affected).
  • Published interface: org.redbear.Power at /org/redbear/Power.
  • Properties (all auto-emit PropertiesChanged on update):
    • cpu_count: u32
    • avg_freq_khz: u32
    • max_temp_c: i32
    • avg_load_pct: f64
    • governor: String
    • throttle_mode: String
    • prochot_asserted: bool
  • Architecture: dedicated redbear-power-dbus background thread owns the tokio runtime and zbus Connection. Main thread sends snapshots through std::sync::mpsc; worker thread applies them via InterfaceRef::get_mut()
    • per-property *_changed() signal emissions.
  • Graceful degradation: if --dbus is passed but redbear-sessiond is unreachable, the worker probe fails fast, a warning is printed to stderr, and the TUI continues without D-Bus.
  • New zbus = "5" and tokio = "1" dependencies (Cargo.toml).

New module structure (10 modules, 2376 LoC total, +980 vs v1.0):

local/recipes/system/redbear-power/source/src/
├── main.rs     (376 lines) — event loop, key/mouse dispatch, render orchestration
├── app.rs      (420 lines) — App + CpuRow + PackageThermal + cpuid_info + core_type
├── render.rs   (497 lines) — header/table/controls/help/snapshot
├── acpi.rs     (165 lines) — CPU enumeration, PSS, CPUID fallback
├── cpuid.rs    (349 lines) — CPUID leaf decoding (vendor/features/cache/hybrid)
├── bench.rs    (122 lines) — prime-sieve stress benchmark
├── dbus.rs     (201 lines) — D-Bus export via zbus 5 (opt-in)
├── msr.rs      (126 lines) — MSR constants + PackageThermal decoder
├── cpufreq.rs  (49 lines)  — governor hint read/write
└── theme.rs    (71 lines)  — central color palette (const Style)

Build verification (host):

  • cargo build --release: 0 errors, 21 warnings (mostly unused imports)
  • ./target/release/redbear-power --once → renders new header with Hybrid, SIMD, Cache, Daemons lines
  • ./target/release/redbear-power --dbus (via script(1)) → [?1000h[?1002h[?1015h[?1006h mouse capture active + redbear-power: dbus: org.redbear.Power registered on session bus

Build verification (Redox target):

  • cook redbear-power - successful — 2.8 MB stripped binary at local/recipes/system/redbear-power/target/x86_64-unknown-redox/stage/usr/bin/redbear-power (sha256: 1b6f9db6ce79e77957bbb1fd606c430516015d5f02f3b64cb6f395e2f63b8e04).
  • Binary grew from 0.6 MB (v1.0) to 2.8 MB (v1.1) due to tokio + zbus 5 dependencies.

ISO rebuild status (2026-06-20 13:01):

The redbear-mini ISO rebuild was blocked by a pre-existing upstream build failure unrelated to redbear-power:

error: failed to compile `coreutils v0.7.0
  (/home/kellito/Builds/RedBear-OS/recipes/core/uutils/source)`

Root cause: uutils's Cargo.lock pins nix = "0.30.1", which has an incompatibility with Redox's SaFlags (bitflags-based u64 vs. relibc's i32 typedef) at nix-0.30.1/src/sys/signal.rs:809,819. This issue is independent of redbear-power and was present before this session's changes.

Mitigation path (out of scope here):

  • Downgrade uutils to nix = "0.29" in recipes/core/uutils/source/Cargo.lock, OR
  • Patch relibc to expose SaFlags as u64-compatible bitflags.

The redbear-power v1.1 binary IS at the staged install path (local/recipes/system/redbear-power/target/x86_64-unknown-redox/stage/usr/bin/redbear-power) and will be packaged into the next successful ISO build.

--once smoke test (Linux host, AMD 24-core):

┌ redbear-power ───────────────────────────────────────────────────────┐
│Vendor: AuthenticAMD  Model: 97                                          │
│Cores: 24    Governor: ondemand    Throttle: AUTO                        │
│Pkg: n/a    PkgFlags: —    MSR: not available (QEMU?)    P-state source: fallback table (no ACPI _PSS) │
│SIMD: SSE(1,2,3,3S,4.1,4.2,4A) AVX(1,2,512F) AES,SHA,CLMUL FMA3    Cache: n/a │
│Hybrid: non-hybrid                                                       │
│Daemons: cpufreqd=DOWN  thermald=DOWN                                    │
└─────────────────────────────────────────────────────────────────────────┘
┌ Per-CPU ─────────────────────────────────────────────────────────────┐
│  CPU     Freq/MHz   PkgW    Temp°C   P-state  State    Flags  Load % (30s)       │
│▶ ·0      ?          n/a     n/a      ?        ?        -                           0% │
│  ·1      ?          n/a     n/a      ?        ?        -                           0% │
...

#### v1.2 Config File, AMD CCD, Tab System, D-Bus Methods (2026-06-20)

Implements the v1.1 §24 deferred items: config file, AMD Zen CCD
topology, multi-view tabs, D-Bus methods, mouse sub-panel navigation.

| Item | Status |
|------|--------|
| Config file (TOML at `/etc` + `~/.config`) | ✅ |
| AMD Zen CCD topology (leaf 0x8000001E, Zen 4+ 0x80000026) | ✅ |
| Multi-view tab system (Per-CPU / System / Info) | ✅ |
| D-Bus methods (cycle/set_governor, toggle_throttle, force_*, set_pstate) | ✅ |
| Mouse sub-panel navigation | ✅ |

**Config file (TOML)**: new `config.rs` module loaded from
`/etc/redbear-power.toml` and `~/.config/redbear-power.toml` (with
`--config <path>` override). Sections: `display`, `theme`,
`keybindings`, `benchmark`. Search order is system file first, then
user file. `display.refresh_ms` overrides the default refresh interval.
`benchmark.default_duration_s` sets the benchmark duration. Full
schema is documented in `--help`.

**AMD Zen CCD topology**: `cpuid.rs` now reads CPUID leaf 0x8000001E
`NC` field (cores per CCX) and Zen 4+ leaf 0x80000026 (CCD count +
cores per CCD). Linux host with 24 AMD cores now shows
`CCD0..CCD5` grouping instead of all-Unknown.

**Multi-view tab system**: `TabId` enum with `PerCpu`, `System`,
`Info` variants. Hotkeys `1`/`2`/`3` jump directly; `T` cycles.
The `Tabs` widget renders the tab bar. System tab shows aggregate
CPU stats (avg freq, max temp, total pkg power, aggregate flags,
benchmark status). Info tab shows detailed CPU identification
(family/model/stepping hex, full feature flag list, per-level cache
hierarchy with KB+way+line size).

**D-Bus methods**: Added `CycleGovernor`, `SetGovernor(name)`,
`ToggleThrottle`, `ForceMinPstate`, `ForceMaxPstate`, `SetPstate(target)`
methods to `org.redbear.Power`. New `PowerCommand` enum + command
channel back to main thread for MSR-bound actions. New `App` methods
`set_governor(Governor)` and `set_selected_pstate(i32)` enable D-Bus
clients to set governor/P-state directly.

**Mouse sub-panel navigation**: refined hit-test so left-click on
header/controls cycles governor, right-click toggles throttle,
middle-click on table expands P-state. Header now has two distinct
actions (governor + throttle) reachable via different mouse buttons.

**v1.2 source state**: 2758 LoC across **11 modules** (was 2376/10 in
v1.1). New module: `config.rs` (224 lines). New dependencies:
`toml = "0.8"`, `dirs = "5"`, `serde = { version = "1", features = ["derive"] }`.

Cross-compiled binary: 3.2 MB stripped Redox ELF
(SHA256 `58b7812a5f673e227753c01e93a05678bd9e8f28101d8a447d70d4943170c40a`).

ISO rebuild status: still blocked by pre-existing upstream
nix-0.30.1 vs Redox relibc SaFlags incompatibility in uutils.
v1.2 binary IS staged and will be packaged into the next successful
ISO build once that issue is resolved (separate scope).

#### v1.3 Linux-host Fallbacks (2026-06-20)

Per the user's "still same n/a, nothing changed" feedback, v1.3 adds
runtime probes + Linux sysfs fallbacks so the binary shows real data
on a Linux host (not just on Redox bare metal).

| Item | Status |
|------|--------|
| `platform.rs` (NEW, 291 LoC) — `Platform::Redox/Linux/Other` + per-source probes | ✅ |
| `msr.rs::read_msr` falls back to `/dev/cpu/{cpu}/msr` via `lseek+pread` | ✅ |
| `acpi.rs::read_cpu_stats` falls back to `/proc/stat` aggregation | ✅ |
| `acpi.rs::read_acpi_pss` falls back to `/sys/.../scaling_available_frequencies` | ✅ |
| `cpufreq.rs::read_governor_hint` falls back to `/sys/.../scaling_governor` | ✅ |
| Removed hardcoded P0..P5 fallback table (zero-stub policy) | ✅ |
| New `Sources:` header line: `MSR=ok PSS=no load=ok gov=ok hwmon=ok` | ✅ |
| Hwmon detection filters for `coretemp`/`k10temp`/`zenpower` | ✅ |
| `eprintln!` per failed probe naming the failure mode | ✅ |

**Sources header line** replaces the misleading `P-state source: fallback
table (no ACPI _PSS / sysfs)` line from v1.2. Each `=ok`/`=no` reflects
the actual runtime probe result, so the user sees at a glance which
data sources are live vs unreachable on this host.

**v1.3 source state**: 3501 LoC across **12 modules** (was 2758/11 in
v1.2). New module: `platform.rs` (291 lines).

Cross-compiled binary: 3.3 MB stripped Redox ELF
(SHA256 `cbc0a6d04e9d9252314dd71a1c411d4c488417e25f8d860970f718990864431a`).

Linux host smoke test (`./target/release/redbear-power --once`):

Sources: MSR=ok PSS=no load=ok gov=ok hwmon=ok

PSS=no reflects the AMD-pstate driver on this host which uses
`amd_pstate_*` sysfs names (not `scaling_available_frequencies`).
MSR=ok probe but actual `pread(/dev/cpu/0/msr)` blocked by CAP_SYS_RAWIO
at kernel level — code is correct, host needs `setcap cap_sys_rawio+ep`.

#### v1.4 System Tab Memory + OS Info (2026-06-20)

Per the user's "continue implementing more features from cpu-x" directive,
v1.4 ships System tab enhancements for memory bars and OS identity.

| Item | Status |
|------|--------|
| `meminfo.rs` (NEW, 241 LoC) — `MemInfo`, `OsInfo`, `read_meminfo`, `read_os_info`, `format_kib`, `format_uptime` | ✅ |
| System tab OS identity line (`Manjaro Linux \| Kernel: 7.0.10-1-MANJARO \| Host: moryzen \| Up: 15d 20h 2m 54s`) | ✅ |
| System tab memory summary (`Mem: 16.8 GiB used / 62.5 GiB total`) | ✅ |
| 5 memory bars: Used / Buffers / Cached / Free / Swap (Swap hidden if 0) | ✅ |
| Unicode block-character bars (`█` filled, `░` empty) — 20 cells wide | ✅ |
| Refresh cadence: meminfo + os_info every 4th tick (avoids `/proc/meminfo` hammering) | ✅ |

**Data sources opened at runtime** (strace-confirmed):
- `/proc/meminfo` — MemTotal, MemFree, MemAvailable, Buffers, Cached,
  SwapTotal, SwapFree, Shmem, SReclaimable
- `/etc/os-release` — PRETTY_NAME field
- `/etc/hostname` — system hostname
- `/proc/uptime` — system uptime

**Linux host smoke test** (Manjaro, Ryzen 9 7900X, 64 GiB):

OS: Manjaro Linux Kernel: 7.0.10-1-MANJARO Host: moryzen Up: 15d 20h 2m 54s Mem: 16.8 GiB used / 62.5 GiB total Used: [█████░░░░░░░░░░░░░░░] 26.9% 16.8 GiB / 62.5 GiB Buffers: [░░░░░░░░░░░░░░░░░░░░] 0.9% 577.9 MiB / 62.5 GiB Cached: [█████████░░░░░░░░░░░] 45.4% 28.4 GiB / 62.5 GiB Free: [█████░░░░░░░░░░░░░░░] 26.9% 16.8 GiB / 62.5 GiB Benchmark: (idle)


**v1.4 source state**: 3864 LoC across **13 modules** (was 3501/12 in
v1.3). New module: `meminfo.rs` (241 lines).

Cross-compiled binary: 3.7 MB stripped Redox ELF
(SHA256 `fa83f4205ef7ed46e2542eed9975463ba1a2663bdcd85045d078100f830341bb`).

**Forward work on Redox target** (deferred to v1.5+):
- `/proc/meminfo` and `/proc/uptime` don't exist on Redox yet.
- Required: add `meminfo` scheme daemon + `/etc/os-release` /
  `/etc/hostname` to `base` recipe's `[[files]]`.
- Until then, `read_meminfo()` and `read_os_info()` return empty structs
  on Redox → System panel honestly reports empty data (zero-stub policy).

#### v1.5 Motherboard Tab (DMI/SMBIOS) (2026-06-20)

Per the user's "continue implementing more features from cpu-x" directive,
v1.5 ships the **Motherboard tab** as the 4th tab in the multi-view system.

| Item | Status |
|------|--------|
| `dmi.rs` (NEW, 118 LoC) — `DmiInfo` with 18 fields + per-field sysfs read | ✅ |
| `TabId::Motherboard` variant + cycle order (`PerCpu → System → Info → Motherboard`) | ✅ |
| Hotkey `4` jumps directly to Motherboard tab | ✅ |
| `render_motherboard_panel()` with 4 sections: System / Board / BIOS / Chassis | ✅ |
| Sources header line: added `dmi=ok\|no` after `hwmon=` | ✅ |
| `render_once` now dumps Motherboard panel for headless verification | ✅ |

**Data sources opened at runtime** (strace-confirmed):
- `/sys/class/dmi/id/sys_vendor`, `product_name`, `product_family`,
  `product_version`, `board_vendor`, `board_name`, `board_version`,
  `board_serial`, `board_asset_tag`, `bios_vendor`, `bios_version`,
  `bios_date`, `bios_release`, `chassis_vendor`, `chassis_type`,
  `chassis_version`, `chassis_asset_tag` (all 18 fields)

**Linux host smoke test** (Manjaro, MSI MPG X670E CARBON WIFI):

Manufacturer: Micro-Star International Co., Ltd. (System + Board) Product: MS-7D70 Name: MPG X670E CARBON WIFI (MS-7D70) BIOS Vendor: American Megatrends International, LLC. BIOS Version: 1.74 BIOS Date: 05/12/2023 BIOS Release: 5.26 Chassis Type: 3 (Desktop)


`product_serial` and `product_uuid` correctly report `?` (root-only
readable; redbear-power runs unprivileged).

**v1.5 source state**: 4117 LoC across **14 modules** (was 3864/13 in
v1.4). New module: `dmi.rs` (118 lines).

Cross-compiled binary: 3.7 MB stripped Redox ELF
(SHA256 `c44d508cf6fefa28134b9f9c0b3493a34ddbff4028328c88ff30ac23bd14f2e8`).

**Forward work on Redox target** (deferred to v1.6+):
1. **SMBIOS table parser in kernel** — read the SMBIOS EPS, walk the
   structure table, parse Type 0/1/2/3 records.
2. **`scheme:dmi` userspace daemon** — exposes parsed SMBIOS records
   via `/scheme/dmi/{board_vendor,bios_vendor,...}` (mirrors sysfs).
3. **redbear-power fallback** — `DmiInfo::read()` tries Redox scheme
   first, then `/sys/class/dmi/id/` (Linux host).

Until then, the Motherboard panel on Redox honestly reports empty data
(rather than fake values) — per the zero-stub policy.

#### v1.6 Battery Tab (2026-06-20)

Per the user's "v1.6 = Battery tab (Recommended)" directive, v1.6
ships the **Battery tab** as the 5th tab in the multi-view system.

| Item | Status |
|------|--------|
| `battery.rs` (NEW, 128 LoC) — `BatteryInfo` with 15 fields + per-field sysfs read | ✅ |
| `TabId::Battery` variant + cycle order (`PerCpu → System → Info → Motherboard → Battery`) | ✅ |
| Hotkey `5` jumps directly to Battery tab | ✅ |
| `render_battery_panel()` with 3 sections: Identity / State / Power | ✅ |
| `RBP_BATTERY_PATH` env override (useful for testing + dev workflow) | ✅ |
| `render_once` now dumps Battery panel for headless verification | ✅ |

**Data sources opened at runtime** (when battery present):
- `/sys/class/power_supply/BAT0/type` — device type filter
- `status`, `capacity`, `energy_now`, `energy_full`, `power_now`,
  `voltage_now`, `time_to_empty`, `time_to_full`, `cycle_count`,
  `technology`, `model_name`, `manufacturer`, `serial_number` (13 fields)

**Mock battery smoke test** (`RBP_BATTERY_PATH=/tmp/fake-battery`):

Manufacturer: MSI Technology: Li-ion Cycles: 127 Status: Discharging Capacity: 67% Health: 67% Energy: 33.50 Wh / 50.00 Wh Power: 8.50 W Voltage: 12.50 V Time to empty: 3h 0m Time to full: ?


µWh → Wh conversion verified (33,500,000 µWh → 33.50 Wh); µV → V
conversion verified (12,500,000 µV → 12.50 V); `time_to_full=0`
correctly hidden.

**On actual desktop host** (no battery):

(no battery detected — /sys/class/power_supply/BAT* not present)


**v1.6 source state**: 4359 LoC across **15 modules** (was 4117/14 in
v1.5). New module: `battery.rs` (128 lines).

Cross-compiled binary: 3.8 MB stripped Redox ELF
(SHA256 `c6fca1728faff9edd053b933f0c57075e25dfe52450b7ab604d04d5024b1cc88`).

**Forward work on Redox target** (deferred to v1.7+):
1. **`power_supply` scheme daemon** — exposes battery state via
   `/scheme/power_supply/BAT0/{status,capacity,...}` (mirrors sysfs).
2. **ACPI battery object parser** — read `_BST` (battery status) and
   `_BIF` (battery information) AML methods; convert to `BatteryInfo`
   fields.
3. **Per-tick refresh** — battery state should be polled at 2-5 Hz,
   not read once at startup. Move `BatteryInfo::read()` into
   `App::refresh()` with 5-tick throttling.
4. **redbear-power fallback** — `find_battery_dir()` tries Redox
   scheme first, then `/sys/class/power_supply/` (Linux host).

Until then, the Battery panel on Redox honestly reports empty data
(rather than fake values) — per the zero-stub policy.

#### v1.7 Per-Tick Battery Refresh (2026-06-20)

Per the user's "v1.7 = Per-tick battery refresh (Recommended)"
directive, v1.7 closes the v1.6 forward-work item.

| Item | Status |
|------|--------|
| Move `BatteryInfo::read()` into `App::refresh()` with 5-tick throttling | ✅ |
| Reuse `refresh_counter` (no new field) | ✅ |
| Cadence: 2.5 sec at default POLL_MS=500 (0.04% CPU cost) | ✅ |
| Independent of meminfo cadence (5th tick vs 4th tick — coprime) | ✅ |
| `find_battery_dir()` re-checks on each refresh (laptop plugged-in mid-session works) | ✅ |

**Verification**: Mock battery at `/tmp/fake-battery/BAT0/` with
`capacity=67`. After `RBP_BATTERY_PATH=/tmp/fake-battery --once`, the
panel showed `67%`. Changed capacity file to `50`, re-ran `--once`,
panel showed `50%`. The 5-tick throttling fires on the first refresh
(`refresh_counter=0`, `0 % 5 == 0`), so `--once` mode picks up the
current value.

**Build verification**: Same 3.8 MB stripped Redox binary size as v1.6
(single `if` branch added to `App::refresh()`). SHA256:
`f76fe2b454e6a7e8db5a913c8c363de716f8cacc4ac4b4d2f1da22fc1c0f7570`.

**Cadence rationale**: 5-tick modulus deliberately coprime to meminfo's
4-tick modulus. With coprime moduli, battery and meminfo refreshes don't
synchronize — no thundering-herd of 14+4 sysfs reads at the same moment
(which would be visible to the user as a periodic 20ms stall).

#### v1.8 Bench Stress Modes (2026-06-20)

Per the user's "v1.8 = Bench stress modes (Recommended)" directive,
v1.8 extends `bench.rs` from a single prime-sieve to a 3-mode suite.

| Item | Status |
|------|--------|
| `BenchKind` enum: `PrimeSieve` / `Fft` / `Aes` | ✅ |
| `prime_worker()` — extracted from inline v1.0 loop | ✅ |
| `fft_worker()` — radix-2 Cooley-Tukey FFT on 1024-element f64 buffers | ✅ |
| `aes_worker()` — software AES-128 with FIPS-197 test vector | ✅ |
| `Bench::single_core` toggle (1 thread vs all cores) | ✅ |
| Hotkey `n` — cycle benchmark kind | ✅ |
| Hotkey `s` — toggle single-core vs all-cores | ✅ |
| 5 unit tests (`cargo test --release`) | ✅ all pass |
| Help text updated (controls panel + long help) | ✅ |

**Workload characteristics**:
| Mode | Characteristic | Cores for full saturation |
|------|----------------|---------------------------|
| Prime sieve | Branch-heavy, low IPC | All (limited by cache) |
| FFT | Memory-bound, SIMD-friendly | All (limited by memory bandwidth) |
| AES-128 | Pure-compute, integer-heavy | All (limited by ALU) |

**Use cases**:
- AES single-core vs multi-core ratio shows scaling efficiency
  (24x on independent cores, 8x on shared FSB).
- FFT multi-core stress = memory subsystem + cache hierarchy test.
- Prime sieve = fast thermal load (heats up quickest).

**v1.8 source state**: bench.rs 123 → 304 lines (+181). Total project
unchanged at ~4,380 LoC across 15 modules (v1.7).

Cross-compiled binary: 3.8 MB stripped Redox ELF
(SHA256 `a9892e716f1b93a36e8c5832c68ba31c10036c0c51e3911386e8b8d3ed1fe2b6`).

**Forward work** (deferred to v1.9+):
1. **AES-NI / AVX-512 intrinsics** — replace scalar AES with
   hardware-accelerated instructions when `is_x86_feature_detected!`
   returns true.
2. **Result history** — circular buffer of last N runs in System tab.
3. **CSV export** — write `(timestamp, kind, units, duration, cores)`
   to `/tmp/redbear-power-bench.csv`.

#### v1.9 Sensors Tab (hwmon) (2026-06-20)

Per the user's "v1.9 = Sensor tab (hwmon) (Recommended)" directive,
v1.9 ships the **Sensors tab** as the 6th tab in the multi-view system.

| Item | Status |
|------|--------|
| `sensor.rs` (NEW, 231 LoC) — `SensorKind` + `SensorReading` + `HwmonChip` + `SensorInfo` | ✅ |
| `TabId::Sensors` variant + cycle order | ✅ |
| Hotkey `6` jumps to Sensors tab | ✅ |
| `render_sensor_panel()` with per-chip sections + Label/Value pairs | ✅ |
| Unit conversion: m°C → °C, mV → V, µW → W, mA → A, RPM as int | ✅ |
| Per-tick refresh at 3-tick modulus (1.5 sec cadence) | ✅ |
| 7 unit tests covering unit conversions + empty state | ✅ all pass |
| 12 total tests (5 bench + 7 sensor) | ✅ all pass |

**Data sources opened at runtime** (when hwmon present):
- `/sys/class/hwmon/hwmonN/name` — chip identifier
- `temp*_input` (m°C), `temp*_label`
- `fan*_input` (RPM), `fan*_label`
- `in*_input` (mV), `in*_label`
- `power*_input` (µW), `power*_label`
- `curr*_input` (mA), `curr*_label`

**Linux host smoke test** (Manjaro, Ryzen 9 7900X):

Detected 7 chip(s), 11 sensor(s) total: ▸ mt7921_phy0 temp 58.0 °C ▸ r8169_0_e00:00 temp 51.0 °C ▸ k10temp Tccd1 82.6 °C Tccd2 57.1 °C Tctl 85.6 °C ▸ nvme Sensor 2 53.9 °C Composite 50.9 °C Sensor 1 50.9 °C ▸ spd5118 temp 50.0 °C ▸ spd5118 temp 51.5 °C ▸ nvme Composite 48.9 °C


**v1.9 source state**: 4885 LoC across **16 modules** (was ~4562/15 in
v1.8). New module: `sensor.rs` (231 lines). 12 unit tests total.

Cross-compiled binary: 3.8 MB stripped Redox ELF
(SHA256 `7a7c31bcf3577c99a72291c46d34e5d2d52951c1e78ee5d216760f41f623234b`).

**Refresh cadence**: sensor uses 3-tick modulus (1.5 sec at POLL_MS=500).
Combined with meminfo's 4-tick and battery's 5-tick moduli, all three
coprime — no two expensive sysfs reads ever fire in the same tick.

**Forward work on Redox target** (deferred to v1.10+):
1. **`hwmon` scheme daemon** in `redox-driver-sys` — exposes parsed
   sensor data via `/scheme/hwmon/<chip>/{...}`.
2. **Chip drivers** — k10temp, coretemp, nvme, etc. need user-space
   drivers feeding the scheme daemon.
3. **Per-CPU temperature integration** — map k10temp's `Tctl` to the
   `Pkg` column of selected CPU. Currently hwmon only exposes
   package-level temps, not per-core.
4. **redbear-power fallback** — `SensorInfo::read()` tries Redox scheme
   first, then `/sys/class/hwmon/` (Linux host).

Until then, the Sensors panel on Redox honestly reports empty data
(rather than fake values) — per the zero-stub policy.

#### v1.10 Per-CPU Pkg Temp from hwmon (2026-06-20)

Per the user's "v1.10 = Per-CPU Pkg temp from hwmon (Recommended)"
directive, v1.10 closes the v1.9 forward-work item. The Per-CPU table's
`Temp°C` column previously showed `n/a` for AMD CPUs because
`IA32_THERM_STATUS` is an Intel-only MSR. v1.10 falls back to hwmon
when the MSR is unavailable.

| Item | Status |
|------|--------|
| `SensorInfo::pkg_temp_c(cpu_index)` helper | ✅ |
| Recognizes k10temp Tctl (AMD Zen / Zen 2 / Zen 3 / Zen 4 / Zen 5) | ✅ |
| Recognizes coretemp "Package id 0" (Intel, forward-compat) | ✅ |
| Recognizes zenpower Tdie (AMD alt driver) | ✅ |
| Falls back from `IA32_THERM_STATUS` MSR to hwmon pkg_temp_c | ✅ |
| 5 new unit tests (k10temp / coretemp / zenpower / none / unrelated) | ✅ all pass |
| 17 total tests (5 bench + 12 sensor) | ✅ all pass |

**Linux host smoke test** (AMD Ryzen 9 7900X):
- Before v1.10: every CCD row showed `n/a` for Temp°C.
- After v1.10: every CCD row shows `85` (k10temp Tctl value, °C).

**Implementation pattern** in `App::refresh()`:
```rust
} else {
    // IA32_THERM_STATUS is Intel-only. On AMD, fall back to
    // k10temp Tctl (the package control temperature), which
    // applies to all CPUs on the same package.
    row.temp_c = self.sensors.pkg_temp_c(row.id);
    row.prochot = false;        // k10temp doesn't expose PROCHOT
    row.critical = false;       // k10temp doesn't expose Critical
    row.power_limit = false;    // k10temp doesn't expose Power Limit
}

PROCHOT/Critical/PowerLimit flags are set to false in the fallback path because k10temp doesn't expose these — only the temperature. Honest empty-state pattern: don't fake flag values.

Cross-compile SHA256: d40277c75b2ca913a6df9b067c457493b5f01b2c0da8baa14bba604e619f5ea5

Forward work (deferred to v1.11+):

  1. Per-CCD temperature — k10temp exposes Tccd1, Tccd2, etc. for each CCD cluster. Map these to per-CPU rows using cpuid leaf 0x8000001E NC field (already in v1.2 cpuid.rs).
  2. Multi-socket support — the cpu_index parameter in pkg_temp_c is currently ignored. On 2-socket systems, there are 2 k10temp chips. Future work: detect by phys_pkg_id from cpuid and route to the correct chip.
  3. PROCHOT on AMD — k10temp exposes temp*_max / temp*_crit thresholds. Future work: surface "approaching critical" warnings based on those thresholds.
  4. hwmon scheme daemon on Redox — see v1.9 forward work.

v1.11 Network Tab (sysfs + if_inet6) (2026-06-20)

Per the user's "v1.11 = Network tab (Recommended)" directive, v1.11 ships the Network tab as the 7th tab in the multi-view system.

Item Status
network.rs (NEW, 203 LoC) — NetInterface + NetInfo + IPv6 parser
TabId::Network variant + cycle order
Hotkey 7 jumps to Network tab
render_network_panel() with State/MAC/MTU/Speed/RX/TX/IPv6
Per-tick refresh at 7-tick modulus (3.5 sec cadence)
7 unit tests (format_bytes + empty state + zero traffic) all pass
24 total tests (5 bench + 12 sensor + 7 network) all pass

Data sources opened at runtime (when sysfs/net present):

  • /sys/class/net/<iface>/operstate — link state (up/down/unknown)
  • /sys/class/net/<iface>/speed — link speed in Mbps
  • /sys/class/net/<iface>/address — MAC address
  • /sys/class/net/<iface>/mtu — MTU
  • /sys/class/net/<iface>/statistics/{rx,tx}_{bytes,packets,errors,dropped}
  • /proc/net/if_inet6 — IPv6 addresses with scope encoding

Linux host smoke test (Manjaro, 6 interfaces: enp14s0, lo, moscow, tailscale0, tun0, wlp13s0):

  • Real link state: enp14s0=down, wlp13s0=up, others=unknown
  • Real traffic stats: lo (686 MiB), wlp13s0 (38/237 GiB), tailscale0 (2/11 GiB)
  • Real IPv6 addresses with correct scope encoding (link for fe80::, compat for fd7a/fd01)
  • MAC shown only when not 00:00:00:00:00:00 (enp14s0, wlp13s0 only)
  • Speed shown only when >0 (tun0=10000 Mbps)

v1.11 source state: ~5150 LoC across 17 modules (was ~4945/16 in v1.10). New module: network.rs (203 lines). 24 unit tests total.

Cross-compiled binary: 3.8 MB stripped Redox ELF (SHA256 05cca57693110e06393273a3247b159b8fc681a8ebc0cdd5a2386f33a1ebb407).

Refresh cadence: 7-tick modulus (3.5 sec at POLL_MS=500). Coprime with all existing moduli (3, 4, 5) — LCM of {3,4,5,7} = 420 ticks.

Forward work (deferred to v1.12+):

  1. Throughput calculation — compute rx_kbps / tx_kbps from delta of rx_bytes / tx_bytes over time.
  2. IPv4 addresses — currently only IPv6. IPv4 requires parsing /proc/net/fib_trie or shelling out to ip addr.
  3. ethtool stats — driver-specific counters via /sys/class/net/<iface>/{statistics,*} beyond the standard set.
  4. Network namespace detectionnetns info for containers.

v1.12 Storage Tab (sysfs) (2026-06-20)

Per the user's "v1.12 = Storage tab (Recommended)" directive, v1.12 ships the Storage tab as the 8th tab. Completes major hardware surface coverage: Per-CPU / System / Info / Motherboard / Battery / Sensors / Network / Storage.

Item Status
storage.rs (NEW, 261 LoC) — DiskInfo + DiskStats + kind heuristic
TabId::Storage variant + cycle order
Hotkey 8 jumps to Storage tab
render_storage_panel() with Model/Size/Scheduler/Queue/R+W/Parts
Per-tick refresh at 11-tick modulus (5.5 sec cadence)
10 unit tests (size + parse + delta + kind_label) all pass
34 total tests (5 bench + 12 sensor + 7 network + 10 storage) all pass

Data sources opened at runtime (when sysfs/block present):

  • /sys/block/<dev>/device/{model,vendor} — disk identity
  • /sys/block/<dev>/size — size in 512-byte sectors
  • /sys/block/<dev>/queue/{rotational,scheduler,nr_requests} — IO
  • /sys/block/<dev>/removable — removable flag
  • /sys/block/<dev>/stat — 15-field IO statistics (single line)
  • /sys/block/<dev>/<partition> — partitions (auto-discovered)

Linux host smoke test (3 disks: 2 NVMe SSD + 1 USB):

  • nvme0n1: ADATA SX6000PNP, 476.9 GiB, 2 partitions, 15/25 GiB R/W
  • nvme1n1: Samsung SSD 990 PRO 2TB, 1.8 TiB, 3 partitions, 30 MiB R
  • sdb: USB DISK 3.0, 57.7 GiB (Removable detected), 2 partitions

v1.12 source state: ~5415 LoC across 18 modules (was ~5150/17 in v1.11). New module: storage.rs (261 lines). 34 unit tests total.

Cross-compiled binary: 3.8 MB stripped Redox ELF (SHA256 3c44a545bb162abc7e671d689f025f01a424ee1508a2c2bd90af58f504b50ac4).

Refresh cadence: 11-tick modulus (5.5 sec). Coprime with all existing moduli (3, 4, 5, 7) — LCM of {3,4,5,7,11} = 9240 ticks.

Forward work (deferred to v1.13+):

  1. Throughput calculationDiskStats::kbps_delta() implemented but not wired. Store previous stats in App + add "R: 1.5 MiB/s" line.
  2. SMART data — read via smartctl --json if available. Skip if not (per zero-stub policy).
  3. NVMe-specific statsnvme*/queue/* + cross-ref with hwmon.
  4. Disk temperature — link hwmon temp to storage panel.

v1.13 Process Tab (procfs) (2026-06-20)

Per the user's "v1.13 = Process list (Recommended)" directive, v1.13 ships the Process tab as the 9th tab. Last major top-style view.

Item Status
process.rs (NEW, 215 LoC) — ProcessInfo + ProcInfo + stat parser
TabId::Process variant + cycle order
Hotkey 9 jumps to Process tab
render_process_panel() with PID/STATE/PRIO/NI/THR/RSS/VIRT/COMM columns
Per-tick refresh at 13-tick modulus (6.5 sec cadence)
9 unit tests (size + parse + edge cases) all pass
43 total tests (5 bench + 12 sensor + 7 network + 10 storage + 9 process) all pass

Data sources opened at runtime:

  • /proc/[pid]/stat — 52-field single line (man 5 proc)
  • /proc/[pid]/comm — fallback for process name extraction
  • /proc/ itself — scanned for numeric dir names = PIDs

Linux host smoke test (596 processes, top 50 shown):

  • opencode (3.7 GiB RSS), thunderbird (2.1 GiB), plasmashell (517 MiB)
  • kwin_wayland shows PRIO=-2 (real-time scheduling)
  • thread counts up to 92 (thunderbird)
  • Total RSS: 17.5 GiB

v1.13 source state: ~5635 LoC across 19 modules (was ~5415/18 in v1.12). New module: process.rs (215 lines). 43 unit tests total.

Cross-compiled binary: 3.9 MB stripped Redox ELF (SHA256 2c30f86dce574f173efdcf8eb588f83abd8f0bdf2c5a2678452dd0e6a244dbf2).

Refresh cadence: 13-tick modulus (6.5 sec). Coprime with all existing moduli (3, 4, 5, 7, 11) — LCM = 60060 ticks.

Forward work (deferred to v1.14+):

  1. CPU% column — store previous ticks, compute delta.
  2. Process filtering — search by name/regex.
  3. Sort modes — toggle between RSS/CPU/PID/name with hotkey.

v1.14 CPU% in Process Tab (2026-06-20)

Per the user's "v1.14 = CPU% in Process tab (Recommended)" directive, v1.14 closes v1.13 §37.6 forward work. Process tab now shows real-time CPU usage per process.

Item Status
cpu_pct: f64 field on ProcessInfo
ProcInfo::read_with_cpu_pct(prev, dt_secs, num_cpus)
Wall-clock dt (not tick-based)
prev_processes + prev_refresh_secs fields in App
CPU% column in render_process_panel
4 new unit tests (formula + zero + underflow + dt=0) all pass
47 total tests (5 bench + 12 sensor + 7 network + 10 storage + 13 process) all pass

Math sanity check (verified by unit test):

  • utime=100→200, stime=50→80, dt=2sec, num_cpus=4
  • delta = 280-150 = 130 ticks / 2 sec = 65 ticks/sec
  • CPU% = 65 / 4 cpus × 100 = 1625.0%
  • Yes, CPU% can exceed 100% on multi-core (single process can use multiple cores simultaneously)

Linux host smoke test:

  • After 13 ticks (6.5 sec) of running: opencode CPU% populates
  • In --once mode: all CPU% = 0.0 (binary exits before second refresh)

v1.14 source state: ~5680 LoC across 19 modules (was ~5635 in v1.13). 47 unit tests total.

Cross-compiled binary: 3.9 MB stripped Redox ELF (SHA256 d46cd66b8e158e2327839ef502879951877a5500d4a40807d3dbc72ed7397231).

Forward work (deferred to v1.15+):

  1. Process filtering — search by name/regex.
  2. Sort modes — toggle between RSS/CPU/PID/name with hotkey.
  3. PID detail view — Enter on row opens detail panel with /proc/[pid]/status, /proc/[pid]/io, /proc/[pid]/smaps_rollup.

v1.15 Disk Throughput in Storage Tab (2026-06-20)

Per the user's "v1.15 = Disk throughput (Recommended)" directive, v1.15 closes the v1.12 §36.6 forward-work item.

Item Status
read_kbps: f64 + write_kbps: f64 fields on DiskStats
StorageInfo::read_with_throughput(prev, dt_secs)
Wall-clock dt (shared with v1.14 process refresh via prev_refresh_secs)
prev_storage: StorageInfo field in App
R/W KiB/s in render_storage_panel Read/Written lines
3 new unit tests (formula + underflow + zero dt) all pass
49 total tests (5 bench + 12 sensor + 7 network + 12 storage + 13 process) all pass

Math sanity check (verified by unit test):

  • prev_read=1MB, now_read=5MB, dt=2sec → 1953.125 KiB/s
  • prev > now → saturating_sub → 0 (no panic)

Linux host smoke test:

  • After 11 ticks (5.5 sec): R/W KiB/s populates per disk
  • In --once mode: 0.0 (binary exits before second refresh)

v1.15 source state: ~5720 LoC across 19 modules (was ~5680 in v1.14). 49 unit tests total.

Cross-compiled binary: 3.9 MB stripped Redox ELF (SHA256 d1207b648ce89e19f8dd040f234648e1665f053ec31f8511ea187627d79bde2d).

Forward work (deferred to v1.16+):

  1. Network throughput — same pattern for NetInfo rx_kbps/tx_kbps.
  2. Per-process disk I/O — show per-process /proc/[pid]/io in Process tab.
  3. Disk temperature — link hwmon temp to Storage panel.

v1.16 Network Throughput in Network Tab (2026-06-20)

Per the user's "v1.16 = Network throughput (Recommended)" directive, v1.16 closes the v1.11 §35.7 forward-work item.

Item Status
rx_kbps: f64 + tx_kbps: f64 fields on NetInterface
NetInfo::read_with_throughput(prev, dt_secs)
Wall-clock dt (shared with v1.14 + v1.15 via prev_refresh_secs)
prev_net: NetInfo field in App
R/W KiB/s in render_network_panel RX/TX bytes lines
3 new unit tests (formula + underflow + zero dt) all pass
52 total tests (5 bench + 12 sensor + 10 network + 12 storage + 13 process) all pass

Math sanity check (verified by unit test):

  • prev=1MB, now=5MB, dt=2sec → 1953.125 KiB/s
  • prev > now → saturating_sub → 0 (no panic)

Linux host smoke test:

  • After 7 ticks (3.5 sec): R/W KiB/s populates per interface
  • In --once mode: 0.0 (binary exits before second refresh)

v1.16 source state: ~5755 LoC across 19 modules (was ~5720 in v1.15). 52 unit tests total.

Cross-compiled binary: 3.9 MB stripped Redox ELF (SHA256 053f1a0cca5185637d0316d56f5cf5832cf2e754b689bc24edf16ea5d0404fa2).

Forward work (deferred to v1.17+):

  1. Per-process network I/O/proc/[pid]/net/dev for per-process bytes.
  2. IPv4 addresses — currently only IPv6.
  3. ethtool driver stats — driver-specific counters.

3.4 D-Bus

Component Status Detail
dbus 1.16.2 🟢 Builds System bus socket path fix applied (2026-06-19): -Dsystem_socket=/run/dbus/system_bus_socket baked into dbus-1.pc at compile time
redbear-sessiond 🟢 Builds login1-compatible session broker; retry loops tuned (3 attempts, 1s)
redbear-upower 🟢 Builds UPower surface; retry loops tuned
redbear-polkit 🟢 Builds PolicyKit bridge; retry loops tuned
redbear-udisks 🟢 Builds UDisks2 service; retry loops tuned
redbear-dbus-services 🟢 Builds .service files + XML policies

System bus socket path (durable fix): dbus-1.16.2's meson.build:946 defaults system_bus_socket to {prefix}/{runstatedir}/dbus/system_bus_socket, which under Redox resolves to /usr/var/run/dbus/system_bus_socket (not /run/...). All Red Bear OS D-Bus clients hardcode /run/dbus/system_bus_socket to match the /run/dbus/system_bus_socket directory created by redbear-mini.toml's postinstall. The fix is in local/recipes/system/dbus/recipe.toml mesonflags:

"-Druntime_dir=/run",
"-Dsystem_socket=/run/dbus/system_bus_socket",

This bakes the correct value into dbus-1.pc's system_bus_default_address=unix:path=/run/dbus/system_bus_socket, so any client using the dbus-1 pkg-config metadata gets the correct path with no runtime env-var. The DBUS_SYSTEM_BUS_ADDRESS env var in 12_dbus.service is kept as defense-in-depth for the daemon.

Retry loops: Reduced from 5 attempts / 2 s to 3 attempts / 1 s in redbear-sessiond, redbear-upower, redbear-polkit, and redbear-udisks (four services). Original values were D-Bus startup-friendly but too slow on Redox where the bus becomes available quickly after daemon start.

Known issue: dbus-daemon --system fails user lookup for messagebus user in some runtime configurations.

3.5 Qt6 / KF6 / KDE Plasma

Qt6

Component Status
qtbase 6.11.0 (Core+Gui+Widgets+DBus+Wayland) 🟢 Builds — 7 libs + 12 plugins (target: 6.11.1)
qtdeclarative 🟢 Builds — QML interpreter-only (-DQT_FEATURE_qml_jit=OFF); 86 QtQuick + 83 QtQml headers staged; 106 libQt6{Qml,Quick}*.so libs present
qtwayland 🟢 Builds — Wayland QPA plugin
qtsvg 🟢 Builds
Qt6::Sensors 🟡 Builds (dummy backend, 520KB pkgar)
QtNetwork 🟢 Re-enabled — DNS resolver hardened

KF6 Frameworks — 36 build, 12 blocked

Building (36 packages): karchive, kauth, kbookmarks, kcodecs, kcolorscheme, kcompletion, kconfig, kconfigwidgets, kcoreaddons, kcrash, kdbusaddons, kdeclarative, kded6, kglobalaccel, kguiaddons, ki18n, kiconthemes, kidletime, kio, kitemmodels, kitemviews, kjobwidgets, knotifications, kpackage, kservice, ktextwidgets, kwayland, kwidgetsaddons, kwindowsystem, kxmlgui, solid, sonnet, kcmutils, attica, kdecoration, kglobalacceld

Blocked (12 packages):

Package Reason
kirigami Qt6 Wayland null+8 crash prevents runtime QML; headers/libs DO exist
plasma-framework Depends on kirigami (runtime validation, not build)
plasma-workspace Depends on kf6-knewstuff payload + real kwin
plasma-desktop Transitive — depends on plasma-workspace
kf6-knewstuff Empty package — cmake succeeds but core source produces no libs with QtQuick off
breeze Build issues
kde-cli-tools Build issues
kf6-prison Source issues
kf6-kwallet QML/GPG disabled; not in current enabled subset
kf6-purpose Not attempted
kf6-frameworkintegration Not attempted
kf6-krunner Not attempted

KWin / Plasma Session

Component Status
kwin 🔴 Blocked — real cmake build requires working Qt6 Wayland runtime (null+8 crash); redbear-compositor provides the kwin_wayland binary as a separate package
kwin real build 🔄 Attempted — gated on Qt6 Wayland null+8 crash resolution
plasma-workspace 🔴 Blocked
plasma-desktop 🔴 Blocked (transitive)
Full Plasma session 🔴 Not functional

CORRECTION — The "QML JIT gate" was FALSE (v5.0, 2026-06-20):

Previous versions of this document (v4.x) claimed QQuickWindow/QQmlEngine headers were "unavailable" and that QML JIT was "the single biggest desktop blocker." This was factually wrong. Agent-verified findings (2026-06-20):

  • 86 QtQuick header files exist in the sysroot (include/QtQuick/)
  • 83 QtQml header files exist in the sysroot (include/QtQml/)
  • 106 libQt6{Qml,Quick}*.so shared libraries are staged
  • qtdeclarative BUILDS successfully with -DQT_FEATURE_qml_jit=OFF (interpreter-only QML)
  • QML interpreter-only mode works — JIT is an optimization, not a requirement

The REAL desktop blocker is the Qt6 Wayland null+8 crash (see §3.1). Qt6 Wayland clients segfault in wl_proxy_add_listener() when the compositor returns NULL for an unsupported interface. A candidate fix (qtwaylandscanner-null-guard-listeners.patch) is wired into qtwayland's recipe but has never been runtime-validated. This crash prevents SDDM greeter, KWin, and all Qt6 Wayland clients from running — but it is NOT a QML/JIT issue.

Resolving this crash unblocks: kirigami (runtime), plasma-framework, KWin real build, SDDM greeter, and the entire Qt6 Wayland client surface.

3.6 Version Targets — "Latest Upstream" (v5.0, 2026-06-20)

User mandate: "kde, qt, wayland - all must be latest versions!"

Component Current Target Status
Qt6 (qtbase) 6.11.0 6.11.1 Minor bump needed
SDDM 0.21.0 0.21.0 Already latest stable
KDE Plasma (not built) 6.7.0 (2026-06-11) Future target
KDE Frameworks 6 (KF6) various 6.27.0 (2026-06-05) Update recipe revs
ECM various 6.27.0 (2026-06-02) Update recipe revs
libwayland 1.24.0 1.25.0 (2026-03-19) Bump needed
wayland-protocols (current) 1.49 (2026-06-07) Update
plasma-wayland-protocols (current) 1.21.0 Update

4. Network & Wireless

4.1 Wired Networking — Working

  • Native Redox net stack present (pcid-spawner → NIC daemon → smolnetd/dhcpd/netcfg)
  • redbear-netctl native command shipped
  • RTL8125 autoload wired through Realtek path
  • VirtIO networking in QEMU: DBUS_SYSTEM_BUS=present

4.2 Wi-Fi — Host-tested, no hardware

  • Intel PCIe transport builds, 119 tests
  • LinuxKPI compat with 17 modules, 93 tests
  • redbear-wifictl daemon + scheme interface
  • Bounded host-tested scan/connect/disconnect/profile flows
  • Blocker: No Intel hardware available; MediaTek MT7921K on current host

4.3 Bluetooth — Experimental BLE-first

  • Controller probe via USB, HCI init, scheme:hciN
  • GATT client workflow (discover→read), 209 tests
  • QEMU validation in progress

5. Honest Blocker Map

Critical Path (ordered)

[0] Wire SDDM + pam-redbear into config         → login prompt target
[1] Qt6 Wayland null+8 crash resolution          → unblocks ALL Qt6 Wayland clients
[2] SDDM greeter renders under compositor         → SDDM login prompt in QEMU
[3] Real KWin build                               → unblocks plasma-workspace → plasma-desktop
[4] Mesa virgl runtime wiring + QEMU -virtio-vga-gl → GPU-accelerated SDDM
[5] Hardware GPU validation                       → unblocks Mesa HW renderers
[6] ACPI shutdown robustness                      → release-grade ACPI
[7] Bare-metal validation                         → unblocks all hardware claims

Blocker Detail

# Blocker What's needed Estimated effort Hardware required
0 SDDM config wiring Add sddm + pam-redbear to redbear-full.toml; create init service; configure SDDM compositor path 2-3 days No
1 Qt6 Wayland null+8 crash Rebuild libwayland→qtbase→qtdeclarative→qtwayland with null-guard patch; validate QML window renders under redbear-compositor 1-2 weeks No
2 SDDM greeter runtime SDDM greeter (QML) launches as Wayland client of redbear-compositor; user sees login prompt 1 week No
3 Mesa virgl runtime Wire missing patches into recipe.toml; test with -device virtio-vga-gl 3-5 days No (QEMU)
4 KWin real build Real cmake build of KWin; requires Qt6 Wayland runtime working 2-4 weeks No
5 Plasma session plasma-workspace + plasma-desktop cmake builds; requires kirigami + kwin 2-4 weeks No
6 HW GPU backend CS ioctl implementation → Mesa HW renderer cross-compile 12-20 weeks Yes — AMD/Intel GPU
7 ACPI shutdown Remove panic paths, deterministic _S5 2-4 weeks No
8 Bare-metal proof Real AMD/Intel hardware validation for all layers 4-8 weeks Yes — AMD + Intel machines

Path to SDDM Login Prompt (Blocks 0-2) — IMMEDIATE TARGET

Wire SDDM config (2-3d) → Resolve null+8 crash (1-2w) → SDDM greeter renders (1w)
                                                              ↓
                                                  SDDM login prompt in QEMU
                                                  Total: 2-3 weeks
                                                  With virgl: + 3-5 days

Path to Software-Rendered KDE Plasma (Blocks 0-5)

SDDM login (2-3w) → KWin real build (2-4w) → Plasma session (2-4w)
                                                          ↓
                                              Software-rendered KDE Plasma on Wayland
                                              Total: 6-11 weeks (from current state)

Path to Hardware-Accelerated KDE Plasma (Blocks 0-8)

Software-rendered path (6-11w)
    + virgl runtime wiring (3-5d, QEMU proof)
    + GPU CS ioctl backend + Mesa HW cross-compile (12-20w, parallel)
    + Hardware validation (4-8w, parallel)
                                                          ↓
                                              Hardware-accelerated KDE Plasma on Wayland
                                              Total: 18-31 weeks

6. What Changed Since v3.0 (2026-04-29 → 2026-04-30)

Change Impact
Credential syscalls implemented setgroups/getgroups/initgroups/RLIMIT functional. Unblocks polkit, dbus, logind, sudo.
Kernel groups process-scoped setgroups() propagates to all process threads. NGROUPS_MAX enforced.
CallerCtx.groups added Schemes can now check supplementary group membership for access control.
Kernel readback for getgroups Cache is repopulated from kernel after exec/crash.
setrlimit returns proper errors EINVAL for unknown resources, EPERM for process limits.

7. Configuration Surface

config/redbear-full.toml enables the desktop-capable target:

  • 36 KDE packages (33 kf6-* + kdecoration + kglobalacceld + kwin); 12 blocked
  • mesa + libdrm (software GPU stack, swrast + virgl — virgl runtime patch wiring PENDING)
  • qtbase + qtdeclarative + qtwayland + qtsvg + qt6-wayland-smoke
  • seatd + redbear-authd + redbear-session-launch + redbear-greeter (legacy)
  • dbus + firmware-loader + redox-drm + evdevd + udev-shim
  • redbear-compositor (real Rust Wayland compositor)
  • SDDM v0.21.0 + pam-redbear — WIRED (v5.3): [packages] enabled, 21_sddm.service wired, /etc/sddm.conf installed
  • plus inherited packages from redbear-mini profile

8. Evidence Model

Evidence Class What It Means
Source Code exists in tree
Host build-verified cargo check zero warnings on Linux
Redox build-verified make r.* successful on x86_64-unknown-redox
Runtime-validated Exercised in QEMU
Hardware-validated Exercised on real AMD/Intel hardware

Current highest evidence bar reached: QEMU runtime proof for greeter/login, bounded compositor, D-Bus system bus, evdevd/udev-shim, DRM scheme enumeration.

No component has hardware validation. All hardware claims remain evidence-qualified.


9. Subsystem Plans (Reference)

This document is the authority. Subsystem plans remain for deep-dive detail:

Plan Covers
KERNEL-IPC-CREDENTIAL-PLAN.md Kernel credential syscalls, IPC, RLIMIT — Phases K1-K2,K4 complete
IRQ-AND-LOWLEVEL-CONTROLLERS-ENHANCEMENT-PLAN.md PCI/IRQ/MSI-X/IOMMU quality
ACPI-IMPROVEMENT-PLAN.md ACPI shutdown, power, sleep states
RELIBC-IPC-ASSESSMENT-AND-IMPROVEMENT-PLAN.md relibc IPC surface
DRM-MODERNIZATION-EXECUTION-PLAN.md DRM/KMS modernization
WAYLAND-IMPLEMENTATION-PLAN.md Wayland compositor stability
DBUS-INTEGRATION-PLAN.md D-Bus architecture
GREETER-LOGIN-IMPLEMENTATION-PLAN.md Greeter/login design

10. Stale Docs Deleted (This Pass)

File Reason
COMPREHENSIVE-OS-ASSESSMENT.md Consolidated into this document
DESKTOP-STACK-CURRENT-STATUS.md Consolidated into this document
AMD-FIRST-INTEGRATION.md Historical — AMD and Intel are equal-priority targets
HARDWARE-3D-ASSESSMENT.md Historical — consolidated into §2
DMA-BUF-IMPROVEMENT-PLAN.md Historical — consolidated into §2
INPUT-SCHEME-ENHANCEMENT.md Historical — consolidated into §3.2
BOOT-PROCESS-ASSESSMENT.md Historical — consolidated into §1
LINUX-BORROWING-RUST-IMPLEMENTATION-PLAN.md Historical — consolidated into §2
QT6-PORT-STATUS.md Historical — consolidated into §3.5
REDBEAR-INFO-RUNTIME-REPORT.md Historical — validation infrastructure now standard
RELIBC-COMPREHENSIVE-ASSESSMENT.md Historical — consolidated into §1.5
RELIBC-COMPLETENESS-AND-ENHANCEMENT-PLAN.md Historical — consolidated into §1.5
RELIBC-IMPLEMENTATION-PLAN.md Historical — consolidated into §1.5