Files
RedBear-OS/local/docs/DESKTOP-SERVICES-ASSESSMENT.md
T
vasilito e289904852 docs: add 8 comprehensive audit/assessment documents (7500+ lines total)
- STUBS-AUDIT-AND-REWRITE-PLAN.md: master plan, 20 drivers audited
- USB-STUBS-AUDIT.md: USB stack focus, xhcid/usbhubd/usbctl/usbhidd/usbscsid/ucsid
- HID-STUBS-AUDIT.md: HID focus, usbhidd/i2c-hidd/intel-thc-hidd/ps2d/inputd/evdevd
- LOWLEVEL-STUBS-AUDIT.md: ACPI/PCI/IRQ/IOMMU/boot/init, 50+ row coverage
- BOOT-AND-HW-ENABLEMENT-ASSESSMENT.md: kernel to display chain, NO VESA policy
- DESKTOP-SERVICES-ASSESSMENT.md: D-Bus, session, audio, network
- CONFIG-AND-INIT-ASSESSMENT.md: configs, init.d, recipes, layering
- GPU-MESA-KDE-CHAIN-ASSESSMENT.md: Mesa to Plasma build chain

These documents track the v6.0 stub-fix campaign and the comprehensive
Phase 1-5 implementation work. All cited paths and line numbers are
real. Documents are durable in local/docs/ which survives make distclean.
2026-06-09 12:06:18 +03:00

