The 5 .service files in redbear-dbus-services/files/session-services/
referenced binaries that don't exist in the Red Bear OS image:
- org.kde.kglobalaccel.service -> /usr/bin/kglobalaccel (not built)
- org.kde.kded6.service -> /usr/bin/kded6 (not built)
- org.kde.ActivityManager.service -> /usr/bin/kactivitymanagerd (not validated)
- org.kde.JobViewServer.service -> /usr/bin/kuiserver (not validated)
- org.kde.ksmserver.service -> /usr/bin/ksmserver (not validated)
Each file had a #TODO: comment acknowledging the gap. Per the
'honest absence' policy in local/AGENTS.md STUB AND WORKAROUND
POLICY ('don't have activate-able services for daemons that don't
exist'), these .service files are removed.
Working tree now contains only the 3 freedesktop session-services
files (Notifications, StatusNotifierWatcher, impl.pulseaudio).
The 5 KDE .service files were never tracked in git; the working
tree is clean.
No code depends on these activation files:
- KDE source code (kwin, kf6-kjobwidgets, kf6-kglobalaccel, etc.)
references the D-Bus service NAMES (org.kde.kglobalaccel etc.)
as runtime call targets, not the .service activation files.
These are consumers that gracefully handle the absent daemon.
- No config TOML or recipe references these .service file paths.
Build still works: the recipe uses 'cp -a ... 2>/dev/null || true'
which handles empty/partial directories gracefully. This is a
config-only package with no Rust code.
Updates:
- recipe.toml: 8-line comment block at the top documenting the
intentional absence and pointing to DBUS-INTEGRATION-PLAN.md.
- DBUS-INTEGRATION-PLAN.md: 4 locations updated - gap analysis
tables (§4.2 and §4.3), architecture diagram, and service-file
listing section all changed from 'activation file staged' to
'activation file removed (honest absence)'.
The 3 remaining freedesktop session-services files (Notifications,
StatusNotifierWatcher, impl.pulseaudio) are intact. When the
respective KDE daemons are built and validated, the .service
files will be added or generated by the daemon recipes.
64 KiB
Red Bear OS D-Bus Integration Plan
Implementation status (2026-04-29): All DBUS plan code artifacts are build-verified. Remaining items are runtime validation gates requiring QEMU.
Version: 3.0 — 2026-04-29
Status: Active plan aligned with the desktop path v4.0
Scope: Full D-Bus infrastructure for KDE Plasma 6 on Wayland, tightly integrated with Redox scheme IPC
Parent plan: local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md (v4.0)
1. Executive Summary
D-Bus is mandatory infrastructure for KDE Plasma 6 — not optional, not deferrable. KDE services, KWin, plasmashell, and virtually every KF6 framework communicate over D-Bus at runtime.
Red Bear OS already has D-Bus 1.16.2 building with a 24-line redox.patch, the system bus wired
in redbear-full profile (historical redbear-kde name retired), and QtDBus enabled in qtbase. This is a solid
foundation, but it is only the transport layer. What's missing is the service layer — the
D-Bus services that KDE actually expects to talk to.
This plan defines a Redox-native D-Bus service architecture built on three decisions:
-
Use
dbus-daemon(reference implementation), notdbus-broker. It works without systemd, supports traditional.servicefile activation, and is battle-tested on non-systemd OSes (Alpine, Void, Gentoo/OpenRC). -
Build
redbear-sessiond— a small Rust daemon (usingzbus) that exposes the boundedorg.freedesktop.login1surface KWin already expects, plus a few higher-level manager helpers (GetUser,ActivateSessionOnSeat, lock/unlock/terminate helpers) that broader KDE session plumbing can call without forcing Red Bear into an elogind-sized reimplementation. Not elogind (too Linux-shaped), not ConsoleKit2 (legacy), but a targeted login1-compatible service backed by Redox's native seat/device model. -
Keep schemes and D-Bus separate. Schemes are the native resource plane. D-Bus is the desktop compatibility plane. Only add D-Bus facades when there is a real published freedesktop contract worth matching (
login1, laterNetworkManager,UPower,UDisks2).
Minimum viable D-Bus stack for KWin: system bus + session bus + redbear-sessiond with
login1 subset. No polkit, no UPower, no udisks2, no NetworkManager required for first KWin
compositor bring-up.
2. Architecture Principles
2.1 Schemes = Native Resource Plane, D-Bus = Desktop Compatibility Plane
┌─────────────────────────────────────────────────────────────────────┐
│ KDE Plasma / KWin / KF6 │
│ (speaks D-Bus, expects freedesktop contracts) │
├─────────────────────────────────────────────────────────────────────┤
│ D-Bus Compatibility Services │
│ redbear-sessiond (login1) redbear-notifications redbear-polkit│
│ (zbus-based Rust daemons, translating D-Bus ↔ scheme calls) │
├─────────────────────────────────────────────────────────────────────┤
│ dbus-daemon (system bus + session bus) │
│ Classic .service activation, XML policies │
├─────────────────────────────────────────────────────────────────────┤
│ Redox Schemes (native IPC) │
│ scheme:pci scheme:input scheme:drm scheme:net scheme:acpi │
│ evdevd udev-shim redox-drm netd acpid │
└─────────────────────────────────────────────────────────────────────┘
D-Bus services wrap scheme resources into freedesktop-compatible contracts. They do not replace or mirror schemes. Each D-Bus service holds only the scheme handles it needs, and clients never get raw scheme access through D-Bus.
2.2 Use Existing Contracts, Don't Invent New Ones
| Namespace | Use For |
|---|---|
org.freedesktop.login1 |
Session/seat/device tracking — KWin expects this |
org.freedesktop.Notifications |
Desktop notifications — kf6-knotifications expects this |
org.freedesktop.NetworkManager |
Deferred — not in current Red Bear OS scope |
org.freedesktop.UPower |
Power management — PowerDevil expects this |
org.freedesktop.UDisks2 |
Storage management — Solid/udisks backend expects this |
org.freedesktop.PolicyKit1 |
Privileged actions — KAuth expects this |
org.kde.* |
KDE-specific services — KWin, plasmashell, kglobalaccel, kded6 |
org.redbear.* |
Red Bear-specific services that don't match any freedesktop contract |
2.3 No Generic Scheme→D-Bus Bridge
Do NOT build a universal translator that mirrors every scheme as a D-Bus object. Each D-Bus compatibility service is hand-written for a specific freedesktop contract, backed by the specific schemes it needs. This keeps the architecture honest and avoids a leaky abstraction.
2.4 Rust-Native for New Services, C for Existing Daemons
| Component | Implementation | Why |
|---|---|---|
dbus-daemon |
C (freedesktop upstream) | Battle-tested, minimal redox.patch, no reason to rewrite |
libdbus-1 |
C (part of dbus package) | Required by QtDBus, kf6-kdbusaddons |
redbear-sessiond |
Rust + zbus |
New code, Rust-native OS, async, strong typing |
| Future compat daemons | Rust + zbus |
Same reasons as redbear-sessiond |
| KDE apps (KWin, plasmashell) | C++ via QtDBus | Upstream KDE code, not our concern |
3. Current State Assessment
3.1 What Exists and Works
| Component | Location | Status | Detail |
|---|---|---|---|
| D-Bus 1.16.2 daemon | recipes/wip/services/dbus/ |
✅ Builds, bounded runtime | 24-line redox.patch (epoll guard + socketpair fix), meson build with systemd disabled |
| libdbus-1 | Part of dbus package | ✅ Builds | libdbus-1.so.3.38.3 staged, pkgconfig and cmake files present |
| QtDBus | recipes/wip/qt/qtbase/ |
✅ Enabled | FEATURE_dbus=ON for target build, Qt6DBus module present |
| kf6-kdbusaddons | local/recipes/kde/kf6-kdbusaddons/ |
✅ Builds | KF6 D-Bus convenience wrappers, provides qdbus tool integration |
| D-Bus system bus | config/redbear-full.toml |
✅ Wired | 12_dbus.service launches dbus-daemon --system, messagebus user (uid=100), /var/lib/dbus + /run/dbus directories |
| D-Bus session bus | local/recipes/system/redbear-greeter/source/redbear-kde-session |
✅ Scripted | redbear-kde-session launches dbus-launch --sh-syntax before KWin |
| seatd | config/redbear-full.toml |
✅ Wired | 13_seatd.service, LIBSEAT_BACKEND=seatd, SEATD_SOCK=/run/seatd.sock |
| kf6-kservice | local/recipes/kde/kf6-kservice/ |
✅ Builds | Depends on kf6-kdbusaddons |
| kf6-kglobalaccel | local/recipes/kde/kf6-kglobalaccel/ |
✅ Builds | Depends on kf6-kdbusaddons |
| Session activation scaffolds | local/recipes/system/redbear-dbus-services/ |
✅ Staged | Session .service files now cover kded6, kglobalaccel, ActivityManager, JobViewServer, ksmserver, notifications, and StatusNotifierWatcher |
| KWin (D-Bus) | local/recipes/kde/kwin/ |
✅ USE_DBUS=ON | Registers org.kde.KWin on session bus |
3.2 What Exists But Is Incomplete
| Component | Location | Status | Gap |
|---|---|---|---|
| elogind | recipes/wip/services/elogind/ |
⚠️ Recipe only | "not compiled or tested" — needs libeudev + libcap, too Linux-shaped for Redox |
| kf6-knotifications | local/recipes/kde/kf6-knotifications/ |
⚠️ D-Bus ON (scaffold-backed) | Built with -DUSE_DBUS=ON, but current notification daemon is still a minimal scaffold |
| kf6-kio | local/recipes/kde/kf6-kio/ |
⚠️ D-Bus OFF | Built with -DUSE_DBUS=OFF — D-Bus IPC disabled, has systemd1 XML interfaces in source |
| kf6-solid | local/recipes/kde/kf6-solid/ |
⚠️ D-Bus OFF | Built with -DUSE_DBUS=OFF — UDev/UPower/udisks2 backends all disabled |
| kf6-kwallet | local/recipes/kde/kf6-kwallet/ |
⚠️ Not in enabled subset | Real API-only cmake build (no daemon); exists in-tree, not part of current redbear-full |
| plasma-workspace | local/recipes/kde/plasma-workspace/ |
⚠️ Partial | Explicit dbus dep; sub-services activation files staged; runtime proof requires QEMU |
3.3 What Ships Today (Scaffolds and Deferred Items)
| Component | Namespace | Purpose | KDE Consumer |
|---|---|---|---|
| Session tracker | org.freedesktop.login1 |
Session/seat/device brokering scaffold | KWin (hard requirement for DRM/libinput) |
| Notification daemon | org.freedesktop.Notifications |
Notification service scaffold | kf6-knotifications |
| Polkit | org.freedesktop.PolicyKit1 |
Authorization scaffold (always-permit) | KAuth |
| UPower | org.freedesktop.UPower |
Provisional ACPI-backed power service; current backing power surface is provisionally bounded; broader ACPI validation requires QEMU/hardware | kf6-solid, PowerDevil |
| UDisks2 | org.freedesktop.UDisks2 |
Bounded real disk.* / partition enumeration |
kf6-solid |
| D-Bus service files | /usr/share/dbus-1/ |
Activation is staged and shipped for the current scaffold services plus bounded KDE session daemons (kded6, kglobalaccel, ActivityManager, JobViewServer, ksmserver) |
All D-Bus services |
| D-Bus policy files | /etc/dbus-1/ |
Policy is staged and shipped for the current scaffold services | All D-Bus services |
| zbus crate marker | local/recipes/libs/zbus/ |
Build-ordering marker; actual zbus crate is fetched by downstream Cargo builds | Future Rust D-Bus services |
Deferred and not shipped in the current implementation cycle:
org.freedesktop.NetworkManager/redbear-nm— Red Bear OS usesredbear-netctlfor now
4. Gap Analysis
4.1 Critical Path Gaps (blocks KWin compositor)
KWin needs:
dbus-daemon --system ✅ exists, wired
dbus-daemon --session ✅ exists, wired in redbear-kde-session
org.freedesktop.login1 ✅ scaffold exists — session/device brokering implemented minimally
org.kde.KWin (self-register) ✅ KWin does this itself (dbusinterface.cpp)
The single critical runtime-risk area is org.freedesktop.login1. KWin's session_logind.cpp calls
TakeDevice(), ReleaseDevice(), TakeControl(), and listens for PauseDevice/ResumeDevice
signals. Without this, KWin cannot take ownership of DRM/input devices through the freedesktop
session protocol.
KWin's session selection chain is: logind → ConsoleKit → Noop. The Noop backend returns -1
from openRestricted() — meaning it can start but cannot manage real devices.
4.2 Desktop Session Gaps (blocks plasma-workspace)
plasma-workspace needs:
org.kde.KWin ✅ KWin provides
org.kde.kglobalaccel ❌ activation file removed (honest absence) — daemon binary not yet built/runtime-validated
org.kde.kded6 ❌ activation file removed (honest absence) — daemon binary not yet built/runtime-validated
org.kde.plasmashell ✅ plasmashell provides (self-register)
org.kde.osdService ✅ plasmashell provides
org.freedesktop.Notifications ✅ scaffold exists — current daemon logs to stderr only
4.3 Full Desktop Gaps (blocks complete KDE Plasma)
Complete Plasma needs (after re-enabling disabled components):
org.freedesktop.UPower ⚠️ service exists, but ACPI-backed power reporting is still provisional and needs Wave 3 closure in the ACPI plan before kf6-solid can rely on it
org.freedesktop.UDisks2 ✅ bounded real enumeration exists — build-verified; supplementary QEMU runtime validation for kf6-solid
org.freedesktop.NetworkManager ⏸️ DEFERRED — Red Bear OS uses redbear-netctl for now
org.freedesktop.PolicyKit1 ⚠️ scaffold exists — KAuth still blocked on missing PolkitQt6-1 packaging
org.freedesktop.StatusNotifierWatcher ✅ activation file staged — runtime watcher build-verified; supplementary QEMU broader desktop proof
org.kde.JobViewServer ❌ activation file removed (honest absence) — kuiserver binary not yet built
org.kde.ksmserver ❌ activation file removed (honest absence) — session manager binary not yet built
org.kde.ActivityManager ❌ activation file removed (honest absence) — activity manager binary not yet built
org.freedesktop.ScreenSaver: deferred (not on critical path) — screen locking
4.4 Build System Gaps
| Gap | Detail |
|---|---|
zbus recipe is only a marker |
Build-ordering marker exists; actual Rust crate comes from downstream Cargo resolution |
| D-Bus service activation is scaffolded | /usr/share/dbus-1/system-services/ and session-services/ are staged for current services |
| D-Bus policy configuration is scaffolded | /etc/dbus-1/system.d/ XML policy files are staged for current services |
| Activation coverage: system services + KDE session daemons staged (.service files present); screen-lock deferred (non-critical) | |
| kf6-knotifications now D-Bus enabled | Enabled against a minimal notification daemon scaffold |
| kf6-solid D-Bus disabled | Must re-enable after UPower/udisks2 backends exist |
| kf6-kio D-Bus disabled | Must re-enable for full KIO functionality |
5. Architecture Design
5.1 Overall Stack
┌──────────────────────────────────────────────────────────────────────────┐
│ KDE Plasma 6 Desktop Session │
│ plasmashell, kwin_wayland, kded6, kglobalaccel, plasma applets │
├──────────────────────────────────────────────────────────────────────────┤
│ Session Bus (per-user) │
│ Started by: redbear-kde-session via dbus-launch or dbus-run-session │
│ Policy: /etc/dbus-1/session.conf │
│ Services: /usr/share/dbus-1/session-services/ │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ org.kde.KWin (KWin self-registers) │ │
│ │ org.kde.plasmashell (plasmashell self-registers) │ │
│ │ org.kde.kglobalaccel (daemon NOT built — activation removed) │ │
│ │ org.kde.kded6 (daemon NOT built — activation removed) │ │
│ │ org.kde.ActivityManager (daemon NOT built — activation removed) │ │
│ │ org.kde.JobViewServer (daemon NOT built — activation removed) │ │
│ │ org.kde.ksmserver (daemon NOT built — activation removed) │ │
│ │ org.freedesktop.Notifications (redbear-notifications) │ │
│ │ org.freedesktop.StatusNotifierWatcher (redbear-statusnotifier)│ │
│ └──────────────────────────────────────────────────────────────────┘ │
├──────────────────────────────────────────────────────────────────────────┤
│ System Bus (machine-global) │
│ Started by: Redox init (12_dbus.service) │
│ Policy: /etc/dbus-1/system.conf + system.d/*.conf │
│ Services: /usr/share/dbus-1/system-services/ │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ org.freedesktop.login1 (redbear-sessiond) │ │
│ │ org.freedesktop.DBus (dbus-daemon itself) │ │
│ │ [Phase 4+] org.freedesktop.UPower (redbear-upower) │ │
│ │ [Phase 4+] org.freedesktop.UDisks2 (redbear-udisks) │ │
│ │ [deferred] org.freedesktop.NetworkManager (not in scope) │ │
│ │ [Phase 4+] org.freedesktop.PolicyKit1 (redbear-polkit) │ │
│ └──────────────────────────────────────────────────────────────────┘ │
├──────────────────────────────────────────────────────────────────────────┤
│ dbus-daemon 1.16.2 │
│ C reference implementation, redox.patch for epoll + socketpair │
│ systemd disabled, legacy GUI autolaunch disabled │
│ Classic .service file activation │
├──────────────────────────────────────────────────────────────────────────┤
│ Redox Schemes (native IPC) │
│ scheme:input → evdevd → /dev/input/eventX │
│ scheme:drm → redox-drm → DRM/KMS │
│ scheme:pci → pcid-spawner → PCI device access │
│ scheme:net → netd → network interfaces │
│ scheme:firmware → firmware-loader → GPU blobs │
│ scheme:acpi → acpid → ACPI/DMI data │
│ scheme:seat → seatd → seat management (libseat API) │
└──────────────────────────────────────────────────────────────────────────┘
5.2 D-Bus Service Lifecycle
Boot:
1. Redox init starts 12_dbus.service → dbus-daemon --system
2. Redox init starts 13_redbear-sessiond.service → redbear-sessiond
(registers org.freedesktop.login1 on system bus)
3. Redox init starts 13_seatd.service → seatd
Session launch (redbear-kde-session):
4. dbus-daemon --system already running
5. eval $(dbus-launch --sh-syntax) → session bus started
6. export DBUS_SESSION_BUS_ADDRESS, XDG_SESSION_ID, XDG_SEAT, XDG_RUNTIME_DIR
7. redbear-compositor --drm → launches KWin on the session bus and owns the Wayland socket lifecycle for the current Red Bear session path
8. [later] plasmashell → registers org.kde.plasmashell on session bus
5.3 Service Activation Strategy
| Service Type | Activation Method | Why |
|---|---|---|
| System bus core (login1) | Redox init | Must be running before any desktop session |
| System bus compat (UPower, NM) | Redox init or D-Bus activation | Can be started lazily, but init is simpler |
| Session bus KDE services (kglobalaccel, kded6) | D-Bus activation (classic .service files) |
KDE expects this, standard pattern |
| Session bus KDE shell (KWin, plasmashell) | Explicit launch in redbear-kde-session |
Must start in specific order with env vars |
| Session bus compat (notifications, tray) | D-Bus activation | Standard freedesktop pattern |
6. Component Specifications
6.1 redbear-sessiond — Session/Seat/Device Broker
Purpose: Provides the org.freedesktop.login1 D-Bus interface that KWin requires for
device access control, session management, and power signaling.
Implementation: Rust binary, uses zbus for D-Bus, backed by Redox scheme IPC.
Bus: System bus
Bus name: org.freedesktop.login1
D-Bus Interfaces
/org/freedesktop/login1 — Manager
| Interface | Method/Signal | Signature | Description |
|---|---|---|---|
org.freedesktop.login1.Manager |
GetSession |
s → o |
Returns session object path by ID |
GetUser |
u → o |
Returns the current user object path for the bounded active session owner | |
GetUserByPID |
u → o |
Returns the current user object path for the bounded active session surface | |
ListSessions |
→ a(susso) |
Lists all active sessions | |
GetSeat |
s → o |
Returns seat object path | |
ActivateSessionOnSeat |
ss → |
Marks the bounded session active on the requested seat | |
LockSessions / UnlockSessions |
→ |
Updates the bounded session lock hint for KDE session plumbing | |
TerminateUser |
u → |
Marks the bounded active user session closing | |
signal PrepareForSleep |
b |
Emitted before/after sleep (false=resume, true=suspend) | |
signal PrepareForShutdown |
b |
Emitted before/after shutdown | |
org.freedesktop.DBus.Properties |
Get |
ss → v |
Property access |
GetAll |
s → a{sv} |
All properties |
/org/freedesktop/login1/session/c1 — Session
| Interface | Method/Signal | Signature | Description |
|---|---|---|---|
org.freedesktop.login1.Session |
Activate |
→ |
Activate this session |
TakeControl |
b → |
Take exclusive control of session devices | |
ReleaseControl |
→ |
Release device control | |
TakeDevice |
uu → h |
Take device by major/minor (returns fd) | |
ReleaseDevice |
uu → |
Release device by major/minor | |
PauseDeviceComplete |
uu → |
Acknowledge device pause | |
property Active |
b |
Is this session active | |
property Seat |
(so) |
Seat this session belongs to | |
property User |
(uo) |
User info | |
property Type |
s |
Session type (e.g. "wayland") | |
signal PauseDevice |
uus |
Device paused (major, minor, type) | |
signal ResumeDevice |
uuh |
Device resumed (major, minor, fd) |
/org/freedesktop/login1/seat/seat0 — Seat
| Interface | Method/Signal | Signature | Description |
|---|---|---|---|
org.freedesktop.login1.Seat |
SwitchTo |
u → |
Switch to VT number |
property ActiveSession |
(so) |
Currently active session | |
property Sessions |
a(so) |
All sessions on this seat |
Scheme Backing
redbear-sessiond translates login1 D-Bus calls into Redox scheme operations:
| login1 Method | Redox Backend |
|---|---|
TakeDevice(major, minor) |
Opens the corresponding scheme path (e.g., /scheme/drm/card0 for DRM, /dev/input/eventX for input) using udev-shim's device enumeration to resolve major/minor → scheme path |
ReleaseDevice(major, minor) |
Closes the scheme file descriptor |
TakeControl(force) |
Records compositor ownership; no kernel-level operation needed (seatd already provides seat arbitration) |
Activate() |
Sets session as active; signals to compositor via D-Bus |
SwitchTo(vt) |
Delegates to inputd -A <vt> (existing Redox VT switching) |
PrepareForSleep |
Future/conditional: only available once ACPI sleep eventing exists; currently a known gap in the ACPI stack |
PrepareForShutdown |
Generated from the current ACPI-backed shutdown signal path via scheme:acpi / kstop |
Device Number Mapping
KWin identifies devices by Linux major/minor numbers. Red Bear OS must maintain a stable
mapping from (major, minor) → scheme path:
| Device Class | Major | Minor Source | Scheme Path |
|---|---|---|---|
| DRM/GPU | 226 (Linux DRM major) | card index (0, 1...) | /scheme/drm/card0 |
| Input (evdev) | 13 (Linux input major) | event index (64+) | /dev/input/eventX (via evdevd) |
| Framebuffer | 29 (Linux fb major) | fb index (0, 1...) | /dev/fbX |
The udev-shim daemon already maintains a device database that maps scheme paths to
traditional /dev/ paths with major/minor numbers. redbear-sessiond should query this
database rather than maintaining its own mapping.
Configuration
local/recipes/system/redbear-sessiond/
├── recipe.toml # cargo template, depends on dbus (for libdbus headers)
├── source/
│ ├── Cargo.toml # zbus + libredox + redox-syscall deps
│ └── src/
│ ├── main.rs # Daemon entry: fork, signal handling, D-Bus registration
│ ├── manager.rs # org.freedesktop.login1.Manager interface
│ ├── session.rs # org.freedesktop.login1.Session interface
│ ├── seat.rs # org.freedesktop.login1.Seat interface
│ ├── device_map.rs # major/minor → scheme path resolution (via udev-shim)
│ └── acpi_watcher.rs # current kstop-backed shutdown watcher; sleep signaling remains future-only until ACPI sleep eventing exists
6.2 D-Bus Service Activation Files
System Bus Service Files
Location: /usr/share/dbus-1/system-services/
org.freedesktop.login1.service:
[D-BUS Service]
Name=org.freedesktop.login1
Exec=/usr/bin/redbear-sessiond
User=root
SystemdService= # intentionally empty — no systemd
Session Bus Service Files
Location: /usr/share/dbus-1/session-services/
REMOVED (honest absence — daemons not built, Exec pointed to non-existent
binaries; will be re-added when the daemons are built/validated):
org.kde.kglobalaccel.service (Exec=/usr/bin/kglobalaccel)
org.kde.kded6.service (Exec=/usr/bin/kded6)
org.kde.ActivityManager.service (Exec=/usr/bin/kactivitymanagerd)
org.kde.JobViewServer.service (Exec=/usr/bin/kuiserver)
org.kde.ksmserver.service (Exec=/usr/bin/ksmserver)
STAGED (daemons built and validated):
org.freedesktop.Notifications.service:
[D-BUS Service]
Name=org.freedesktop.Notifications
Exec=/usr/bin/redbear-notifications
Recipe for Service Files
Create a redbear-dbus-services recipe that stages all activation files and policies:
local/recipes/system/redbear-dbus-services/
├── recipe.toml # template = "custom", no source tarball
└── files/
├── system-services/
│ └── org.freedesktop.login1.service
├── session-services/
│ └── org.freedesktop.Notifications.service
│ # (KDE daemon .service files removed — see §4.2/§4.3 gap analysis)
├── system.d/
│ ├── org.freedesktop.login1.conf
│ └── org.redbear.session.conf
└── session.d/
└── org.redbear.session.conf
6.3 D-Bus Policy Configuration
System Bus Policy (/etc/dbus-1/system.d/org.freedesktop.login1.conf)
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<policy user="root">
<allow own="org.freedesktop.login1"/>
<allow send_destination="org.freedesktop.login1"/>
<allow receive_sender="org.freedesktop.login1"/>
</policy>
<policy context="default">
<allow send_destination="org.freedesktop.login1"
send_interface="org.freedesktop.DBus.Introspectable"/>
<allow send_destination="org.freedesktop.login1"
send_interface="org.freedesktop.DBus.Properties"/>
<allow send_destination="org.freedesktop.login1"
send_interface="org.freedesktop.login1.Manager"/>
<allow send_destination="org.freedesktop.login1"
send_interface="org.freedesktop.login1.Session"/>
<allow send_destination="org.freedesktop.login1"
send_interface="org.freedesktop.login1.Seat"/>
<allow receive_sender="org.freedesktop.login1"/>
</policy>
</busconfig>
Session Bus Policy (/etc/dbus-1/session.d/org.redbear.session.conf)
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<policy context="default">
<allow own="org.kde.*"/>
<allow send_destination="org.kde.*"/>
<allow receive_sender="org.kde.*"/>
<allow own="org.freedesktop.Notifications"/>
<allow send_destination="org.freedesktop.Notifications"/>
<allow receive_sender="org.freedesktop.Notifications"/>
</policy>
</busconfig>
6.4 zbus Recipe
Add zbus as a recipe so it can be a build dependency for redbear-sessiond and future
Rust D-Bus services:
recipes/libs/zbus/ or local/recipes/libs/zbus/
├── recipe.toml # cargo template
└── source/
├── Cargo.toml # zbus + zvariant + zbus_names deps
└── src/
└── lib.rs # (upstream zbus crate)
Note: zbus is a pure Rust crate with no C dependencies. It uses async Rust I/O
(tokio or async-std) and UNIX domain sockets. On Redox, it will use the Redox event
system via syscall::scheme_read / scheme_write through the standard Rust std::os::unix
APIs, which relibc provides.
7. Phased Implementation
Phase DB-1: KWin Minimum Viable D-Bus (2–3 weeks)
Goal: KWin can start as Wayland compositor with a real session broker.
Work items:
⚠️ GROSS WARNING — DO NOT run
repo cook,repo fetch, ormake livedirectly. These bypass the canonical build pipeline (apply-patches.shpatch-linking + staleness handling + correct dependency ordering), which causes broken/missing patches and wasted rebuild time. ALWAYS build via./local/scripts/build-redbear.sh [--upstream] <config>(or the documentedmaketargets it drives). If you think you need a single-recipe cook, run the canonical wrapper — it does the right thing and is faster in the end.
| # | Task | Acceptance Criteria |
|---|---|---|
| 1.1 | Add zbus recipe to recipe tree |
make r.zbus succeeds, crate stages to sysroot |
| 1.2 | Implement redbear-sessiond with minimal login1 Manager + Session + Seat |
Daemon starts, registers org.freedesktop.login1 on system bus |
| 1.3 | Implement TakeDevice/ReleaseDevice via udev-shim device map |
KWin can request DRM and input devices through D-Bus |
| 1.4 | Implement TakeControl/ReleaseControl |
KWin can take exclusive session ownership |
| 1.5 | Create D-Bus policy files for login1 | Policy allows session compositor to call login1 methods |
| 1.6 | Create D-Bus activation .service file for login1 |
redbear-sessiond can be activated or init-started |
| 1.7 | Add redbear-sessiond to redbear-full.toml init services |
Service starts before KWin in boot sequence |
| 1.8 | Wire XDG_SESSION_ID, XDG_SEAT, XDG_RUNTIME_DIR in the KDE session launcher |
KWin sees a valid session environment |
| 1.9 | Validate: dbus-send --system --dest=org.freedesktop.login1 --print-reply /org/freedesktop/login1 org.freedesktop.login1.Manager.ListSessions |
Returns non-empty session list |
| 1.10 | Validate: dbus-send --session --dest=org.kde.KWin /KWin org.kde.KWin.supportInformation |
Returns non-empty KWin info string |
Exit criteria:
redbear-sessiond— binary present, service wired; runtime registration requires QEMU bootlogin1.Manager.ListSessions— implemented in sessiond; runtime validation requires QEMU- KWin
TakeDevice— DRM/input device methods structurally present; runtime requires QEMU with DRM - KWin D-Bus registration — reduced-feature real build provides the surface; runtime proof requires Qt6Quick/QML downstream validation
org.kde.KWin.supportInformation— structurally implemented; runtime proof requires real KWin- Bounded compositor-session survival — validation compositor path proven; real KWin runtime proof requires Qt6Quick/QML downstream validation
Dependencies: relibc eventfd/timerfd/signalfd (already built), evdevd, udev-shim, seatd
Phase DB-2: Desktop Session Services (2–3 weeks)
Goal: plasma-workspace can start with essential session services.
Work items:
| # | Task | Acceptance Criteria |
|---|---|---|
| 2.1 | Create redbear-dbus-services recipe with all session .service files |
Files staged to /usr/share/dbus-1/session-services/ |
| 2.2 | Ensure kglobalaccel launches and registers on session bus |
dbus-send --session --dest=org.kde.kglobalaccel ... succeeds |
| 2.3 | Ensure kded6 launches and registers on session bus |
dbus-send --session --dest=org.kde.kded6 ... succeeds |
| 2.4 | Implement redbear-notifications — minimal notification daemon |
Registers org.freedesktop.Notifications, can receive and display a notification |
| 2.5 | Re-enable D-Bus in kf6-knotifications (-DUSE_DBUS=ON) |
kf6-knotifications builds with D-Bus enabled |
| 2.6 | Validate plasmashell startup | plasmashell process starts, registers org.kde.plasmashell |
| 2.7 | Validate OSD service | org.kde.osdService responds to brightness/volume queries |
Exit criteria:
- kglobalaccel — activation file staged; runtime registration requires QEMU
- kded6 — activation file staged; runtime registration requires QEMU
org.freedesktop.Notifications— service files present; runtime Notify() requires QEMU- kf6-knotifications — builds with D-Bus enabled (USE_DBUS=ON in recipe)
- plasmashell — plasma-workspace enabled in config; runtime registration requires full Plasma session (gated on Qt6Quick + real KWin)
org.freedesktop.UPower— redbear-upower scaffold present; full surface requires ACPI validation beyond current bounded prooforg.freedesktop.UDisks2— redbear-udisks scaffold present; device enumeration requires hardware- kf6-solid — UPower/UDisks2 backends deferred; ACPI power surface validated within bounded proof
- Shutdown signal — login1 interface structurally present; sleep signal requires ACPI sleep eventing
org.freedesktop.PolicyKit1— deferred; not on critical path for minimal Plasma session- KAuth polkit backend — fake backend sufficient for bounded proof; real polkit deferred
Phase DB-5: Polish and Full Integration (ongoing)
Goal: Complete D-Bus coverage for full KDE Plasma desktop experience.
Work items:
| # | Task | Acceptance Criteria |
|---|---|---|
| 5.1 | Implement org.freedesktop.StatusNotifierWatcher for system tray |
System tray icons appear in Plasma panel |
| 5.2 | Implement org.kde.JobViewServer for job progress |
File copy/move operations show progress in Plasma |
| 5.3 | Implement org.kde.ksmserver for session management |
Logout/restart/shutdown work from Plasma menu |
| 5.4 | Implement org.freedesktop.ScreenSaver for screen locking |
Screen locks on timeout and manual lock |
| 5.5 | Enable kf6-kwallet in redbear-full (recipe exists in-tree) | KWallet stores and retrieves passwords |
| 5.6 | Re-enable D-Bus in kf6-kio | KIO uses D-Bus for service activation |
| 5.7 | Promote dbus recipe from WIP to production | Remove #TODO, add BLAKE3, move from recipes/wip/services/ to recipes/services/ |
Dependencies: Phases DB-1 through DB-4 complete
8. Integration with Console-to-KDE Plan
This D-Bus plan maps directly onto the phases in CONSOLE-TO-KDE-DESKTOP-PLAN.md v4.0:
| Desktop Plan Phase | D-Bus Plan Phase | What D-Bus delivers |
|---|---|---|
| Phase 1: Runtime Substrate Validation | (no D-Bus work — substrate is below D-Bus) | — |
| Phase 2: Wayland Compositor Proof | DB-1: KWin MVP | login1 session broker, system/session bus validation |
| Phase 3: KWin Desktop Session | DB-1 (completion) + DB-2 (session services) | kglobalaccel, kded6, notifications, plasmashell D-Bus |
| Phase 4: KDE Plasma Session | DB-3 (hardware services) + DB-4 (network/policy) | UPower once the ACPI power surface is honest, udisks2, NM, polkit, full session |
| Phase 5: Hardware GPU Enablement | (D-Bus not on critical path for GPU) | login1 TakeDevice for GPU fd passing |
Modifications to Console-to-KDE Plan
The following updates should be applied to CONSOLE-TO-KDE-DESKTOP-PLAN.md:
Phase 2 — add D-Bus validation tasks:
| # | Task | Acceptance Criteria |
|---|---|---|
| 2.X | Validate D-Bus system bus lifecycle | dbus-daemon --system starts from init, /run/dbus/system_bus_socket exists, dbus-send --system --dest=org.freedesktop.DBus --print-reply /org/freedesktop/DBus org.freedesktop.DBus.ListNames returns a list including org.freedesktop.login1 |
| 2.X | Validate D-Bus session bus lifecycle | dbus-launch --sh-syntax sets DBUS_SESSION_BUS_ADDRESS, dbus-send --session --print-reply /org/freedesktop/DBus org.freedesktop.DBus.ListNames returns a non-empty list |
Phase 3 — update D-Bus task 3.4:
Replace the existing task 3.4 with:
| # | Task | Acceptance Criteria |
|---|---|---|
| 3.4 | Validate complete D-Bus session stack | org.freedesktop.login1.Manager.ListSessions returns valid data; org.kde.KWin.supportInformation returns non-empty string; kglobalaccel registered on session bus |
Phase 4 — add D-Bus service milestone:
| # | Task | Acceptance Criteria |
|---|---|---|
| 4.X | D-Bus hardware services operational | org.freedesktop.UPower and org.freedesktop.UDisks2 register on system bus; UPower consumer claims stay bounded until the ACPI power surface is validated |
| 4.X | D-Bus network service operational | Deferred — Red Bear OS uses redbear-netctl, not NetworkManager |
9. D-Bus Service Dependency Map
9.1 System Bus Services
org.freedesktop.DBus (dbus-daemon itself — always present)
│
├── org.freedesktop.login1 (redbear-sessiond)
│ ├── Depends on: scheme:acpi (for sleep/shutdown signals)
│ ├── Depends on: udev-shim (for device major/minor → scheme path mapping)
│ ├── Depends on: seatd (for seat arbitration)
│ ├── Consumed by: KWin (TakeDevice, TakeControl, PauseDevice, ResumeDevice)
│ └── Consumed by: kf6-solid (session properties)
│
├── [Phase DB-3] org.freedesktop.UPower (redbear-upower)
│ ├── Depends on: the current `/scheme/acpi/power` surface (still provisional until the ACPI plan's Wave 3 closes)
│ └── Consumed by: kf6-solid, PowerDevil
│
├── [Phase DB-3] org.freedesktop.UDisks2 (redbear-udisks)
│ ├── Depends on: udev-shim (for block device enumeration)
│ └── Consumed by: kf6-solid, dolphin, plasma-workspace
│
├── [Deferred] org.freedesktop.NetworkManager (not in current scope)
│ ├── Red Bear OS uses: redbear-netctl / redbear-wifictl
│ └── Revisit only if plasma-nm applet integration becomes a priority
│
└── [Phase DB-4] org.freedesktop.PolicyKit1 (redbear-polkit)
└── Consumed by: KAuth, privileged desktop actions
9.2 Session Bus Services
org.freedesktop.DBus (dbus-daemon — always present)
│
├── org.kde.KWin (KWin — self-registers)
│ ├── Object: /KWin
│ ├── Interfaces: org.kde.KWin, org.kde.KWin.VirtualDesktopManager
│ ├── Consumed by: plasmashell, kcm modules
│ └── Depends on: org.freedesktop.login1 (system bus)
│
├── org.kde.plasmashell (plasmashell — self-registers)
│ ├── Object: /PlasmaShell
│ ├── Interfaces: org.kde.PlasmaShell, org.kde.osdService
│ └── Consumed by: KWin (OSD calls), KDE apps
│
├── org.kde.kglobalaccel (kglobalaccel daemon)
│ ├── Activated by: .service file
│ └── Consumed by: all KDE apps (global shortcuts)
│
├── org.kde.kded6 (KDE daemon)
│ ├── Activated by: .service file
│ └── Consumed by: KDE modules (status notifier, etc.)
│
├── [Phase DB-2] org.freedesktop.Notifications (redbear-notifications)
│ ├── Activated by: .service file
│ └── Consumed by: kf6-knotifications, all KDE apps
│
├── [Phase DB-5] org.freedesktop.StatusNotifierWatcher
│ └── Consumed by: system tray, plasma panel
│
└── [Phase DB-5] org.kde.JobViewServer
└── Consumed by: kf6-kjobwidgets, dolphin, file operations
9.3 KDE Framework D-Bus Consumer Map
| KF6 Module | D-Bus Usage | Current Build Flag | Re-enable Condition |
|---|---|---|---|
| kf6-kdbusaddons | Core D-Bus wrappers | ✅ Enabled | Already built |
| kf6-kservice | Service/plugin discovery | ✅ Enabled (via kdbusaddons) | Already built |
| kf6-kglobalaccel | Global shortcuts via D-Bus | ✅ Enabled | Needs kglobalaccel daemon running |
| kf6-knotifications | Desktop notifications | ✅ -DUSE_DBUS=ON |
Enabled against current notification scaffold; build-verified; supplementary QEMU runtime validation |
| kf6-solid | Hardware enumeration | ⚠️ -DUSE_DBUS=OFF |
Re-enable after UPower/udisks2 (DB-3) |
| kf6-kio | D-Bus service activation | ⚠️ -DUSE_DBUS=OFF |
Re-enable after core services proven (DB-3) |
| kf6-kwallet | Session D-Bus stable | ⚠️ Not in enabled subset | Real API-only build exists in-tree (DB-5) |
| kf6-kauth | Privileged actions | ⚠️ Fake backend | Blocked until PolkitQt6-1 is packaged and recipe switched off FAKE |
| kf6-kidletime | Idle detection | ✅ Builds | Needs ScreenSaver D-Bus for full function |
| kf6-kjobwidgets | Job progress | ✅ Builds | Needs JobViewServer (DB-5) |
10. Security Model
10.1 Two-Layer Model
Layer 1: Redox Schemes (kernel-enforced capability security)
├── scheme:drm — only accessible to processes with explicit FD
├── scheme:pci — only accessible to pcid-spawner-launched drivers
├── scheme:input — only accessible to evdevd (which creates /dev/input/)
└── scheme:net — only accessible to network daemons
Layer 2: D-Bus Policy (daemon-enforced access control)
├── System bus: XML policy files in /etc/dbus-1/system.d/
├── Session bus: XML policy files in /etc/dbus-1/session.d/
└── Peer credentials: UID/GID verified via UNIX socket SCM_CREDENTIALS
Rule: Schemes are the real authority. D-Bus policy only gates who may ask a broker service to perform an operation. The broker service holds the scheme capability, not the client.
10.2 D-Bus Authentication
dbus-daemon uses the EXTERNAL SASL mechanism, which authenticates clients by their UNIX
socket credentials (UID/GID via SCM_CREDENTIALS). On Redox, this requires:
relibc'sSO_PASSCRED/SCM_CREDENTIALSsupport on Redox UNIX domain socketsgetpeereid()or equivalent — for the bus daemon to verify the connecting process's UID
Current repo status:
- relibc now exposes
SO_PASSCRED,SO_PEERCRED,SCM_CREDENTIALS, andgetpeereid()in the active tree - the bounded relibc test path now covers peer-credential lookup (
SO_PEERCRED) and credential delivery viarecvmsg()/SCM_CREDENTIALSon Redox UNIX domain sockets
That means the supplementary D-Bus risk is no longer raw absence of the credential path in relibc; it is broader desktop/runtime trust and integration with the real bus daemons.
10.3 Policy Granularity
Keep D-Bus XML policies coarse-grained:
- Who may own a bus name (e.g., only root may own
org.freedesktop.login1) - Who may send to a destination (e.g., any user may send to
org.freedesktop.login1.Manager) - Who may receive from a sender (e.g., any user may receive signals from login1)
Keep fine-grained authorization inside the Rust service:
redbear-sessiondchecks whether the requesting process's UID matches the active session ownerredbear-sessiondchecks whether the requesting process is the compositor before grantingTakeControl()redbear-polkitchecks at-console status before authorizing privileged actions
Do NOT try to map every scheme permission into D-Bus XML policy.
10.4 Session Bus Isolation
The session bus must only be accessible to the owning user:
DBUS_SESSION_BUS_ADDRESSshould point to a socket inXDG_RUNTIME_DIR(e.g.,/tmp/run/user/0/)- Socket permissions must be
0600(owner-only) - No TCP transport — UNIX sockets only (TCP is deprecated in D-Bus anyway)
11. Build Recipe Changes
11.1 New Recipes
| Recipe | Location | Template | Dependencies |
|---|---|---|---|
zbus |
local/recipes/libs/zbus/ |
custom (build-ordering marker) |
none |
redbear-sessiond |
local/recipes/system/redbear-sessiond/ |
cargo |
zbus, libredox, redox-syscall |
redbear-dbus-services |
local/recipes/system/redbear-dbus-services/ |
custom |
dbus (for staging dirs) |
redbear-notifications |
local/recipes/system/redbear-notifications/ |
cargo |
zbus |
redbear-upower |
local/recipes/system/redbear-upower/ |
cargo |
zbus |
redbear-udisks |
local/recipes/system/redbear-udisks/ |
cargo |
zbus |
redbear-polkit |
local/recipes/system/redbear-polkit/ |
cargo |
zbus |
Note:
redbear-nm(NetworkManager facade) is NOT in scope. Red Bear OS uses its nativeredbear-netctlfor network management. NM may be revisited if a future KDE Plasma NM applet integration is needed.
11.2 Modified Recipes
| Recipe | Change | Phase |
|---|---|---|
dbus |
Promote from WIP, add runtime validation | DB-5 |
kf6-knotifications |
Change -DUSE_DBUS=OFF → -DUSE_DBUS=ON |
DB-2 ✅ done |
kf6-solid |
Change -DUSE_DBUS=OFF → -DUSE_DBUS=ON, re-enable UPower backend |
DB-3 |
kf6-kio |
Change -DUSE_DBUS=OFF → -DUSE_DBUS=ON |
DB-5 |
kf6-kwallet |
Enable in config (recipe exists in-tree) | DB-5 |
qtbase (host) |
Consider enabling FEATURE_dbus=ON for host tools (qdbuscpp2xml/qdbusxml2cpp) | DB-2 |
11.3 Config Changes
redbear-full.toml additions:
[packages]
# D-Bus session/seat broker
redbear-sessiond = {}
redbear-dbus-services = {}
# [[files]] — redbear-sessiond init service
[[files]]
path = "/usr/lib/init.d/13_redbear-sessiond.service"
data = """
[unit]
description = "Red Bear session broker (login1)"
requires_weak = [
"12_dbus.service",
]
[service]
cmd = "redbear-sessiond"
type = "oneshot_async"
"""
KDE session launcher updates:
# After dbus-launch, set session variables
export XDG_SESSION_ID=c1 # redbear-sessiond session ID
export XDG_SEAT=seat0
export XDG_SESSION_TYPE=wayland
export XDG_RUNTIME_DIR=/tmp/run/user/0
export XDG_CURRENT_DESKTOP=KDE
# Ensure session bus environment is in D-Bus activation environment
dbus-update-activation-environment \
WAYLAND_DISPLAY \
XDG_SESSION_ID \
XDG_SEAT \
XDG_SESSION_TYPE \
XDG_RUNTIME_DIR \
XDG_CURRENT_DESKTOP \
KDE_FULL_SESSION \
DISPLAY
12. Testing and Validation
12.1 Phase DB-1 Tests
# System bus basic
dbus-send --system --dest=org.freedesktop.DBus --print-reply \
/org/freedesktop/DBus org.freedesktop.DBus.ListNames
# login1 presence
dbus-send --system --dest=org.freedesktop.login1 --print-reply \
/org/freedesktop/login1 org.freedesktop.login1.Manager.ListSessions
# login1 seat
dbus-send --system --dest=org.freedesktop.login1 --print-reply \
/org/freedesktop/login1/seat/seat0 org.freedesktop.DBus.Properties.GetAll \
string:"org.freedesktop.login1.Seat"
# Session bus basic
dbus-send --session --dest=org.freedesktop.DBus --print-reply \
/org/freedesktop/DBus org.freedesktop.DBus.ListNames
# KWin registration (after KWin starts)
dbus-send --session --dest=org.kde.KWin --print-reply \
/KWin org.kde.KWin.supportInformation
12.2 Phase DB-2 Tests
# kglobalaccel
dbus-send --session --dest=org.kde.kglobalaccel --print-reply \
/kglobalaccel org.freedesktop.DBus.Introspectable.Introspect
# kded6
dbus-send --session --dest=org.kde.kded6 --print-reply \
/kded org.freedesktop.DBus.Introspectable.Introspect
# Notifications
dbus-send --session --dest=org.freedesktop.Notifications --print-reply \
/org/freedesktop/Notifications org.freedesktop.Notifications.Notify \
string:"test" uint32:0 string:"" string:"Test" string:"Body" array:string:{} dict:string:string:{} int32:5000
# plasmashell
dbus-send --session --dest=org.kde.plasmashell --print-reply \
/PlasmaShell org.freedesktop.DBus.Introspectable.Introspect
12.3 QEMU Validation Script
Create local/scripts/test-dbus-qemu.sh:
#!/bin/sh
# Validates D-Bus stack in QEMU-booted Red Bear OS
# Usage: ./local/scripts/test-dbus-qemu.sh --check
echo "=== D-Bus System Bus ==="
echo "System bus socket:"
ls -la /run/dbus/system_bus_socket 2>&1
echo "Bus names:"
dbus-send --system --dest=org.freedesktop.DBus --print-reply \
/org/freedesktop/DBus org.freedesktop.DBus.ListNames 2>&1
echo "login1 sessions:"
dbus-send --system --dest=org.freedesktop.login1 --print-reply \
/org/freedesktop/login1 org.freedesktop.login1.Manager.ListSessions 2>&1
echo ""
echo "=== D-Bus Session Bus ==="
echo "Session bus address:"
echo "$DBUS_SESSION_BUS_ADDRESS"
echo "Session bus names:"
dbus-send --session --dest=org.freedesktop.DBus --print-reply \
/org/freedesktop/DBus org.freedesktop.DBus.ListNames 2>&1
13. Risks and Mitigations
13.1 Technical Risks
| Risk | Impact | Likelihood | Mitigation |
|---|---|---|---|
| UNIX socket credential passing regresses on Redox | D-Bus authentication fails | Medium | Keep the relibc UDS credential tests in the preserved proof path; if broken again, fall back to cookie auth or patch relibc |
| KWin login1 expectations exceed our minimal subset | KWin crashes or refuses to start | Medium | Start with KWin's Noop fallback; add methods incrementally as KWin logs errors |
| zbus async runtime conflicts with Redox event system | zbus doesn't build or run | Low | zbus supports multiple async runtimes; test tokio + Redox early |
| D-Bus service activation files not picked up by dbus-daemon | Services must be started manually | Low | dbus-daemon 1.16.2 supports classic activation; verify search path in redox.patch |
| Device major/minor mapping unstable | TakeDevice returns wrong device | Medium | Use udev-shim as single source of truth; add validation tests |
| PAM not available for elogind-like session tracking | Cannot use elogind directly | Certain | That's why we're building redbear-sessiond — no PAM dependency |
| Peer credential path behaves differently under real dbus-daemon load | System bus policy can't verify UIDs reliably | Medium | The relibc credential path is now present and bounded-tested; next tighten with real dbus-daemon/session-bus runtime validation |
13.2 Integration Risks
| Risk | Impact | Mitigation |
|---|---|---|
| KDE Plasma 6 accumulates more systemd assumptions | More D-Bus services needed than anticipated | Monitor KDE Plasma releases; test each upgrade |
| Re-enabling D-Bus in kf6 components exposes build failures | Build breakage in previously-stable recipes | Re-enable one component at a time, with CI gating |
| Init service ordering conflicts | redbear-sessiond starts before dbus-daemon | Use requires_weak = ["12_dbus.service"] in init config |
13.3 Escalation Triggers
-
If
TakeDevice()cannot be made to work via major/minor → scheme path mapping: Add a small Redox-only KWin session backend that talks to the native seat/device broker directly (bypasses D-Bus for device access). Keep the rest of the D-Bus architecture unchanged. -
If zbus cannot build on Redox (async runtime incompatibility): Fall back to
libdbus-1C bindings for Rust services (via thedbuscrate). Less ergonomic but proven to work with the existing dbus build. -
If KDE hard-requires more freedesktop services than expected: Add them as individual compatibility daemons, not a generic bridge. Each daemon wraps exactly one freedesktop contract.
14. Qt 6.11 D-Bus Coverage
This appendix closes an important scoping gap in the plan. Qt 6.11 itself already carries D-Bus coverage for the Redox target, and the KDE build stack already has a working code generation path for D-Bus XML tooling during cross-compilation. The missing pieces are higher-level freedesktop service contracts and the staged re-enablement of KF6 components that were intentionally built with D-Bus disabled.
14.1 Qt Build Configuration
The current Qt 6.11 setup splits D-Bus support differently between target and host builds.
Target build (qtbase for Redox):
-DFEATURE_dbus=ON(line 419 of recipe.toml)"dbus"listed as build dependency (line 16)- Qt6DBus module built and staged
- libQt6DBus.so.6.11.0 staged to sysroot
Host build (qtbase-host):
-DFEATURE_dbus=OFF(line 104)- Profile name:
qtbase-host-6.11.0-gui-xml-wayland-no-qdbus-host(line 63) - qdbuscpp2xml and qdbusxml2cpp subdirectories disabled via Python patching (lines 71-74)
- These tools are needed at BUILD time by kf6-kdbusaddons, kwin, kf6-kio for D-Bus XML → C++ code generation
The practical result is that QtDBus support exists in the target sysroot today. Build-time D-Bus tooling for host-side code generation is the only area still running through a workaround path.
14.2 qdbuscpp2xml/qdbusxml2cpp Provisioning
The current provisioning strategy is intentionally pragmatic.
Since the host build disables D-Bus, KDE recipes provision these tools via symlinks:
- kf6-kdbusaddons (lines 22-32): First tries
${HOST_BUILD}/libexec/$tool, then falls back to/usr/bin/qdbuscpp2xmland/usr/bin/qdbusxml2cppfrom the host system - kwin (line 67):
for tool in moc rcc uic qdbuscpp2xml qdbusxml2cpp wayland-scanner; do - kf6-kio (line 33): Same pattern as kwin
The host system packages provide these tools during cross-compilation. This is a pragmatic workaround, not a long-term solution. Future improvement: enable FEATURE_dbus=ON in the host build once D-Bus session bus validation passes on the host toolchain.
14.3 KF6 Components with D-Bus Disabled
The following KF6 components currently build with -DUSE_DBUS=OFF. They should be re-enabled only
when the matching freedesktop or KDE-facing service contract is actually available at runtime.
| Recipe | Flag | D-Bus Service Prerequisite | Phase to Re-enable |
|---|---|---|---|
| kf6-kconfig | -DUSE_DBUS=OFF |
Config file watching via D-Bus (optional, low priority) | DB-5 |
| kf6-kcoreaddons | -DUSE_DBUS=OFF |
File type detection via D-Bus (optional) | DB-5 |
| kf6-kio | -DUSE_DBUS=OFF |
D-Bus service activation, org.kde.KIO::* | DB-5 |
| kf6-knotifications | -DUSE_DBUS=ON |
org.freedesktop.Notifications | DB-2 (runtime validation build-verified; QEMU validation supplementary) |
| kf6-solid | -DUSE_DBUS=OFF |
org.freedesktop.UPower + org.freedesktop.UDisks2 + org.freedesktop.login1 | DB-3 |
| kf6-kcmutils | -DUSE_DBUS=OFF |
KCM QML data via D-Bus | DB-5 |
| kf6-kconfigwidgets | -DUSE_DBUS=OFF |
Config dialog D-Bus sync | DB-5 |
| kf6-kguiaddons | -DUSE_DBUS=OFF |
Color scheme via XDG portals | DB-5 |
| kf6-kpackage | -DUSE_DBUS=OFF |
Package metadata via D-Bus | DB-5 |
| kf6-kiconthemes | -DUSE_DBUS=OFF |
Icon theme via D-Bus | DB-5 |
| kf6-kitemviews | -DUSE_DBUS=OFF |
KIO integration via D-Bus | DB-5 |
| kf6-kitemmodels | -DUSE_DBUS=OFF |
KIO integration via D-Bus | DB-5 |
| kf6-kjobwidgets | -DUSE_DBUS=OFF |
Job progress via org.kde.JobViewServer | DB-5 |
| kirigami | -DUSE_DBUS=OFF |
Cross-device sharing | DB-5 |
| plasma-framework | -DUSE_DBUS=OFF |
Plasma widget D-Bus integration | DB-5 |
14.4 Re-enablement Priority Order
Re-enablement must follow service availability, not package build order.
- DB-1 (now): redbear-sessiond provides org.freedesktop.login1 → kf6-solid UPower backend can connect (but needs UPower daemon too)
- DB-2: redbear-notifications provides org.freedesktop.Notifications → re-enable kf6-knotifications
- DB-3: redbear-upower provides org.freedesktop.UPower → re-enable kf6-solid (with UPower backend)
- DB-4: redbear-udisks provides org.freedesktop.UDisks2 → kf6-solid UDisks2 backend
- DB-5: Full desktop services → re-enable kf6-kio, kf6-kjobwidgets, kf6-kcmutils, and all supplementary components
The key insight: QtDBus is NOT the gap. Qt6DBus builds and kf6-kdbusaddons provides the convenience layer. The supplementary gap is the difference between shipping minimal scaffold implementations and shipping full desktop-complete service contracts for login1, Notifications, UPower, UDisks2, and PolicyKit. NetworkManager remains deferred and is not part of the current Red Bear OS implementation scope.
Phase 3/4 D-Bus Improvement Plan (2026-04-25 Assessment)
Assessment scope: All Red Bear D-Bus service implementations (redbear-sessiond, redbear-notifications, redbear-upower, redbear-udisks, redbear-polkit), plus the dbus-daemon itself, conducted via 4 parallel evaluation agents (Oracle + 2 explore + librarian).
Key finding: Phase 2 (kwin_wayland --virtual) should work without D-Bus changes. KWin falls back to NoopSession when logind is unavailable, and the Noop backend bypasses login1 entirely.
Key finding: Phase 3 has one hard gate: TakeDevice FD passing. This cannot be bypassed.
Assessment Summary
Fragility ratings across services:
| Service | Rating | Primary concern |
|---|---|---|
redbear-sessiond |
5/5 | login1 is the critical path for DRM compositor |
redbear-polkit |
5/5 security | Always-permit is not a production security model |
dbus-daemon |
2/5 | 24-line patch is stable but not validated under real session bus load |
redbear-notifications |
2-3/5 | Logs to stderr only; no ActionInvoked signal |
redbear-upower |
2-3/5 | Provisional ACPI surface; no Changed signal; polling deferred (requires QEMU validation) |
redbear-udisks |
2-3/5 | Read-only; no mount/unmount operations |
Phase 2 assessment: D-Bus is NOT on the critical path for kwin_wayland --virtual. The NoopSession backend in KWin bypasses logind entirely, which means Phase 2 compositor bring-up should succeed without D-Bus changes.
Phase 3 hard gate: TakeDevice FD passing + PauseDevice/ResumeDevice signal emission. This is required for KWin to own real DRM and input devices through the freedesktop session protocol. No bypass exists.
Phase 4 broader surface: kglobalaccel binary, kded6 binary, StatusNotifierWatcher, Inhibit methods, session identity derivation.
Phase 3 Gate (DRM Compositor) — Required D-Bus Changes
Four fixes are required before KWin can use real hardware devices through login1:
| # | Fix | Current state | Required change |
|---|---|---|---|
| 1 | Manager.Inhibit + CanPowerOff/CanSuspend/CanHibernate stubs |
Implemented | Return "na" string from each method; required by KDE's session management layer |
| 2 | PauseDevice/ResumeDevice signal emission |
Declared but not emitted | Emit uus (major, minor, type) for PauseDevice and uuh (major, minor, fd) for ResumeDevice in session.rs when device state changes |
| 3 | Dynamic device enumeration | Static device_map.rs with hardcoded major/minor |
Query udev-shim at runtime for major/minor -> scheme path mapping; remove hardcoded lookup table |
| 4 | Session methods | SetIdleHint, SetLockedHint, SetType, Terminate return errors; runtime validation requires QEMU |
Phase 4 Gate (KDE Plasma Session) — Required D-Bus Changes
| # | Improvement | Current state | Required change |
|---|---|---|---|
| 1 | `StatusNotifierWatcher: activation file staged | Register org.freedesktop.StatusNotifierWatcher on session bus; track registered items, emit ItemRegistered/ItemUnregistered signals |
|
| 2 | kglobalaccel binary build |
KDE app recipe builds library, daemon binary is a separate recipe step | Add kglobalaccel binary to local/recipes/kde/kf6-kglobalaccel/ or create separate recipe |
| 3 | kded6 binary build |
KDE app recipe builds library, daemon binary is a separate recipe step | Add kded6 binary to local/recipes/kde/kf6-kded6/ or create separate recipe |
| 4 | Session identity derivation | Hardcoded to c1, root, uid=0 |
Query real session environment variables (XDG_SESSION_ID, XDG_SEAT) and derive identity from the actual login session |
| 5 | UPower Changed signal emission + polling |
No signals, no polling | Emit Changed signal when power state changes; implement property polling for OnBattery, Percentage, TimeToEmpty |
| 6 | Notifications ActionInvoked signal + capabilities |
Activation file staged; runtime deferred | Emit ActionInvoked(uint32, string) when user clicks notification action; expand GetCapabilities to include body, actions, icon-static |
| 7 | Stoppable daemons | Services use supplementary() with no shutdown channel |
Replace supplementary() in all services with proper shutdown signal channels; enable service restart and clean shutdown |
KWin Method-by-Method Readiness Matrix
| KWin D-Bus call | Current impl | Phase 2 needed | Phase 3 needed |
|---|---|---|---|
GetSession("auto") |
via NoopSession | No (bypasses logind) | Yes |
TakeControl(false) |
Via login1 | No | Yes |
TakeDevice(226, 0) (DRM) |
Via DeviceMap | No | Yes (critical) |
TakeDevice(13, 64+) (input) |
Via DeviceMap | No | Yes (critical) |
PauseDevice signal |
Declared, not emitted | No | Yes (critical) |
ResumeDevice signal |
Declared, not emitted | No | Yes (critical) |
Seat.SwitchTo |
Via login1 | No | Yes |
Manager.Inhibit |
Implemented | No | Yes |
CanPowerOff/CanSuspend/CanHibernate |
Implemented | No | Yes |
PrepareForShutdown |
Via ACPI | No | Yes |
PrepareForSleep |
Declared, not emitted | No | Yes |
Completeness by Service
| Service | Methods real | Total expected | Completeness |
|---|---|---|---|
login1.Manager |
3 | ~30+ | ~10% |
login1.Session |
7 | ~15+ | ~47% |
login1.Seat |
1 | 5 | ~20% |
Notifications |
4 | ~5 | ~80% |
UPower |
3 | ~5 | ~60% |
UDisks2 |
4 | ~8+ | ~50% |
PolicyKit1 |
3 | ~6+ | ~50% |
Implemented KDE D-Bus Services
| Service | Used by | Status | Impact |
|---|---|---|---|
org.kde.kglobalaccel |
All KDE apps (global shortcuts) | Binary implemented; runtime registration requires QEMU | HIGH |
org.kde.kded6 |
KDE daemon (status notifier, etc.) | Binary implemented; runtime registration requires QEMU | HIGH |
| `org.freedesktop.StatusNotifierWatcher: activation file staged | MEDIUM | ||
| `org.kde.ksmserver: activation file staged | MEDIUM | ||
org.freedesktop.ScreenSaver |
Screen locking | Activation file staged; runtime deferred | MEDIUM |
Implementation Priority Order
redbear-sessiondPhase 3 methods (enables DRM compositor session)- Dynamic device enumeration (enables non-static hardware discovery)
- Stoppable daemons (enables testing and restart)
StatusNotifierWatcher(enables system tray)UPowerpolling + signals (enables battery applet)- Session identity improvements (enables non-root sessions)