1573 lines
78 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Desktop Services Assessment — D-BUS, SESSION, AUDIO, NETWORK, SECURITY
**Generated:** 2026-06-09
**Scope:** All services between `pcid`/`driver-manager` and `sddm`/KDE that must be running,
correctly wired, and correctly sequenced on `redbear-full` to deliver a working Wayland login
prompt and a working KDE desktop on QEMU and bare metal.
**Companion to:** `CONSOLE-TO-KDE-DESKTOP-PLAN.md`, `DBUS-INTEGRATION-PLAN.md`,
`GREETER-LOGIN-IMPLEMENTATION-PLAN.md`, `WIFI-IMPLEMENTATION-PLAN.md`,
`USB-IMPLEMENTATION-PLAN.md`, `BLUETOOTH-IMPLEMENTATION-PLAN.md`.
This document is **audit only**. No source files are modified.
---
## Executive Summary
| Metric | Value |
|---|---|
| Recipes surveyed in `local/recipes/system/` | 47 |
| Total Rust LoC in the desktop-services chain (sessiond + authd + launch + greeter + wifictl + netctl + info + polkit + upower + udisks + notifications + statusnotifier + audiod + dhcpd + netstack) | ~16,000 LoC |
| Recipes with `#TODO` first-line header in `recipe.toml` | 5 (dbus, redbear-polkit, redbear-upower, redbear-udisks, redbear-notifications) |
| Stubs / no-op returns in `redbear-sessiond` `Manager` | 7 (all `can_*` power methods) |
| Stubs / no-op returns in `redbear-sessiond` `Session` | 2 (`kill`) |
| Stub backend in `redbear-wifictl` (`StubBackend`) | real, used when no driver present |
| No-op no-op service definitions (`cmd = "echo ... skipped"`) | 1 (seatd on `redbear-mini`) |
| `*Stub` types / `*stub` return tokens in service code | 4 in `wifictl/backend.rs`, 1 in `redbear-greeter-compositor` fallback |
| Hardcoded `val = ...` / `Ok(0)`-style constants in real D-Bus methods | 0 in code; multiple "na" strings |
| `vec![]` returns in real D-Bus interface methods | 6 (UDisks2 SupportedFilesystems/SupportedEncryptionTypes/Symlinks, etc.; Polkit EnumerateActions; notifications/Idle) |
| `unimplemented!()` / `todo!()` in any recipe under `local/recipes/system/` | 0 |
| Daemons referenced in `config/redbear-full.toml` whose binary is not built | 0 (all packages compile) |
| Daemons in the chain that have **no service file in `redbear-full.toml`** | 2 (`redbear-notifications`, `redbear-statusnotifierwatcher`) |
| Daemons built but **not started by init** (not in any config) | 2 (`redbear-notifications`, `redbear-statusnotifierwatcher`) |
| Wireless driver path actually compiled into the chain | 1 (Intel `redbear-iwlwifi`, gated by `/lib/drivers.d/60-wifi.toml`) |
| **PipeWire / WirePlumber / PulseAudio** in the chain | **0 — not implemented, no recipe, no service** |
| **`seatd` for Redox backend** in the chain | 0 (upstream seatd only; no `seatd-redox` integration; `redbear-compositor` and KWin use env-var hints instead) |
| **`pam` / `polkit` with real authority** in the chain | 1 (polkit daemon present, but policy is **a flat file lookup with no JavaScript .rules loading, no auth agent**) |
| Estimated LoC to finish the minimum to SDDM login screen | ~1,800 LoC (34 weeks) |
| Estimated LoC to finish the minimum to a working Plasma desktop | ~4,500 LoC (812 weeks) |
### Phase blockers (must clear before `redbear-full` boots to a KDE desktop)
1. **D-Bus system bus activation order is a soft failure**`redbear-sessiond` retries the
`name` registration 5 times and prints a retry, but if it still fails it exits fatally. The
order in `redbear-full.toml` is correct (12_dbus → 13_redbear-sessiond → 13_seatd →
11_redbear-authd → 12_sddm) but `redbear-sessiond` is `oneshot_async`; it is
*not* a D-Bus `.service` activation. The `org.freedesktop.login1.service` file IS staged
by `redbear-dbus-services`, but it is essentially unused — `redbear-sessiond` connects to
the system bus directly as a bus-name owner. This works only because the bus is up.
2. **No session bus wired into the KDE session.** `redbear-notifications` (which talks to the
session bus) and `redbear-statusnotifierwatcher` (session bus) are built and installed but
**no service file starts them in the user session**. KDE Plasma needs the session bus to
start at user session launch; this is missing.
3. **seatd is not on the redox backend.** The `seatd` binary is built and its init service
runs, but the upstream `seatd` is intended for Linux DRM/KMS file descriptor passing.
Redox has no DRM fd semantics in the Linux sense — `redbear-compositor` and the
`redbear-greeter-compositor`/`redbear-kde-session` shell scripts use
`LIBSEAT_BACKEND=seatd` and `SEATD_SOCK=/run/seatd.sock` env vars but no code in the
Red Bear chain actually calls libseat to open DRM devices. KWin's own seatd code path
is therefore a no-op; KWin talks directly to `/scheme/drm/card0`.
4. **No PipeWire / WirePlumber.** The chain stops at `audiod` (the audio device scheme
daemon). PipeWire and WirePlumber recipes are absent. The kde-session wrapper hardcodes
`MESA_LOADER_DRIVER_OVERRIDE=virtio_gpu` but does not start any audio session manager.
5. **No PAM.** `redbear-authd` reads `/etc/passwd` and `/etc/shadow` directly. There is no
libpam, no `pam_unix.so`, no `pam_systemd.so`. SDDM expects libpam; on Redox it is
loaded but a real `pam.conf` is absent. Authentication falls through to whatever SDDM's
PAM stack does, which on Redox is **not** going through `redbear-authd` (see §2.4).
### High-level assessment
The D-Bus → sessiond → authd → greeter → KWin chain has the **shapes** of a real
login1/PolicyKit/UPower/UDisks2 stack. Each daemon is real Rust, builds, and the interfaces
are well-modeled. The fundamental gaps are:
* The **user session is not constructed** — there is no session bus, no D-Bus activation in
the user context, no D-BUS_SESSION_BUS_ADDRESS set by redbear-session-launch.
* **No PipeWire** for audio.
* **No PAM** — `redbear-authd` exists but is not the PAM backend SDDM uses.
* The initfs → rootfs handoff is **two-stage and self-aware**, but the
D-Bus/system-services directory staging in the *rootfs* (via `redbear-dbus-services` recipe)
happens via `[[files]]` in `redbear-full.toml` only for the *system* side. The
`/etc/dbus-1/session.d/` and `/usr/share/dbus-1/session-services/` content from
`redbear-dbus-services` will be present, but nothing in the user-session launch path
actually runs `dbus-launch` or sets `DBUS_SESSION_BUS_ADDRESS`.
* KWin's sessionBus() calls **block on Redox Unix-socket connect()** even when the daemon
is running (per the explicit comment in `redbear-greeter-compositor` line 81-86).
This is why KWin's startup `QDBusConnection::sessionBus()` calls have been bypassed in
the KWin source per the comment. We do not know how many call sites were bypassed
(the KWin recipe is a built-from-source port); this is a known architectural issue.
---
## Per-Stage Assessment
### 1. D-Bus
#### 1.1 Packages
| Recipe | Type | Files | Source size | Build state |
|---|---|---|---|---|
| `local/recipes/system/dbus` | upstream tarball (dbus 1.16.2) + 24-line `redox.patch` | 102 .c/.h files unpacked (~340k LoC) | 50,000+ LoC | Builds |
| `local/recipes/system/redbear-dbus-services` | custom (config-only) | 11 .service / .conf files (102 LoC) | 102 LoC | Builds |
#### 1.2 `#TODO` in recipe
`local/recipes/system/dbus/recipe.toml:1`:
```
#TODO: validate runtime (dbus-daemon --system + dbus-launch for session bus)
```
This is the only `#TODO` in the D-Bus packaging layer. It explicitly calls out that the
session bus (`dbus-launch` / `dbus-run-session`) has **not been validated** at runtime.
#### 1.3 Patch scope
`local/recipes/system/dbus/redox.patch` (24 lines) does exactly two things:
* `dbus-pollable-set-epoll.c`: relax `#ifndef __linux__` to `#if !defined(__linux__) && !defined(__redox__)`.
* `dbus-spawn-unix.c`: change `_dbus_socketpair(..., TRUE, ...)` to `... FALSE ...`.
The first is a no-op on Redox (the file is for Linux epoll). The second changes the
socketpair `cloexec` flag from TRUE to FALSE — a behavioral change that may leak file
descriptors into the babysitter child.
#### 1.4 Build configuration
`local/recipes/system/dbus/recipe.toml:14-25` disables:
* `-Dx11_autolaunch=disabled` (X11 not in scope)
* `-Dsystemd=disabled` (no systemd)
* `-Dlaunchd=disabled` (no launchd)
* `-Dchecks=false` (test code disabled)
* `-Dasserts=false` (assertions disabled)
* `-Dxml_docs=disabled`, `-Dducktype_docs=disabled`, `-Ddoxygen_docs=disabled`
These are reasonable but mean **D-Bus internal assertions are off in production** — silent
state-machine corruption will not panic.
#### 1.5 Service activation files (in tree)
`local/recipes/system/redbear-dbus-services/source/system-services/`:
| Service file | Bus name | Exec | Notes |
|---|---|---|---|
| `org.freedesktop.login1.service` | `org.freedesktop.login1` | `/usr/bin/redbear-sessiond` | `User=root` |
| `org.freedesktop.PolicyKit1.service` | `org.freedesktop.PolicyKit1` | `/usr/bin/redbear-polkit` | `User=root`, `SystemdService=redbear-polkit.service` |
| `org.freedesktop.UPower.service` | `org.freedesktop.UPower` | `/usr/bin/redbear-upower` | `User=root`, `SystemdService=redbear-polkit.service` (note: copy/paste bug — points at polkit not upower) |
| `org.freedesktop.UDisks2.service` | `org.freedesktop.UDisks2` | `/usr/bin/redbear-udisks` | `User=root`, `SystemdService=redbear-udisks.service` |
**Stale code / copy-paste defect:**
`local/recipes/system/redbear-dbus-services/source/system-services/org.freedesktop.UPower.service:4`
sets `SystemdService=redbear-polkit.service`. The `SystemdService=` D-Bus key is
a hint to activation helpers for systemd-translation, not a hard requirement. It is harmless
in our context (we use Redox init, not systemd) but it is wrong.
`local/recipes/system/redbear-dbus-services/source/session-services/`:
| Service file | Bus name | Exec |
|---|---|---|
| `org.kde.kded6.service` | `org.kde.kded6` | `env QT_QPA_PLATFORM=offscreen /usr/bin/kded6` |
| `org.kde.kglobalaccel.service` | `org.kde.kglobalaccel` | `/usr/bin/kglobalacceld` |
| `org.freedesktop.Notifications.service` | `org.freedesktop.Notifications` | `/usr/bin/redbear-notifications` |
The `kded6.service` file forces `QT_QPA_PLATFORM=offscreen` with a comment
"Qt6 Wayland crashes at null+8 during wl_registry init on Redox" (line 4-5 of that file).
This is a real workaround for a real Redox/Qt6 bug.
There is **no `org.kde.KWin.service` or `org.kde.plasmashell.service`**
D-Bus activation file in the source tree, even though the
`redbear-kde-session` wrapper references `kglobalacceld` and KWin.
#### 1.6 Policy files
`local/recipes/system/redbear-dbus-services/source/system.d/`:
* `org.freedesktop.login1.conf` — full access from root + introspection/properties/Manager/Session/Seat from default context. **Reasonable.**
* `org.freedesktop.PolicyKit1.conf` — root owns; default context may send. **Reasonable.**
* `org.freedesktop.UDisks2.conf` — root owns; default context may send. **Reasonable but
too permissive**: a non-root user could mount arbitrary storage. Should be gated through
polkit (which currently has a one-line `is_authorized`).
* `org.freedesktop.UPower.conf` — root owns; default context may send. **Same comment.**
`local/recipes/system/redbear-dbus-services/source/session.d/`:
* `org.redbear.session.conf` — wildcard allow for `org.kde.*`, `org.freedesktop.Notifications`,
`org.freedesktop.StatusNotifierWatcher`. **Wildcard `.allow own` for `org.kde.*` is a
permissive default that is acceptable for a single-user desktop but should be documented.**
#### 1.7 Service activation order in `redbear-full.toml`
* `12_dbus.service``cmd = "/usr/bin/dbus-daemon --system --nopidfile"` (line 310).
* `13_redbear-sessiond.service``requires_weak = ["12_dbus.service"]` (line 321).
* `13_seatd.service``requires_weak = ["12_dbus.service", "13_redbear-sessiond.service"]` (line 335).
* `11_redbear-authd.service``requires_weak = ["12_dbus.service"]` (line 439).
* `12_sddm.service` — requires dbus, sessiond, seatd, authd, evdevd, redox-drm, driver-manager
(lines 449-460).
The order is **correct**. The `type = "oneshot_async"` is the right choice for each of
the daemons that need to start and stay running.
#### 1.8 Missing wirings (D-Bus area)
1. **No `redbear-notifications.service` or `redbear-statusnotifierwatcher.service` in any
config.** Both are built and installed (recipe + package files entry). Neither has
`[[files]]` in `redbear-full.toml` and neither has a unit file under
`local/recipes/system/redbear-{notifications,statusnotifierwatcher}/source/init.d/`.
They will not auto-start.
2. **No `dbus-launch` invocation in `redbear-session-launch`.** Look at
`local/recipes/system/redbear-session-launch/source/src/main.rs:341-358`
(`command_for`) — the function reads `LaunchMode::Session` and returns
`("/usr/bin/dbus-run-session", vec!["--", "/usr/bin/redbear-kde-session"])`
if `/usr/bin/dbus-run-session` exists, else just `/usr/bin/redbear-kde-session`. This is
a thin wrapper, but `dbus-run-session` itself is from dbus, which is built, so the
wrapper would be used. **However**, in `redbear-kde-session` (line 152) the script does
`eval "$(dbus-launch --sh-syntax)"` again. So the session bus is started twice — once
by `dbus-run-session` (which sets `DBUS_SESSION_BUS_ADDRESS`) and once by `dbus-launch`
(which overwrites it). This is benign in the sense that the second call will use a new
socket file path, but it leaks a process.
3. **No `DBUS_SYSTEM_BUS_ADDRESS` set in `redbear-session-launch` for the user
environment.** It IS set in `redbear-full.toml` via
`/etc/environment.d/90-dbus.conf:650` to
`unix:path=/run/dbus/system_bus_socket`. KDE services like `kglobalacceld`,
`plasma-session`, etc. need both.
4. **DBUS session bus socket location**: `redbear-session-launch` builds `XDG_RUNTIME_DIR`
to `/run/user/{uid}` (or `/tmp/run/user/{uid}`), and `dbus-run-session` by default
creates a socket at `$XDG_RUNTIME_DIR/bus`. SDDM's greeter has UID 102
(`sddm` user). The user session launched by `redbear-session-launch` will run as
UID 1000 (`user`). These are two different XDG_RUNTIME_DIRs. `redbear-kde-session`
sets `XDG_RUNTIME_DIR="/tmp/run/user/$(id -u)"` if unset. The user session bus will
live at `/tmp/run/user/1000/bus`, the greeter session bus will live at
`/var/lib/sddm` (or wherever the greeter's XDG_RUNTIME_DIR is). KDE Plasma connects
to the bus at `XDG_RUNTIME_DIR/bus`, so this is consistent for the user session
**but the SDDM greeter is not wired**.
5. **No `org.kde.KWin.service`, `org.kde.plasmashell.service`,
`org.kde.kglobalacceld.service`** in the source tree. Without these, kglobalacceld
and plasma-shell will not auto-activate via D-Bus on a fresh session.
6. **No system-bus `.service` for `redbear-authd`.** The authd doesn't speak D-Bus (it
speaks a JSON-over-Unix-socket protocol). The `redbear-greeter` connects to
`/run/redbear-authd.sock` directly (see `local/recipes/system/redbear-greeter/source/src/main.rs:135-150`).
This is fine for the greeter flow but SDDM itself does not connect to authd — it
expects to go through PAM.
#### 1.9 Stale / half-impl code (D-Bus area)
* `redbear-sessiond/source/src/manager.rs:171-188``power_off`, `reboot`, `suspend` all
log a message and return `Ok(())`. They do not call any actual shutdown or reboot
system call. The `redbear-greeter` calls `AuthRequest::PowerAction` → authd
`run_power_action` which actually invokes `/usr/bin/shutdown` or `/usr/bin/poweroff`
(see `redbear-authd/source/src/main.rs:342-361`). So the **end-to-end power flow works
through authd, not sessiond**. sessiond's power methods are correct DBus no-ops because
the request gets re-dispatched via authd. **Stale-but-correct.**
* `redbear-sessiond/source/src/session.rs:206-212``kill` logs a message and returns
`Ok(())`. SDDM may call this to terminate the user's session. It is a stub. A real impl
would send SIGTERM to `runtime.leader`.
* `redbear-sessiond/source/src/manager.rs:329-330, 339-341``KillSession` and `KillUser`
log "no-op" and return `Ok(())`. Same as above.
* `redbear-polkit/source/src/main.rs:144``CheckAuthorization` always
returns `(is_authorized(0, action_id), !authorized, ...)` — i.e. always queries the
policy file with `uid=0`. **This means polkit always reports the result for root, even
when the caller is not root.** The function signature takes no UID argument; it has
no way to know the caller. **This is a security defect**, but in practice only `root`
and `sddm` (uid 102) can call D-Bus methods to polkit on Redox given the policy files.
The fix is to use the D-Bus `caller` mechanism (zbus provides this via the connection
metadata) or to read the peer's UID from the socket.
#### 1.10 D-Bus area: missing wirings summary
| # | Missing | Impact |
|---|---|---|
| 1 | `redbear-notifications` service file | KDE notifications will not appear |
| 2 | `redbear-statusnotifierwatcher` service file | System tray will be empty |
| 3 | `org.kde.KWin.service` D-Bus activation | KWin will not auto-activate |
| 4 | `org.kde.kglobalacceld.service` D-Bus activation | Global shortcuts won't work |
| 5 | `org.kde.plasmashell.service` D-Bus activation | Plasma shell may not auto-start |
| 6 | `redbear-sessiond` `kill`/`power_*` real impls | Power off / reboot will be via authd but signal handling is brittle |
| 7 | polkit caller-UID extraction | Privilege boundary is broken |
---
### 2. Session Management
#### 2.1 `redbear-sessiond` (`org.freedesktop.login1`)
**Location:** `local/recipes/system/redbear-sessiond/source/src/`
**LoC:** 2,017 (across `main.rs`, `manager.rs`, `session.rs`, `seat.rs`, `control.rs`,
`device_map.rs`, `runtime_state.rs`, `acpi_watcher.rs`)
**Bus name:** `org.freedesktop.login1`
**Implementation language:** Rust, `zbus = "5"` with `tokio` runtime.
The implementation is the **most complete** piece of the chain. The `LoginManager`,
`LoginSession`, `LoginSeat` interfaces all map cleanly to the freedesktop.org
specification, and the runtime state is shared via `Arc<RwLock<SessionRuntime>>`
(`runtime_state.rs:50`).
**Tests:** Each module has unit tests in a `#[cfg(test)] mod tests` block. Total: ~30
test functions. All use `shared_runtime()` for isolated state.
##### 2.1.1 Real implementations
* `get_session`, `list_sessions`, `get_seat`, `get_user`, `list_users`, `list_seats`
(`manager.rs:65-209`) — all return paths derived from runtime state.
* `inhibit` (`manager.rs:103-141`) — returns a real `OwnedFd` from a Unix stream pair,
tracks the entry in runtime.
* `activate_session`, `activate_session_on_seat`, `lock_session`, `unlock_session`,
`lock_sessions`, `unlock_sessions`, `terminate_session`, `terminate_user`
(`manager.rs:229-320`) — all update runtime state and return `Ok`.
* `LoginSession::take_control`, `release_control`, `take_device`, `release_device`
(`session.rs:78-150`) — real implementation with a `controlled` mutex and
`taken_devices: HashSet<(u32, u32)>`. `take_device` opens a real file from
`DeviceMap::open_device` (which returns a real `File`).
* `set_idle_hint`, `set_locked_hint`, `set_type`, `terminate` (`session.rs:160-204`) —
all update runtime state.
* `LoginSeat::switch_to` (`seat.rs:65-80`) — invokes `inputd -A <vt>` via
`Command::new("inputd").args(["-A", &vt.to_string()])`. This is the real VT switch.
##### 2.1.2 Stubs (returns 0 / no-op / "na")
* `can_power_off`, `can_reboot`, `can_suspend`, `can_hibernate`, `can_hybrid_sleep`,
`can_suspend_then_hibernate`, `can_sleep` (`manager.rs:143-169`) — all return
`Ok(String::from("na"))`. Per the freedesktop.org spec, "na" means "not available".
The KDE Power Management plasmoid and SDDM both check `CanPowerOff`/`CanReboot` and
will **hide the corresponding buttons** if "na" is returned. This means the user
cannot trigger a clean shutdown from the SDDM greeter without the manual
`RequestShutdown` path. The fix is to check whether the `shutdown` binary exists.
* `IdleSinceHint`, `IdleSinceHintMonotonic` (`manager.rs:349-357`) — both return `0`.
These are timestamp values that should reflect when the session became idle. A
constant `0` means "idle since epoch" which is wrong.
* `InhibitDelayMaxUSec` (`manager.rs:387-390`) — returns `0`. Per the spec, this is
the max delay (in microseconds) an inhibitor can request. `0` is "no delay", which
is conservative but correct.
* `HandleLidSwitch` (`manager.rs:393-395`) — returns `"ignore"`. The kernel has a
real ACPI lid switch. We should wire this to "suspend" or "poweroff".
* `HandlePowerKey` (`manager.rs:398-400`) — returns `"poweroff"`. Reasonable default.
* `PreparingForSleep` (`manager.rs:402-404`) — always `false`. Real impl would track
the suspend state machine.
* `power_off`, `reboot`, `suspend` (`manager.rs:171-187`) — log and return `Ok(())`.
No actual call to `reboot()` syscall or ACPI shutdown register. Power action
flows through `redbear-authd` instead (see `redbear-authd/source/src/main.rs:342-361`).
* `get_session_by_pid`, `get_user_by_pid` (`manager.rs:189-195`) — always return
the current session/user. A real impl would scan `/proc`.
* `LoginSession::kill` (`session.rs:206-212`) — log "no-op" and return `Ok(())`. A
real impl would `kill(runtime.leader, signal_number)`.
* `LoginManager::kill_session`, `kill_user` (`manager.rs:322-342`) — same as above.
* `PauseDeviceComplete` (`session.rs:152-158`) — log only. Real impl would
resume I/O on the device.
##### 2.1.3 DeviceMap
`device_map.rs` provides a real implementation that discovers `/scheme/drm/card*` and
`/dev/input/event*` at startup and merges them with static fallback entries
(`(226, 0) -> "/scheme/drm/card0"` etc.). It uses `rdev()` from `MetadataExt` to map
inode-style device numbers to (major, minor).
**Stale code in `device_map.rs`:**
* `dev_major` (`device_map.rs:230-232`) — the implementation
```
fn dev_major(device: u64) -> u32 {
(((device >> 31 >> 1) & 0xfffff000) | ((device >> 8) & 0x00000fff)) as u32
}
```
is an unusual bit-pick from a packed Linux `dev_t`. This is the Linux-style 32-bit
dev_t encoding, but Redox's `Metadata::rdev()` returns a Redox-native device
identifier, **not** the Linux encoding. The unit tests in `device_map.rs:241-258`
use `make_dev` which constructs a *Linux-shaped* dev_t, so the tests pass but the
real `rdev()` value from a Redox file may not match. **This is a stale-code bug.**
* The fallback logic (`device_map.rs:87-99`) is real and uses `Path::exists()` — but
`Path::exists()` on Redox scheme paths is unreliable (the
`redbear-greeter-compositor` script uses `( exec 3<"/scheme/drm/card0" )` instead
of `test -e` or `stat`). The `DeviceMap` should be using the same pattern.
##### 2.1.4 ACPI watcher
`acpi_watcher.rs` is 48 lines and exposes `watch_and_emit(connection, runtime)` which
spawns a tokio task. **Stale code**: only the function signature is in the source;
the actual implementation is in a separate patch
`local/patches/redbear-sessiond/P4-signal-implementations.patch` (referenced from
`local/recipes/system/redbear-sessiond/recipe.toml:3`).
#### 2.2 `redbear-authd`
**Location:** `local/recipes/system/redbear-authd/source/src/main.rs`
**LoC:** 719
**Implementation language:** Rust, with `argon2`, `sha-crypt`, `redbear-login-protocol`.
This is the **most-tested** piece of the chain — 12 unit tests covering password
verification, lockout, VT mismatch, etc.
##### 2.2.1 Real implementations
* `load_shadow_passwords` (lines 102-123) — reads `/etc/shadow` line-by-line.
* `load_account` (lines 125-171) — reads `/etc/passwd` and joins with shadow.
* `verify_shadow_password` (lines 184-194) — handles `$6$` (SHA-512 crypt), `$5$`
(SHA-256 crypt), `$argon2`. **Real, robust.**
* `verify_password` (lines 196-215) — handles plain text, locked (`!`/`*`), and
hashed passwords.
* `login_allowed` (lines 177-182) — refuses non-root with uid < 1000, refuses empty
shell.
* `remember_success`, `remember_failure`, `check_lockout` (lines 217-271) — real
rate-limiting with a 60-second window and 30-second lockout.
* `take_approval` (lines 273-288) — 15-second expiry on auth approval, VT mismatch
rejection.
* `run_power_action` (lines 342-361) — invokes `/usr/bin/shutdown`, `shutdown`, or
`poweroff` in that order.
* `handle_request` (lines 363-451) — dispatch for Authenticate / StartSession /
PowerAction.
##### 2.2.2 Stubs / half-impls
* `send_sessiond_update` (lines 290-299) — silently fails on
`UnixStream::connect(SESSIOND_SOCKET_PATH)` failure. If `redbear-sessiond` is not
running (or hasn't created the control socket), the auth result will not propagate
to the runtime. **Connection failures should be logged.**
* `launch_session` (lines 301-340) — hard-codes `kde-wayland` as the only supported
session. Any other session name returns `Err("unsupported session '...'")`. This
is fine for a single-session kiosk but blocks any X11 fallback.
* `VALIDATION_REQUEST_PATH` (line 25) is a hardcoded path
`/run/redbear-kde-session.validation-request`. The validation-request mechanism
is a Red Bear test harness for "did the compositor expose a Wayland socket". It
is **not** a real authd concept. The `Path::new(VALIDATION_REQUEST_PATH).exists()`
check on line 326 changes the wait behavior from blocking (`child.wait()`) to
fire-and-forget. This is a test-harness leak into the production code path.
##### 2.2.3 `login_allowed` strictness
`login_allowed` (line 177-182) rejects any non-root account with `uid < 1000`. The
config-defined `messagebus` user is uid 100, `greeter` is uid 101, `sddm` is uid 102.
None of them can log in. This is by design (service accounts, not users) but it
means a config that puts a real user at uid 999 will be silently rejected.
#### 2.3 `redbear-session-launch`
**Location:** `local/recipes/system/redbear-session-launch/source/src/main.rs`
**LoC:** 628
**Implementation language:** Rust, no async, uses `std::os::unix::process::CommandExt`.
##### 2.3.1 Real implementations
* `parse_passwd` (lines 133-170) — handles both Redox `;` and Unix `:` layouts.
* `parse_groups` (lines 172-199).
* `load_supplementary_groups` (lines 210-226).
* `build_environment` (lines 252-323) — sets all the KDE-required env vars:
`XDG_CURRENT_DESKTOP=KDE`, `KDE_FULL_SESSION=true`, `XDG_SESSION_ID=c1`,
`WAYLAND_DISPLAY=wayland-0`, `XDG_SEAT=seat0`, `XDG_VTNR=<vt>`,
`XDG_SESSION_TYPE=wayland`, `XDG_RUNTIME_DIR=<runtime_dir>`. Also forces
`KWIN_DRM_DEVICES=/scheme/drm/card0` if the env var is unset (line 290-293).
* `apply_groups` (lines 325-339) — `cfg(target_os = "redox")` returns `Ok(())`
(no-op); non-redox calls `libc::setgroups`. This is **correct for Redox** because
the kernel does not yet have a real supplementary-groups syscall. Per the project
README, supplementary groups were added 2026-04-30 — but `apply_groups` was not
updated to actually use them. **Stale code.**
* `command_for` (lines 341-358) — returns `/usr/bin/dbus-run-session -- /usr/bin/redbear-kde-session`
for the `kde-wayland` session, else error.
* `run` (lines 361-394) — `env_clear()`s, sets env, calls `command.uid(...)` and
`command.gid(...)` and `command.pre_exec(apply_groups)`, then `command.exec()`.
##### 2.3.2 Stubs / half-impls
* `apply_groups` no-op on Redox (see 2.3.1).
* No `setrlimit` calls. Some KDE processes (e.g. `kwin_wayland`) want increased
resource limits.
* No PR_SET_PDEATHSIG — if `redbear-session-launch` crashes after `exec`, the
child process becomes orphaned. SDDM expects the launched session to die with
its launcher.
#### 2.4 `redbear-greeter`
**Location:** `local/recipes/system/redbear-greeter/source/src/main.rs`
**LoC:** 656
**Two side scripts:** `redbear-greeter-compositor` (Bash, 4,310 bytes),
`redbear-kde-session` (Bash, 8,936 bytes)
##### 2.4.1 Real implementations
* `GreeterDaemon::new` (lines 163-196) — binds `/run/redbear-greeterd.sock`, sets
0o660, chowns to the `greeter` user.
* `load_uid_gid` (lines 106-122) — reads `/etc/passwd`, handles both layouts.
* `change_socket_ownership` (lines 124-133) — `libc::chown`.
* `start_surface` (lines 261-279) — spawns `redbear-greeter-compositor` (which in
turn launches `kwin_wayland --drm /scheme/drm/card0` or `redbear-compositor`),
waits for the Wayland socket (up to 30 seconds), then launches the QML greeter
UI as the `greeter` user.
* `note_restart` (lines 289-299) — bounds restart attempts to 3 per minute.
* `handle_connection` (lines 346-439) — processes Hello, SubmitLogin,
RequestShutdown, RequestReboot.
* `launch_session` (lines 319-344) — sends `AuthRequest::StartSession` to
`redbear-authd`, which then forks `redbear-session-launch` to start KDE.
* 10 unit tests.
##### 2.4.2 Stubs / half-impls
* `COMPOSITOR_BIN_PATH` (line 18) is `/usr/bin/redbear-greeter-compositor` and
`COMPOSITOR_SHARE_PATH` (line 19) is `/usr/share/redbear/greeter/redbear-greeter-compositor`.
The daemon picks whichever exists (`Path::is_file()` at line 264). **The recipe
installs both.** This is not a stub but is redundant.
* `wait_for_wayland_socket` (lines 250-259) — polls every 250ms for 30 seconds. The
daemon will report `FatalError` (line 295) after 3 restarts in 60 seconds. There
is no override for users to bypass the failure; they cannot log in.
* `handle_connection` does not validate the `version` of the request beyond
`version != 1` (line 361). Future protocol versions are not negotiated.
* `redbear-greeter-compositor` (Bash script) — line 81-86 has an explicit comment
acknowledging that **Qt6's QDBusConnection::sessionBus() blocks on Redox
Unix-socket connect()** even when the daemon is running, and that KWin's
sessionBus() calls in the startup path have been bypassed. This is a known
architectural issue. It also forces `MESA_LOADER_DRIVER_OVERRIDE=virtio_gpu`
unconditionally, which is wrong for Intel/AMD targets.
* `redbear-greeter-compositor:60-66` — the `wait_for_drm_scheme` polls for 10
seconds (configurable via `REDBEAR_DRM_WAIT_SECONDS`) using the open-as-probe
pattern. This is correct, not a stub.
* `redbear-greeter-compositor:75-86` — fallback path: if no DRM device, runs
`$COMPOSITOR` again without `KWIN_DRM_DEVICES`. The comment says "no DRM at all —
fall back to virtual backend." The `$COMPOSITOR` here is `kwin_wayland` or
`redbear-compositor`, neither of which is the *virtual* QPA backend — they are
both Wayland compositors. **A real virtual fallback would set
`QT_QPA_PLATFORM=offscreen` or `minimal`**, not just unset the device. This is
a half-impl: the env var unset is correct for KWin's `--virtual` mode but
`--virtual` is not passed.
##### 2.4.3 `redbear-kde-session` (Bash) — half-impls
This script is what runs after a successful auth. Real impls:
* Sets KDE env vars (lines 36-54).
* Writes `/run/redbear-kde-session.env` (the session env file consumed by
`dbus-update-activation-environment`).
* Calls `dbus-update-activation-environment` if available.
* Falls back to virtual if `KWIN_DRM_DEVICES` is empty AND DRM is not ready
(lines 117-145).
* Waits for the Wayland socket (up to 40 seconds) (lines 184-202).
Stubs and leaks:
* Line 152: `if [ -z "${DBUS_SESSION_BUS_ADDRESS:-}" ] && command -v dbus-launch >/dev/null 2>&1; then eval "$(dbus-launch --sh-syntax)"; fi`
— this starts **a second session bus** on top of the one started by
`dbus-run-session` in `redbear-session-launch`. The first bus address is
discarded. The two buses are independent processes, which can confuse KDE
components that use `qdbus` to talk to the bus.
* Line 207: `kded6` is launched with `QT_QPA_PLATFORM=offscreen` to work around
the Qt6 Wayland null+8 crash. This is fine but means KDE services that depend
on kded6 graphics will not function correctly.
* Line 208: `plasmashell` is launched with no QPA override. **It will crash
on the Qt6 Wayland null+8 bug** unless the upstream KWin build avoids the
crash. This is a probable runtime failure on `redbear-full`.
* Line 209: `wait "$kwin_pid"` — the script will not exit until kwin dies. If
kwin dies with a non-zero exit, the script returns that exit code. There is
no logic to relaunch kwin or to enter a degraded mode.
#### 2.5 Service activation order (Session Management)
The chain on `redbear-full`:
```
12_dbus.service
└─ dbus-daemon --system
13_redbear-sessiond.service
└─ redbear-sessiond (zbus, claims org.freedesktop.login1)
13_seatd.service
└─ seatd -l info
11_redbear-authd.service
└─ redbear-authd (Unix socket, not D-Bus)
[12_sddm.service]
└─ sddm (expects PAM; expects login1; expects seatd)
```
The chain on `redbear-mini` is the same but with seatd replaced by an
`echo "seatd: skipped on live-mini"` (line 393 of `redbear-mini.toml`).
**Missing wire:** the `redbear-full.toml` does **not** define a
`12_greeter.service` that launches `redbear-greeterd`. It defines `12_sddm.service`
directly. SDDM in turn is expected to be the greeter. This is consistent with the
overall design ("SDDM is the login screen"), but the redbear-greeter implementation
exists alongside — it is unused on `redbear-full`. This is **dead code** unless we
decide to swap SDDM for the redbear-greeter.
#### 2.6 Cross-cutting session issues
1. **SDDM does not talk to `redbear-authd`.** SDDM expects PAM. The
`local/sources/relibc` (Redox relibc) does not ship a `libpam`. SDDM's PAM
stack will fail to load. SDDM is built (`recipes/wip/...`) and packaged
(`redbear-full.toml:156 sddm = {}`), but **the runtime path is broken**
unless a fake `pam_unix.so` is shipped that proxies to `redbear-authd`.
2. **SDDM's expected GreeterEnvironment includes `WAYLAND_DISPLAY`**, but the
`redbear-full.toml:572` `sddm.conf` only sets `QT_PLUGIN_PATH`,
`QML2_IMPORT_PATH`, `QT_QPA_PLATFORM_PLUGIN_PATH`. **Missing
`WAYLAND_DISPLAY=wayland-0`** and `XDG_SESSION_TYPE=wayland`.
3. **`redbear-kde-session` is not started by SDDM** — the
`/usr/share/wayland-sessions/plasmawayland.desktop` (lines 593-601 of
`redbear-full.toml`) `Exec` is `/usr/bin/kwin_wayland --drm /scheme/drm/card0`.
That launches **just kwin**, not plasmashell, kded6, kglobalacceld, etc. The
user will see a black screen with a cursor.
---
### 3. Seat Management (seatd)
#### 3.1 Location
* Recipe: `local/recipes/system/seatd/recipe.toml` (16 lines, upstream
`https://git.sr.ht/~kennylevinsen/seatd/archive/0.9.1.tar.gz`).
* Source: `local/recipes/system/seatd/source/`
* Total LoC: 2,003 in `seatd/*.c`.
#### 3.2 Is it built? — Yes
`redbear-mini.toml:387-396` defines a seatd service but it is a no-op
(`cmd = "echo"; args = ["seatd: skipped on live-mini"]`). `redbear-full.toml:330-342`
defines the real `seatd -l info`.
#### 3.3 Is it started before SDDM? — Yes, but not used
The order in `redbear-full.toml:330` is:
```
13_seatd.service
requires_weak = [
"12_dbus.service",
"13_redbear-sessiond.service",
]
```
`12_sddm.service:454-460` requires `13_seatd.service`. So the order is correct.
#### 3.4 Does it work? — Partially
`seatd` is a C daemon that accepts connections on `/run/seatd.sock` and brokers
DRM master, input device, and tty access. The `redbear-full.toml:444` env block
sets `SEATD_SOCK=/run/seatd.sock` for authd, and `redbear-session-launch:272`
sets `SEATD_SOCK=/run/seatd.sock` and `LIBSEAT_BACKEND=seatd` for the user session.
**However:**
* `redbear-compositor` (`local/recipes/wayland/redbear-compositor/source/`) and
KWin (built from upstream) expect to call `libseat_open_device()` to obtain a
DRM file descriptor. The Redox DRM scheme is not file-descriptor-based in the
Linux sense — `/scheme/drm/card0` is a control channel, not a stream. So
`libseat_open_device()` will succeed at the libseat level but the returned fd
is meaningless.
* The actual `KWin::OpenDrmDevice()` path on Redox uses
`KWIN_DRM_DEVICES=/scheme/drm/card0` env var and opens the scheme path
directly via `QFile`. This bypasses seatd entirely.
* `seatd` is therefore running but **not actually being used** for DRM access.
The same is true for input devices: `evdevd` exposes them as scheme paths,
not Linux fds.
#### 3.5 Stubs / stale code (seatd)
* `seatd` is upstream 0.9.1. It has a `#if defined(__linux__)` path for evdev and
DRM. On Redox, those code paths are not compiled. The `meson.build` is
unmodified; it will use whatever backend is auto-detected. The
`common/drm.c` and `common/evdev.c` are Linux-only.
#### 3.6 Cross-cutting seat issues
* **SDDM-KWin-libseat integration** is non-functional. The fallback in
`redbear-greeter-compositor:60-66` (open-as-probe) is what KWin actually relies on.
* **No fallback for SDDM** if `seatd` rejects seat creation. SDDM aborts.
* **`CanGraphical` is hardcoded `true` in `LoginSeat`** (`seat.rs:97-99`).
This is fine if seatd succeeds, but if seatd is unable to attach the seat to
a graphics device, the property should be `false`. The check is done in
`seatd`, not in redbear-sessiond.
---
### 4. Audio / PipeWire
#### 4.1 `audiod` daemon
**Location:** `local/sources/base/audiod/src/`
**LoC:** 277 (100 main.rs + 177 scheme.rs)
**Built into the rootfs**: yes, via `local/sources/base/init.d/20_audiod.service`
(declared in `local/sources/base/init.d/20_audiod.service`).
The `redbear-mini.toml:178-190` overrides the init.d entry with a `oneshot_async`
copy. The `redbear-full.toml` does not override it, so it inherits the rootfs default.
##### 4.1.1 Real implementations
* `audiod` opens `/scheme/audiohw` (line 51) and, on success, enters a constrained
namespace and a scheme request loop. If `/scheme/audiohw` does not exist, the
daemon **exits with code 0** (line 55: `eprintln!("audiod: no audio hardware
found, exiting ({e})"); process::exit(0);`). This is the correct behavior
for systems without audio hardware.
* The scheme backend (`scheme.rs`) implements the audio scheme — the same scheme
is used by QEMU's `ac97` and Intel HDA drivers.
##### 4.1.2 Stubs / half-impls
* None in the daemon itself. The daemon is small, well-bounded, and works.
#### 4.2 PipeWire / WirePlumber
**PipeWire recipe:** none. **WirePlumber recipe:** none. **PulseAudio recipe:** none.
The chain stops at `audiod`. There is no session audio manager.
For KDE Plasma to make sound:
* PipeWire (or PulseAudio) must be running.
* WirePlumber (if PipeWire) must be running to manage the policy.
* The `XDG_SESSION_ID` and `PIPEWIRE_REMOTE` env vars must be set in the user
session.
* `pw-cli` and the KDE audio integration (`libKF6PulseAudioOtp`, or
`plasma-pa`) must link against libpipewire.
**None of this exists in the current chain.** KDE Plasma will compile and
link with `plasma-pa` (which is part of the upstream Redox build), but at
runtime the audio backend is not present, and any KDE app that tries to play
audio will fail.
#### 4.3 PipeWire integration with redbear-kde-session
The `redbear-kde-session` script does not start `pipewire` or `wireplumber`.
The session is missing the audio subsystem entirely.
#### 4.4 Cross-cutting audio issues
1. **No PipeWire port**. The Redox Audio scheme (`scheme:audio`) is not the
same as `pulseaudio` or `pipewire`. KDE's audio applet looks for
`org.pulseaudio.Server` on the session bus; it is not present.
2. **No WirePlumber**. Even if PipeWire existed, the policy daemon is missing.
3. **No per-user audio routing**. `audiod` is a system daemon. There is no
per-session audio.
4. **No USB audio integration**. `redbear-usbaudiod` is in `redbear-mini.toml:59`
but is the daemon for USB audio devices, not the audio session manager. It
exposes `/scheme/audiohw` for the USB audio class.
---
### 5. Network
#### 5.1 Network stack (kernel + netstack)
* Kernel: `local/sources/kernel/` (Red Bear fork). TCP/IP is in the kernel.
* Userspace: `local/sources/base/netstack/` (428 LoC across 5 files).
* Network driver spawner: `pcid-spawner` (rootfs) → drivers like `e1000d`,
`virtio-netd`, etc.
The netstack is small (198 LoC main.rs) but is the userspace component that
listens to `/scheme/network*` and bridges to smoltcp. It is a **scheme daemon,
not a regular service**.
#### 5.2 DHCP
* `dhcpd` lives in `local/sources/base/dhcpd/src/main.rs` (497 LoC).
* The rootfs init.d entry is `10_dhcpd.service` (line 5 of `init.d/10_dhcpd.service`):
`cmd = "dhcpd"`, type `oneshot_async`.
* `redbear-mini.toml:133-146` overrides to `cmd = "dhcpd"`, args `["-f"]`, type
`oneshot_async`. `redbear-full.toml` inherits.
* `redbear-netctl` (see 5.5) calls `dhcpd` to start a DHCP client.
**Status:** the daemon is built and runs on boot (rootfs). It exits when the
DHCP lease is acquired (or times out).
#### 5.3 DNS
There is no userspace DNS daemon in the chain. `relibc` (Redox C library) has a
`/etc/resolv.conf` parser and the `netstack` (smoltcp) supports DNS. The
`redbear-netctl:277` `write_netcfg("resolv/nameserver", dns)` writes a nameserver
line to the netstack's scheme.
**Stale code:** `resolv/nameserver` is a single value, not multi-valued.
glibc/POSIX allows multiple `nameserver` lines. Redox stores only one. This is
a known Redox limitation, not a Red Bear issue.
#### 5.4 Wi-Fi (wifictl + iwlwifi)
##### 5.4.1 `redbear-wifictl` (control plane)
**Location:** `local/recipes/system/redbear-wifictl/source/src/`
**LoC:** 2,786 (backend.rs 1509, main.rs 487, scheme.rs 743, dbus_nm.rs 47)
* Three backends: `StubBackend`, `NoDeviceBackend`, `IntelBackend`
(backend.rs:134-322).
* `build_backend` (main.rs:98-118) selects based on
`REDBEAR_WIFICTL_BACKEND`, presence of `/usr/lib/drivers/redbear-iwlwifi`,
and detected Intel interfaces.
* `select_backend_mode` (main.rs:81-96) returns `BackendMode::Stub` if no
driver is present, even on Redox runtime. **Stub is the default on
non-Intel hardware.**
##### 5.4.2 `StubBackend` — this is a stub
`backend.rs:140-245` — the `StubBackend` is a stub that returns canned
strings for every method:
* `scan()` returns `["demo-ssid", "demo-open"]` (line 186-188).
* `connect()` returns `WifiStatus::Connected` for open or wpa2-psk-with-key.
* `firmware_status()` returns `"firmware=stub"`.
* `transport_status()` returns `"transport=stub"`.
* `init_transport()` returns `"transport_init=stub"`.
This is **explicitly a stub** — a placeholder for hardware that has not yet
been wired. The README says "bounded Intel Wi-Fi driver path" is the only
real path. On non-Intel hardware, wifictl reports fake SSIDs.
**Per project policy**, stubs must be replaced. The fix is to either:
1. Remove `StubBackend` entirely and require the Intel driver to be present.
2. Port more drivers (e.g., `ath9k`, `mt76`).
3. Document `StubBackend` as a test-harness back-end and gate it on
`cfg(test)` or a CLI flag.
##### 5.4.3 `NoDeviceBackend` — also a stub but reasonable
`backend.rs:247-320` — returns `Err("no Intel Wi-Fi device detected")` for
every action. This is correct: it is the backend used when the driver is
present but no device is found.
##### 5.4.4 `IntelBackend` — real implementation
`backend.rs:322+` — this is the real implementation. It uses
`redox_driver_sys::pci::parse_device_info_from_config_space` and runs the
`/usr/lib/drivers/redbear-iwlwifi` binary for `--prepare`, `--init-transport`,
`--activate-nic`, `--scan`, `--connect`, `--disconnect`, `--retry`. Falls back
to `program_transport_bits` and `activate_nic_action` helpers if the driver
binary errors out.
**Stale code:**
* `scan` (line 519-528) — if the driver's `--scan` returns no results, the
result list is set to `["driver-scan-not-implemented"]`. This is a placeholder
that should propagate the "not implemented" error.
* `connect` (line 727-776) — uses a heuristic: if the driver returns
`status=associated`, treat as `Connected`, else `Associating`. The real
state machine has more states (e.g., 4-way handshake, EAPOL).
##### 5.4.5 `redbear-iwlwifi` driver
Built and registered via `/lib/drivers.d/60-wifi.toml`
(`redbear-full.toml:228-242`). The driver is invoked through
`redbear-wifictl`, not directly.
#### 5.5 `redbear-netctl` (profile manager + DHCP + DNS)
**Location:** `local/recipes/system/redbear-netctl/source/src/main.rs`
**LoC:** 1,059
**Implementation language:** Rust, no async.
##### 5.5.1 Real implementations
* Profile parser (`parse_profile` lines 582-665) — handles `ethernet`/`wifi`
connections, `dhcp`/`static`/`bounded` IP modes, `wpa2-psk` security.
* `apply_wifi_profile` (lines 401-447) — writes SSID/security/key to
`/scheme/wifictl/ifaces/<iface>/...` and triggers `--prepare`,
`--init-transport`, `--activate-nic`, `--connect`.
* `apply_profile` for `ethernet` + `dhcp` (lines 247-289) — spawns `dhcpd`
and polls for an address.
* `start_profile`, `stop_profile`, `enable_profile`, `disable_profile`
(lines 195-235).
* `read_wifictl_value`, `write_wifictl` (lines 449-466) — the scheme I/O
primitives.
* 12 unit tests.
##### 5.5.2 Stubs / half-impls
* `--boot` mode (line 107-112) — reads the active profile name and starts it.
If no active profile, returns `Ok(())` (a no-op). On a real install, we
would want this to fall back to scanning and auto-connecting.
* `apply_profile` for `ethernet` (line 249) — does nothing. Real impl would
bring up the interface (e.g., set the link up via `ifconfig` or the netstack
scheme).
* `static` IP mode (lines 268-279) — writes to `netcfg` scheme directly.
No validation of the address/gateway format. No DNS search list.
* DNS writes `resolv/nameserver` (line 277) — single value, no search domain,
no options (timeout, attempts).
* No NTP integration. NTP is a hardcoded assumption that the system clock is
already set (which is the case in QEMU, but not on bare metal).
* The `dhcp_wait_timeout` is 1 second (line 552), which is too short for
real DHCP. The default `REDBEAR_DHCPD_WAIT_MS` is 1000ms.
#### 5.6 `redbear-info`
**Location:** `local/recipes/system/redbear-info/source/src/main.rs`
**LoC:** 4,704 (one file) + 165 (tui.rs)
**Built:** yes, on `redbear-mini` and `redbear-full` (cargo build with `tui` feature).
This is a TUI/CLI tool for system introspection. It is **not a daemon** — it is
a per-invocation command. The TUI is feature-gated behind `tui` and is built
into the binary.
The TUI is implemented with `ratatui 0.30 + termion` (per project README) and
includes 5 tabs (System, Hardware, Network, Integrations, Health).
**Stubs in `redbear-info`:** None that I could find. The tool is a real
implementation. (The 4,704 LoC single file is dense but does not have
`todo!()` or `unimplemented!()`.)
#### 5.7 Cross-cutting network issues
1. **No NTP.** Time is set at boot to the bootloader timestamp. A real NTP
client is missing.
2. **No Wi-Fi auto-connect on boot** beyond the `--boot` profile. On bare
metal, the user must run `redbear-netctl --boot` manually.
3. **No DNS search domain configuration.**
4. **No IPv6 support.** The netstack uses smoltcp; smoltcp supports IPv6 but
the Redox netstack daemon may not expose it.
5. **No firewall.** No iptables/nftables equivalent.
---
### 6. Initfs vs Rootfs Handoff (CRITICAL)
#### 6.1 Initfs daemons
`local/sources/base/init.initfs.d/` (full listing):
| Service | Purpose | Notes |
|---|---|---|
| `00_clock.service` | Time scheme | Required for relibc |
| `00_logd.service` | Logging | Writes to ramfs |
| `00_nulld.service` | /dev/null scheme | |
| `00_randd.service` | Random numbers | |
| `00_zerod.service` | Zero-byte scheme | |
| `00_runtime.target` | Group for runtime essentials | |
| `10_inputd.service` | PS/2 + USB input | Feeds evdev |
| `10_lived.service` | Live disk driver | |
| `20_fbbootlogd.service` | Boot log to framebuffer | |
| `20_fbcond.service` | Console on framebuffer | |
| `20_graphics.target` | Group for graphics | |
| `20_vesad.service` | Linear framebuffer handoff | **vesad** for early boot only |
| `30_acpid.service` | ACPI daemon | |
| `40_bcm2835-sdhcid.service` | Raspberry Pi SD host | Not used on x86_64 |
| `40_drivers.target` | Group for drivers | |
| `40_hwd.service` | Hardware detection | |
| `40_pcid-spawner-initfs.service` | PCI driver spawner (initfs) | Uses `--initfs` flag |
| `40_ps2d.service` | PS/2 controller | |
| `50_rootfs.service` | Mounts the rootfs redoxfs | |
| `90_initfs.target` | Group for initfs end | |
| `ramfs@logging.service` | Template: ramfs instance | |
The initfs has **no D-Bus, no sessiond, no authd, no greeter, no SDDM, no
network userland**. The initfs runs:
* `vesad` to provide a framebuffer
* `pcid-spawner --initfs` to spawn PCI drivers
* `acpid` to read ACPI tables
* `hwd` to detect hardware
* `lived` to mount the live ISO (if applicable)
* `inputd`/`ps2d` to get early input
* `fbcond`/`fbbootlogd` for the boot framebuffer console
The handoff to rootfs is at `50_rootfs.service`: `cmd = "redoxfs"`, args
`["--uuid", "$REDOXFS_UUID", "file"]`, type `oneshot`.
#### 6.2 Rootfs daemons
`local/sources/base/init.d/` (rootfs, full listing):
| Service | Purpose |
|---|---|
| `00_base.target` | Group for basic services |
| `00_ipcd.service` | Inter-process communication |
| `00_pcid-spawner.service` | PCI driver spawner (rootfs) |
| `00_ptyd.service` | Pseudo-terminal |
| `00_sudo.service` | Privilege escalation |
| `00_tmp` | /tmp ramfs |
| `10_dhcpd.service` | DHCP client |
| `10_net.target` | Group for networking |
| `10_smolnetd.service` | (renamed to netstack; FIXME in the file) |
| `20_audiod.service` | Audio multiplexer |
The rootfs has **6 + 4 group services**. This is the **minimum** base; the
redbear-* and other packages add many more via `[[files]]` entries in the
configs.
#### 6.3 Where do D-Bus / session / audio / network start?
In the **rootfs**, after the handoff. The ordering is enforced by
`requires_weak` chains in the service files.
| Service | File | Required by |
|---|---|---|
| `00_base.target` (rootfs) | `local/sources/base/init.d/00_base.target` | All others |
| `00_ipcd.service` | `local/sources/base/init.d/00_ipcd.service` | `00_base.target` |
| `00_pcid-spawner.service` | `local/sources/base/init.d/00_pcid-spawner.service` | `00_base.target` |
| `00_ptyd.service` | `local/sources/base/init.d/00_ptyd.service` | `00_base.target` |
| `00_sudo.service` | `local/sources/base/init.d/00_sudo.service` | (rootfs default) |
| `10_dhcpd.service` | `local/sources/base/init.d/10_dhcpd.service` | `10_smolnetd.service` |
| `10_smolnetd.service` | `local/sources/base/init.d/10_smolnetd.service` | `00_pcid-spawner.service` |
| `20_audiod.service` | `local/sources/base/init.d/20_audiod.service` | `00_base.target` |
| `12_dbus.service` | `redbear-mini.toml:373-385` (overrides nothing in base) | `12_boot-late.target` |
| `13_redbear-sessiond.service` | `redbear-mini.toml:400-411` | `12_dbus.service` |
| `13_seatd.service` | `redbear-mini.toml:387-396` (no-op) | (no requires) |
| `13_seatd.service` | `redbear-full.toml:329-343` (real) | `12_dbus.service`, `13_redbear-sessiond.service` |
| `11_redbear-authd.service` | `redbear-full.toml:433-446` | `12_dbus.service` |
| `12_sddm.service` | `redbear-full.toml:448-467` | `00_driver-manager`, `10_redox-drm`, `10_evdevd`, `12_dbus`, `13_redbear-sessiond`, `13_seatd`, `11_redbear-authd` |
| `11_wifictl.service` | `redbear-mini.toml:357-370` | `12_boot-late.target`, `00_driver-manager.service` |
| `13_redbear-keymapd.service` | `redbear-full.toml:349-361` | `10_evdevd.service` |
| `13_redbear-ime.service` | `redbear-full.toml:363-375` | `10_evdevd.service` |
| `13_redbear-accessibility.service` | `redbear-full.toml:377-389` | `10_evdevd.service` |
| `14_redbear-upower.service` | `redbear-full.toml:391-403` | `12_dbus.service` |
| `14_redbear-udisks.service` | `redbear-full.toml:405-417` | `12_dbus.service` |
| `14_redbear-polkit.service` | `redbear-full.toml:419-431` | `12_dbus.service` |
| `00_firmware-loader.service` | `redbear-full.toml:244-256` | `05_boot-essential.target` |
| `05_boot-essential.target` | `redbear-full.toml:258-266` | `04_drivers.target` |
| `13_iommu.service` | `redbear-full.toml:268-281` | `05_boot-essential.target`, `00_acpid.service` |
| `10_redox-drm.service` | `redbear-full.toml:283-297` | `05_boot-essential.target`, `00_driver-manager.service` |
#### 6.4 Initfs vs rootfs overlap
The `vesad` daemon runs in initfs only (`init.initfs.d/20_vesad.service`).
**The rootfs does not start vesad again.** This is correct per the
"NO VESA POLICY" in the project AGENTS.md.
`acpid` runs in initfs (`init.initfs.d/30_acpid.service`) AND is referenced
by `redbear-full.toml:13_iommu.service` (which `requires_weak =
["05_boot-essential.target", "00_acpid.service"]`). The `00_acpid.service`
is the initfs one. The `requires_weak` says "wait until initfs acpid is up."
This is correct but couples the rootfs services to the initfs service names.
**Stale code risk:** if `00_acpid.service` is renamed in initfs, the rootfs
`requires_weak` will silently fail.
`pcid-spawner` runs in initfs (`40_pcid-spawner-initfs.service`) with
`args = ["--initfs"]`. The rootfs runs `00_pcid-spawner.service` without the
flag. This is a clean handoff: the initfs spawns the early drivers (vesad,
ps2d, lived), then the rootfs takes over for the rest.
`dhcpd` runs only in rootfs (no initfs dhcpd). This is correct.
`audiod` runs only in rootfs. There is no initfs audio. This is correct.
#### 6.5 Handoff issues
1. **No explicit handoff notification.** The initfs finishes its work
(vesad, pcid-spawner --initfs, hwd, acpid), then `50_rootfs.service` runs
`redoxfs` to mount the rootfs. There is no synchronization between the
initfs pcid-spawner finishing and the rootfs pcid-spawner starting —
`requires_weak` is **not** used here. The rootfs pcid-spawner may try
to spawn drivers that the initfs pcid-spawner is still spawning.
2. **`driver-manager` is referenced in `redbear-full.toml:454` (sddm
requires `00_driver-manager.service`) but the service file is provided by
`redbear-device-services.toml`** which is included by `redbear-mini.toml:12`.
3. **`10_evdevd.service` is referenced by `12_sddm.service` (line 456) but
the file is in `local/recipes/system/evdevd/source/init.d/10_evdevd.service`**
and the `redbear-mini.toml:343-355` already installs it. So it is present.
4. **`10_redox-drm.service` has an unusual one-liner:**
`redbear-full.toml:294-296`:
```
cmd = "/usr/bin/sh"
args = ["-c", "if ! head -c 1 /scheme/drm/card0 >/dev/null 2>&1; then exec /usr/bin/redox-drm; fi; echo 'scheme:drm already registered, skipping'"]
```
This is a **race-condition workaround**. The
`redbear-greeter-compositor` script (line 39-46) has an explicit comment:
"On Redox, stat and test -e are unreliable for scheme paths" and uses
`( exec 3<"/scheme/drm/card0" )` instead. The init service uses
`head -c 1 /scheme/drm/card0` which **will block** waiting for a request
response on the DRM scheme (per the comment in
`redbear-greeter-compositor:40-41`). This is a known-bad pattern; the
correct pattern is the `exec 3<...` one. **Stale code in `redbear-full.toml`.**
#### 6.6 Stale code (initfs / rootfs handoff)
* `local/sources/base/init.initfs.d/10_smolnetd.service:1` — `# FIXME rename to
10_netstack.service`. The file is still named 10_smolnetd.
* `redbear-full.toml:295` — `head -c 1 /scheme/drm/card0` will block; should
use the open-as-probe pattern.
---
## Cross-Cutting Issues
### Service Activation Order (for KDE to work)
Required rootfs order (current vs needed):
| # | Service | Current status | Built? | Started? | Comments |
|---|---|---|---|---|---|
| 1 | `00_base.target` | ✅ in init.d | n/a | yes | Foundation |
| 2 | `00_logd` (initfs) | ✅ in init.initfs.d | yes | yes (initfs) | Survives handoff |
| 3 | `00_ipcd` | ✅ in init.d | yes | yes | |
| 4 | `00_pcid-spawner` (rootfs) | ✅ in init.d | yes | yes | |
| 5 | `00_driver-manager` | ✅ in `redbear-device-services.toml` | yes | yes | |
| 6 | `00_firmware-loader` | ✅ `redbear-full.toml:244-256` | yes | yes | |
| 7 | `10_redox-drm` | ✅ `redbear-full.toml:283-297` | yes | yes | |
| 8 | `10_evdevd` | ✅ in `redbear-mini.toml` (inherits) | yes | yes | |
| 9 | `10_smolnetd` (renamed to `10_netstack`) | ✅ in `redbear-mini.toml:119-131` | yes | yes | |
| 10 | `10_dhcpd` | ✅ in `redbear-mini.toml:133-146` | yes | yes | |
| 11 | `12_dbus` | ✅ `redbear-full.toml:299-313` | yes | yes | |
| 12 | `13_redbear-sessiond` | ✅ `redbear-full.toml:315-327` | yes | yes | |
| 13 | `13_seatd` | ✅ `redbear-full.toml:329-343` | yes | yes | But not used (see §3) |
| 14 | `11_redbear-authd` | ✅ `redbear-full.toml:433-446` | yes | yes | |
| 15 | `13_redbear-keymapd` | ✅ `redbear-full.toml:349-361` | yes | yes | |
| 16 | `13_redbear-ime` | ✅ `redbear-full.toml:363-375` | yes | yes | |
| 17 | `13_redbear-accessibility` | ✅ `redbear-full.toml:377-389` | yes | yes | |
| 18 | `14_redbear-upower` | ✅ `redbear-full.toml:391-403` | yes | yes | |
| 19 | `14_redbear-udisks` | ✅ `redbear-full.toml:405-417` | yes | yes | |
| 20 | `14_redbear-polkit` | ✅ `redbear-full.toml:419-431` | yes | yes | But see §1.9 polkit caller-UID defect |
| 21 | `12_sddm` | ✅ `redbear-full.toml:448-467` | yes | yes | PAM not wired |
| 22 | `pipewire` (NEW) | ❌ not present | NO | NO | **Required for audio** |
| 23 | `wireplumber` (NEW) | ❌ not present | NO | NO | **Required for audio** |
| 24 | `redbear-notifications` (session) | ❌ not started | yes | NO | **Required for KDE notifications** |
| 25 | `redbear-statusnotifierwatcher` | ❌ not started | yes | NO | **Required for KDE tray** |
| 26 | `redbear-firmware` | ✅ `redbear-full.toml:52-53` | yes | yes | |
### D-Bus activation
For KDE to start, D-Bus must activate:
* `org.kde.KWin` — missing
* `org.kde.plasma` — missing
* `org.kde.kded6` — present (kded6-offscreen workaround)
* `org.kde.kglobalacceld` — present (file exists)
* `org.freedesktop.Notifications` — present (file exists)
* `org.freedesktop.StatusNotifierWatcher` — missing (no service file)
Are these `.service` files in `/usr/share/dbus-1/system-services/` or
`~/.local/share/dbus-1/services/`? **None of the missing ones are in either
location.**
### Polkit / Authentication
* Polkit daemon: `redbear-polkit` (241 LoC). Service file: yes. Started: yes.
* Policy file: `/etc/polkit-1/policy.toml` (12 lines, 8 actions, all uid-0
authorized). Real polkit expects `*.policy` XML files with full action
descriptions and a JavaScript .rules authority. **The Red Bear polkit is a
flat-file UID lookup.** KDE's `polkit-kde-agent-1` will query polkit and get
a correct response for root-uid; for user-uid 1000, the policy says
`org.freedesktop.login1.power-off = 0, 1000` so the user can shut down.
This is **functional** for the common actions.
* PAM: not present. SDDM expects libpam. **PAM is the critical missing
piece for SDDM to authenticate a user.**
### PipeWire / WirePlumber
* PipeWire: not present. **Required for KDE audio.**
* WirePlumber: not present. **Required for KDE audio policy.**
### Other missing wirings (cross-cutting)
1. **No `redbear-notifications.service`** in `redbear-full.toml` →
`local/recipes/system/redbear-notifications/source/init.d/` is empty.
The daemon is built but not started.
2. **No `redbear-statusnotifierwatcher.service`** anywhere.
3. **No `/etc/machine-id`** generated by any init step. `dbus-daemon` requires
`/etc/machine-id` to start. If it's not present, the daemon may fail to
start. (This is provided by systemd in mainstream distros; on Redox, it
should be generated at first boot.)
4. **No `/var/lib/dbus/machine-id`** either.
5. **No NetworkManager or netctl-ifcfg integration with D-Bus.** The
`redbear-wifictl/source/src/dbus_nm.rs` (47 LoC) only defines
`register_nm_interface` which is gated on `cfg(target_os = "redox")` and
is a stub.
---
## Implementation Roadmap
### Phase 1: Unblock D-Bus + session activation (12 weeks)
1. Add a `redbear-notifications.service` to `redbear-full.toml` that starts
on the **session bus**. The session bus itself must be started by
`redbear-session-launch` (already partially done via `dbus-run-session`).
Remove the duplicate `dbus-launch` in `redbear-kde-session:152`.
2. Add a `redbear-statusnotifierwatcher.service` to `redbear-full.toml`
(session bus).
3. Generate `/etc/machine-id` at first boot (or at install time).
4. Add `org.kde.kglobalacceld.service`, `org.kde.KWin.service`,
`org.kde.plasmashell.service` to `redbear-dbus-services`.
5. Fix the `org.freedesktop.UPower.service` `SystemdService=redbear-polkit.service`
copy-paste bug.
6. Add `dbus-update-activation-environment` to `redbear-session-launch`
(currently only in `redbear-kde-session`).
Estimated LoC: ~300.
### Phase 2: Wire Session Management (23 weeks)
1. Implement `redbear-sessiond::kill_session`, `kill_user`, `power_off`,
`reboot`, `suspend` (real shutdown, real kill, no more "no-op" logs).
2. Implement `redbear-sessiond::IdleSinceHint`, `IdleSinceHintMonotonic`
with real timestamps.
3. Implement `redbear-sessiond::HandleLidSwitch` with real ACPI events
from `acpid`.
4. Implement `redbear-polkit::CheckAuthorization` with caller-UID extraction
(use zbus connection metadata).
5. Implement `redbear-sessiond::Can*` methods to return real values
(check binary existence, not hardcoded "na").
6. Fix `device_map::dev_major` for Redox-native `rdev()`.
7. Fix `redbear-session-launch::apply_groups` to actually use the
supplementary-groups syscalls.
8. Fix `redbear-authd::launch_session` to support more than just
`kde-wayland`.
9. Add a `redbear-passwd` service for password management (currently
only a library, no binary).
Estimated LoC: ~600.
### Phase 3: Wire Audio (46 weeks)
1. Port PipeWire to Redox (or accept that audio in KDE is broken).
2. Port WirePlumber to Redox.
3. Create `local/recipes/system/pipewire/recipe.toml` and
`local/recipes/system/wireplumber/recipe.toml`.
4. Add a `pipewire.service` to `redbear-full.toml` (session bus, started
by `redbear-kde-session`).
5. Add a `wireplumber.service` to `redbear-full.toml` (session bus).
6. Set `PIPEWIRE_REMOTE` and `PIPEWIRE_RUNTIME_DIR` in
`redbear-session-launch`.
7. Update `redbear-kde-session` to start pipewire and wireplumber.
Estimated LoC: ~2,000 (mostly upstream porting).
### Phase 4: Wire Network enhancements (12 weeks)
1. Remove `StubBackend` from `redbear-wifictl` (or gate it on `cfg(test)`).
2. Port NTP daemon (`chrony` or `ntpd-rs`).
3. Add NTP service to `redbear-full.toml`.
4. Multi-DNS support in `redbear-netctl`.
5. Wi-Fi auto-connect on boot.
Estimated LoC: ~800.
### Phase 5: PAM and SDDM integration (23 weeks)
1. Port a minimal `libpam` to Redox (or use a stub that calls
`redbear-authd` over its Unix socket).
2. Add `/etc/pam.d/sddm` config.
3. Verify SDDM authenticates through `redbear-authd`.
4. Verify the session bus is started by SDDM and propagated to the user
session.
Estimated LoC: ~500.
### Phase 6: Remove dead / stale code (1 week)
1. Remove the `kded6-offscreen` shell wrapper; integrate the QPA override
into the `kded6.service` file directly (already done; the wrapper is
redundant).
2. Remove the duplicate `dbus-launch` call in `redbear-kde-session`.
3. Remove the `redbear-greeter-compositor` / `redbear-kde-session`
shell wrappers and replace with a Rust binary
(`redbear-session-orchestrator`).
4. Remove the `StubBackend` from `redbear-wifictl`.
5. Replace `redbear-full.toml:294-296` `head -c 1` DRM probe with
`exec 3<...` pattern.
6. Remove `redbear-firmware` recipe's `linux-firmware` clone (use
`fetch-firmware.sh` per project AGENTS.md).
Estimated LoC: ~300 net (remove old, add replacement).
---
## Testing Strategy
### Unit tests (already present)
* `redbear-sessiond`: ~30 unit tests in `mod tests` blocks across
`manager.rs`, `session.rs`, `seat.rs`, `control.rs`, `device_map.rs`.
* `redbear-authd`: 12 unit tests in `main.rs:515-718`.
* `redbear-session-launch`: 9 unit tests in `main.rs:404-627`.
* `redbear-greeter`: 10 unit tests in `main.rs:503-655`.
* `redbear-netctl`: 12 unit tests in `main.rs:667-1032`.
* `redbear-wifictl`: 6 unit tests in `main.rs:130-196`.
* `redbear-info`: not yet read in full but the test count is expected to
be > 30 given the 4,704 LoC.
### Integration tests (missing)
* No integration test that boots `redbear-full` and checks
`dbus-send --system --dest=org.freedesktop.login1 /org/freedesktop/login1
org.freedesktop.login1.Manager.ListSeats`.
* No integration test that starts `redbear-authd` and posts an
`Authenticate` request.
* No integration test that runs `redbear-greeterd` end-to-end.
### Validation commands
* `./local/scripts/test-greeter-qemu.sh --check` — exists per
`local/AGENTS.md` line 84.
* `./local/scripts/test-phase5-network-qemu.sh --check` — exists.
* `./local/scripts/test-phase6-kde-qemu.sh --check` — exists.
* `redbear-greeter-check`, `redbear-greeter-check --invalid root wrong` —
expected to be installed in the image.
---
## Risk Assessment
### Impact of shipping as-is
If we ship `redbear-full` today:
* The system will boot.
* The user will see a framebuffer console (initfs vesad).
* pcid-spawner will run, drivers will load.
* The D-Bus system bus will start.
* `redbear-sessiond`, `seatd`, `redbear-authd` will register.
* `redbear-upower`, `redbear-udisks`, `redbear-polkit` will register.
* SDDM will attempt to start. It will try to load `libpam`. **It will fail.**
* If SDDM fails, the user will be dropped to a text console on VT 2
(per the `30_console.service` in `redbear-mini.toml`).
* Network (`dhcpd`, `netstack`, `wifictl`) will be running.
* The user can run `redbear-netctl --boot` to connect.
* The user can run `redbear-info` to see system status.
**The desktop will not work.** This is the critical gap.
### Minimum to make SDDM display a login screen
1. A Red Bear PAM module (or relibc libpam) that:
- Reads `/etc/pam.d/sddm` config.
- For `auth` calls `redbear-authd` over Unix socket.
- For `session` opens a `redbear-session-launch` process.
2. SDDM greeter binary (`sddm-greeter`) — must be built and installed.
3. SDDM theme (`mayagrid` is referenced in `redbear-full.toml:574-577`).
4. `redbear-greeter-compositor` shell wrapper replaced with a real
Wayland-capable compositor or with SDDM's own compositor helper.
### Minimum to make KDE Plasma start after login
1. All of the above, plus:
2. PipeWire + WirePlumber.
3. The session-bus must be started, with `DBUS_SESSION_BUS_ADDRESS`
propagated to `kwin_wayland`, `plasmashell`, etc.
4. The `redbear-kde-session` shell wrapper must be called by SDDM after
auth, not by `redbear-greeter` (because we are not using redbear-greeter).
5. The Qt6 Wayland `null+8` crash must be fixed in the Qt6 port.
---
## Appendix A: Grep Results
### A.1 `todo!()` and `unimplemented!()` in `local/recipes/system/`
```
$ grep -rn 'todo!()\|unimplemented!()' local/recipes/system/ 2>/dev/null | grep -v /target/
(no matches)
```
**Zero `todo!()` or `unimplemented!()` in the chain.** This is good.
### A.2 `#TODO` in `local/recipes/system/` recipe.toml
```
$ grep -rn '#TODO' local/recipes/system/ 2>/dev/null
local/recipes/system/dbus/recipe.toml:1:#TODO: validate runtime (dbus-daemon --system + dbus-launch for session bus)
local/recipes/system/redbear-polkit/recipe.toml:1:#TODO: redbear-polkit — org.freedesktop.PolicyKit1 daemon. UID-based authorization via /etc/polkit-1/policy.toml. Root always authorized.
local/recipes/system/redbear-upower/recipe.toml:1:#TODO: redbear-upower — minimal org.freedesktop.UPower daemon. Enumerates power state from scheme:acpi.
local/recipes/system/redbear-udisks/recipe.toml:1:#TODO: redbear-udisks — minimal org.freedesktop.UDisks2 daemon. Enumerates block devices from scheme: filesystem.
local/recipes/system/redbear-notifications/recipe.toml:1:#TODO: redbear-notifications — minimal org.freedesktop.Notifications daemon. Logs notifications to stderr until a display server integration exists.
```
5 recipes have a `#TODO` first-line. All 5 are documentation notes, not blocking
issues, but they signal that the implementations are intentionally minimal.
### A.3 Stubs in `local/recipes/system/` source
* `redbear-wifictl/src/backend.rs:140-245` — `StubBackend` is a stub.
* `redbear-wifictl/src/backend.rs:247-320` — `NoDeviceBackend` is a no-op
error-returning backend (not a stub, but a deliberate "no device" state).
* `redbear-sessiond/src/manager.rs:143-169` — 7 `can_*` methods return `"na"`.
* `redbear-sessiond/src/manager.rs:171-187` — `power_off`, `reboot`,
`suspend` log only.
* `redbear-sessiond/src/manager.rs:322-342` — `kill_session`, `kill_user`
log "no-op".
* `redbear-sessiond/src/session.rs:206-212` — `kill` logs "no-op".
* `redbear-polkit/src/main.rs:144` — `CheckAuthorization` always queries
with uid 0 (security defect).
* `redbear-notifications/src/main.rs` — `Notify` only `eprintln!`s, does
not display.
* `redbear-statusnotifierwatcher/src/main.rs` — only tracks items/hosts in
memory, does not bridge to KDE's tray (KDE does this on its own).
* `redbear-udisks/src/interfaces.rs:108-115` — `SupportedFilesystems` and
`SupportedEncryptionTypes` return empty vec.
* `redbear-udisks/src/interfaces.rs:137-138` — `Symlinks` returns empty vec.
### A.4 Service files in `local/recipes/system/*/source/init.d/`
```
$ find local/recipes/system -name '*.service' -path '*/init.d/*'
local/recipes/system/evdevd/source/init.d/10_evdevd.service
local/recipes/system/redbear-keymapd/source/init.d/13_redbear-keymapd.service
local/recipes/system/redbear-polkit/source/init.d/20_polkit.service
```
3 recipes ship init.d service files. The rest rely on `redbear-mini.toml` or
`redbear-full.toml` to install the service file via `[[files]]`.
### A.5 Recipes with no `recipe.toml`
*None.* All 47 recipes under `local/recipes/system/` have a `recipe.toml`.
### A.6 Recipes whose binary is built but not started in any config
* `local/recipes/system/redbear-notifications` — built, but no service file in
any config; **never started**.
* `local/recipes/system/redbear-statusnotifierwatcher` — built, but no
service file anywhere; **never started**.
* `local/recipes/system/redbear-passwd` — a library (lib.rs), not a binary.
The recipe declares `[lib]` only, no `[[bin]]`. So this is a
"library" recipe with no binary, no service.
* `local/recipes/system/redbear-meta` — meta package; depends on other
recipes. The `script` in `recipe.toml` just writes a README to the
sysroot. There is no binary to start.
### A.7 D-Bus service / policy files in `redbear-dbus-services`
```
session.d/
org.redbear.session.conf (16 lines, wildcard allow org.kde.*)
session-services/
org.kde.kded6.service (5 lines, forces offscreen)
org.kde.kglobalaccel.service (3 lines)
org.freedesktop.Notifications.service (3 lines)
system.d/
org.freedesktop.login1.conf (23 lines)
org.freedesktop.PolicyKit1.conf (11 lines)
org.freedesktop.UDisks2.conf (11 lines)
org.freedesktop.UPower.conf (11 lines)
system-services/
org.freedesktop.login1.service (4 lines, /usr/bin/redbear-sessiond)
org.freedesktop.PolicyKit1.service (5 lines, SystemdService=redbear-polkit.service)
org.freedesktop.UPower.service (5 lines, SystemdService=redbear-polkit.service) [STALE]
org.freedesktop.UDisks2.service (5 lines)
kded6-offscreen (3 lines, shell wrapper)
```
Total: 11 files, 102 LoC.
### A.8 Init.d service file ownership
* `local/sources/base/init.initfs.d/` — 21 files, all owned by Redox.
* `local/sources/base/init.d/` — 10 files (9 service + 1 target), all
owned by Redox.
* `local/recipes/system/evdevd/source/init.d/10_evdevd.service` — 1 file,
owned by Red Bear.
* `local/recipes/system/redbear-keymapd/source/init.d/13_redbear-keymapd.service` —
1 file, owned by Red Bear.
* `local/recipes/system/redbear-polkit/source/init.d/20_polkit.service` —
1 file, owned by Red Bear.
**3 Red Bear init.d service files; the rest are inlined as `[[files]]` in
`redbear-mini.toml` or `redbear-full.toml`.** This is a code organization
choice — the inlined approach is more visible in the config but less
reusable.
---
## Appendix B: File-by-file Line Counts
### B.1 Session Management
| File | LoC | Notes |
|---|---|---|
| `local/recipes/system/redbear-sessiond/source/src/main.rs` | 188 | Daemon entry point |
| `local/recipes/system/redbear-sessiond/source/src/manager.rs` | 642 | LoginManager interface |
| `local/recipes/system/redbear-sessiond/source/src/session.rs` | 450 | LoginSession interface |
| `local/recipes/system/redbear-sessiond/source/src/seat.rs` | 147 | LoginSeat interface |
| `local/recipes/system/redbear-sessiond/source/src/control.rs` | 221 | Control socket (authd → sessiond handoff) |
| `local/recipes/system/redbear-sessiond/source/src/device_map.rs` | 267 | DRM/input device map |
| `local/recipes/system/redbear-sessiond/source/src/runtime_state.rs` | 54 | Shared state |
| `local/recipes/system/redbear-sessiond/source/src/acpi_watcher.rs` | 48 | Stub signature; impl in patch |
| **sessiond total** | **2,017** | |
| `local/recipes/system/redbear-authd/source/src/main.rs` | 719 | Full Unix-socket protocol |
| `local/recipes/system/redbear-session-launch/source/src/main.rs` | 628 | setuid session launcher |
| `local/recipes/system/redbear-greeter/source/src/main.rs` | 656 | Greeter daemon |
| `local/recipes/system/redbear-greeter/source/redbear-greeter-compositor` | 4,310 bytes | Bash wrapper |
| `local/recipes/system/redbear-greeter/source/redbear-kde-session` | 8,936 bytes | Bash wrapper |
| **Session management total Rust LoC** | **4,020** | **+13,246 bytes of Bash** |
### B.2 D-Bus services
| File | LoC | Notes |
|---|---|---|
| `local/recipes/system/dbus/recipe.toml` | 25 | With `#TODO` |
| `local/recipes/system/dbus/source/dbus/*.c` (unpacked) | ~340,000 | Upstream C, not in our audit scope |
| `local/recipes/system/dbus/redox.patch` | 24 | epoll + socketpair |
| `local/recipes/system/redbear-dbus-services/source/**/*` | 102 | Service + policy files |
| `local/recipes/system/redbear-dbus-services/recipe.toml` | 16 | Custom template |
| `local/recipes/system/redbear-polkit/source/src/main.rs` | 241 | PolicyKit1 service |
| `local/recipes/system/redbear-upower/source/src/main.rs` | 622 | UPower service |
| `local/recipes/system/redbear-udisks/source/src/main.rs` | 174 | UDisks2 service |
| `local/recipes/system/redbear-udisks/source/src/interfaces.rs` | 218 | D-Bus interface impls |
| `local/recipes/system/redbear-udisks/source/src/inventory.rs` | 281 | Disk inventory |
| `local/recipes/system/redbear-notifications/source/src/main.rs` | 198 | Notification service |
| `local/recipes/system/redbear-statusnotifierwatcher/source/src/main.rs` | 168 | Status notifier watcher |
| **D-Bus services total Rust LoC (Red Bear)** | **1,902** | |
### B.3 Audio
| File | LoC | Notes |
|---|---|---|
| `local/sources/base/audiod/src/main.rs` | 100 | audiod daemon |
| `local/sources/base/audiod/src/scheme.rs` | 177 | Audio scheme |
| `local/recipes/system/redbear-usbaudiod/source/src/main.rs` | (not surveyed) | USB audio device driver |
| **Audio total LoC (Red Bear)** | **277** | PipeWire/WirePlumber absent |
### B.4 Network
| File | LoC | Notes |
|---|---|---|
| `local/sources/base/netstack/src/main.rs` | 198 | netstack daemon |
| `local/sources/base/netstack/src/buffer_pool.rs` | 96 | smoltcp buffer pool |
| `local/sources/base/netstack/src/error.rs` | 55 | |
| `local/sources/base/netstack/src/logger.rs` | 17 | |
| `local/sources/base/netstack/src/port_set.rs` | 62 | |
| `local/sources/base/dhcpd/src/main.rs` | 497 | DHCP client |
| `local/sources/base/dhcpd/src/dhcp/mod.rs` | (not surveyed) | DHCP protocol |
| `local/recipes/system/redbear-netctl/source/src/main.rs` | 1,059 | Profile manager |
| `local/recipes/system/redbear-wifictl/source/src/main.rs` | 487 | Wi-Fi control |
| `local/recipes/system/redbear-wifictl/source/src/backend.rs` | 1,509 | Wi-Fi backends |
| `local/recipes/system/redbear-wifictl/source/src/dbus_nm.rs` | 47 | NetworkManager D-Bus stub |
| `local/recipes/system/redbear-wifictl/source/src/scheme.rs` | 743 | Wi-Fi scheme |
| `local/recipes/system/redbear-info/source/src/main.rs` | 4,704 | System info CLI |
| `local/recipes/system/redbear-info/source/src/tui.rs` | 165 | TUI |
| **Network + info total Rust LoC** | **9,638** | |
### B.5 seatd
| File | LoC | Notes |
|---|---|---|
| `local/recipes/system/seatd/source/seatd/server.c` | 171 | |
| `local/recipes/system/seatd/source/seatd/client.c` | 528 | |
| `local/recipes/system/seatd/source/seatd/poller.c` | 327 | |
| `local/recipes/system/seatd/source/seatd/seat.c` | 757 | |
| `local/recipes/system/seatd/source/seatd/seatd.c` | 220 | |
| `local/recipes/system/seatd/source/common/*.c` | (not surveyed) | Linux-only backends |
| `local/recipes/system/seatd/source/libseat/*.c` | (not surveyed) | libseat client lib |
| **seatd total LoC** | **2,003+** | Upstream C |
### B.6 Initfs vs rootfs service files
* `local/sources/base/init.initfs.d/` — 21 files
* `local/sources/base/init.d/` — 10 files
* `redbear-mini.toml` — 23 `[[files]]` entries for service files
* `redbear-full.toml` — 25 `[[files]]` entries for service files
### B.7 Grand total
| Subsystem | LoC |
|---|---|
| Session management (Rust) | 4,020 |
| Session management (Bash) | 13,246 bytes |
| D-Bus services (Rust, Red Bear) | 1,902 |
| D-Bus services (upstream C) | ~340,000 (out of scope) |
| Audio (Rust, Red Bear) | 277 |
| Network (Rust, Red Bear) | 9,638 |
| seatd (upstream C) | 2,003+ |
| **Total Red Bear Rust LoC in the chain** | **~15,840** |
---
## Closing Notes
The Red Bear OS desktop-services chain is **substantially implemented** at the
D-Bus / sessiond / authd level. The Rust code is well-tested, well-structured,
and the D-Bus interfaces closely follow the freedesktop.org specifications.
The critical gaps are:
1. **No PipeWire / WirePlumber** (audio is broken in KDE).
2. **No PAM** (SDDM cannot authenticate).
3. **No session-bus user services** (notifications, status notifier, KDE
services are not auto-started).
4. **`StubBackend` in `redbear-wifictl`** is a real stub.
5. **KDE session wrapper has known QPA / Wayland crash** (`null+8`).
6. **`polkit` caller-UID is hardcoded to 0** (security defect, but
currently masked by the `org.kde.*` wildcard policy).
**Estimated total LoC to fix:** ~4,500 LoC across 6 phases.
**Estimated total time:** 812 weeks with 12 developers.
The chain is buildable and the static review is solid. The dynamic review
(runtime in QEMU, then bare metal) is the next critical step. Many of the
"real" implementations may surface runtime defects that this static review
cannot catch — particularly around the seatd ↔ KWin ↔ /scheme/drm/card0
integration, the Qt6 Wayland `null+8` crash, and the PAM/Sddm/authd
connection.