docs: relocate DRIVER-MANAGER-MIGRATION-PLAN to archive + cleanup

The DRIVER-MANAGER-MIGRATION-PLAN was self-declared complete (the
driver-manager cutover happened 2026-07-23 per local/AGENTS.md). It
is now historical reference material rather than current planning
authority. Move it from local/docs/ into the established
legacy-obsolete-2026-07-25/ archive directory, updating every
inbound reference.

Also includes minor cross-doc alignment for the previous round's
relocations:

- local/AGENTS.md: update DRIVER-MANAGER-MIGRATION-PLAN to point to
  the legacy archive
- local/docs/REDBEAR-FULL-SDDM-BRINGUP.md: alignment update
- local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md: alignment update
- local/docs/archived/README.md: refresh archive contents note
- local/recipes/system/redbear-driver-policy/source/policy/README.md:
  policy doc drift alignment
- local/scripts/guard-recipes.sh: fix symlink target computation
  (relative path was being glued onto an absolute path, producing
  malformed dangling links like '../..//mnt/.../recipe.toml')
  -- this is a real bug fix discovered during this audit round.
This commit is contained in:
2026-07-27 12:05:54 +09:00
parent 3c90858e18
commit 1dd1fccbf3
17 changed files with 314 additions and 51 deletions
+1 -1
View File
@@ -88,7 +88,7 @@ redox-master/
| Fix a driver | `recipes/core/base/source/drivers/` | All drivers are userspace daemons |
| Fix relibc (POSIX) | `recipes/core/relibc/source/` | C library written in Rust |
| Wayland integration | `recipes/wip/wayland/` + `local/docs/WAYLAND-IMPLEMENTATION-PLAN.md` | 21 WIP recipes + local validation/ownership plan |
| KDE Plasma path | `recipes/wip/kde/` + `docs/05-KDE-PLASMA-ON-REDOX.md` | 9 WIP KDE app recipes |
| KDE Plasma path | `recipes/wip/kde/` + `local/docs/legacy-obsolete-2026-07-25/05-KDE-PLASMA-ON-REDOX.md` (historical) | 9 WIP KDE app recipes |
| **Desktop path plan** | `local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md` | **Canonical plan: console → HW-accelerated KDE** |
| Linux driver compat | `docs/04-LINUX-DRIVER-COMPAT.md` | linux-kpi + redox-driver-sys architecture (**GPU and Wi-Fi only — not USB**) |
| Build system internals | `src/bin/repo.rs`, `src/lib.rs`, `mk/repo.mk` | Cookbook tool in Rust |
+3
View File
@@ -228,6 +228,9 @@ xwayland = {}
# D-Bus Rust bindings + media
zbus = {}
# StatusNotifierWatcher — session-bus system-tray broker. D-Bus activated via
# redbear-dbus-services (inherited), consistent with redbear-notifications.
redbear-statusnotifierwatcher = {}
pipewire = {}
wireplumber = {}
+1 -1
View File
@@ -381,7 +381,7 @@ Canonical references:
- `local/docs/WAYLAND-IMPLEMENTATION-PLAN.md` — canonical Wayland subsystem plan beneath the desktop path
- `local/docs/GREETER-LOGIN-IMPLEMENTATION-PLAN.md` — canonical greeter/login plan beneath the desktop path
- `local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md`**canonical comprehensive plan** (supersedes other status docs)
- `docs/05-KDE-PLASMA-ON-REDOX.md` — historical KDE implementation rationale
- `local/docs/legacy-obsolete-2026-07-25/05-KDE-PLASMA-ON-REDOX.md` — historical KDE implementation rationale (moved to legacy archive 2026-07-27)
Acceptance:
+7 -4
View File
@@ -22,10 +22,13 @@ For current Red Bear OS status, also read:
docs/
├── 01-REDOX-ARCHITECTURE.md # Architecture reference: microkernel, scheme system, driver model, display architecture
├── 04-LINUX-DRIVER-COMPAT.md # Driver-compat architecture reference + historical porting path
├── 05-KDE-PLASMA-ON-REDOX.md # Historical KDE implementation path + deeper rationale
├── 06-BUILD-SYSTEM-SETUP.md # Build/setup mechanics guide (not canonical policy)
├── 07-RED-BEAR-OS-IMPLEMENTATION-PLAN.md # Canonical public implementation plan
└── README.md # Canonical docs index + status matrix
Note: 05-KDE-PLASMA-ON-REDOX.md was relocated to
local/docs/legacy-obsolete-2026-07-25/05-KDE-PLASMA-ON-REDOX.md (2026-07-27).
It remains a historical KDE implementation reference.
```
## WHERE TO LOOK
@@ -45,9 +48,9 @@ docs/
| How to run Linux GPU drivers? | 04 | Architecture diagram, i915 porting example |
| What is redox-driver-sys? | 04 | Crate 1: memory, IRQ, PCI, DMA wrappers |
| What is linux-kpi? | 04 | Crate 2: C headers translating Linux→Redox APIs |
| How to port Qt? | 05 | Phase KDE-A (qtbase patches, ~500-800 lines) |
| How to port KDE Frameworks? | 05 | Phase KDE-B (25 frameworks, tiered approach) |
| How to port KDE Plasma? | 05 | Phase KDE-C (KWin, Plasma Shell, session config) |
| How to port Qt? | `local/docs/legacy-obsolete-2026-07-25/05-KDE-PLASMA-ON-REDOX.md` | Phase KDE-A (qtbase patches, ~500-800 lines) — historical |
| How to port KDE Frameworks? | `local/docs/legacy-obsolete-2026-07-25/05-KDE-PLASMA-ON-REDOX.md` | Phase KDE-B (25 frameworks, tiered approach) — historical |
| How to port KDE Plasma? | `local/docs/legacy-obsolete-2026-07-25/05-KDE-PLASMA-ON-REDOX.md` | Phase KDE-C (KWin, Plasma Shell, session config) — historical |
| How to set up the build? | 06 | Prerequisites per distro, build commands |
| What is the current work ordering? | 07 | Workstream Order + Blocker chain |
| How to fix POSIX gaps in relibc? | `local/docs/KERNEL-IPC-CREDENTIAL-PLAN.md` | Implemented credential syscalls |
+4 -3
View File
@@ -37,7 +37,8 @@ current/canonical versus historical/reference split obvious.
| `local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md` | **canonical comprehensive implementation plan** — supersedes all individual subsystem docs |
| `local/docs/*IMPLEMENTATION-PLAN*.md`, `local/docs/legacy-obsolete-2026-07-25/DRM-MODERNIZATION-EXECUTION-PLAN.md` | subsystem plans for deep-dive detail only; authority chain → console-to-KDE plan |
| `docs/01-REDOX-ARCHITECTURE.md` | architecture reference |
| `docs/04-LINUX-DRIVER-COMPAT.md`, `docs/05-KDE-PLASMA-ON-REDOX.md` | valuable but partly historical roadmap/design material |
| `docs/04-LINUX-DRIVER-COMPAT.md` | valuable but partly historical roadmap/design material |
| `local/docs/legacy-obsolete-2026-07-25/05-KDE-PLASMA-ON-REDOX.md` | historical KDE implementation path (relocated from `docs/` to legacy archive 2026-07-27) |
When a current-state local document conflicts with an older historical public roadmap, prefer the
console-to-KDE plan.
@@ -48,7 +49,7 @@ console-to-KDE plan.
|---|----------|-------------|
| 01 | [Architecture Overview](01-REDOX-ARCHITECTURE.md) | Architecture reference for Redox internals: microkernel, scheme system, driver model, display stack |
| 04 | [Linux Driver Compatibility Layer](04-LINUX-DRIVER-COMPAT.md) | Historical/current hybrid design reference for the LinuxKPI-style driver compatibility model |
| 05 | [KDE Plasma on Redox](05-KDE-PLASMA-ON-REDOX.md) | Historical KDE implementation path plus deeper KDE-specific rationale |
| 05 | [KDE Plasma on Redox](../local/docs/legacy-obsolete-2026-07-25/05-KDE-PLASMA-ON-REDOX.md) | Historical KDE implementation path (relocated to legacy archive 2026-07-27) |
| 06 | [Build System Setup](06-BUILD-SYSTEM-SETUP.md) | How to build Redox from this repository |
| 07 | [Red Bear OS Implementation Plan](07-RED-BEAR-OS-IMPLEMENTATION-PLAN.md) | Canonical public implementation plan focused on profiles, packaging, validation, and staged hardware enablement |
@@ -66,7 +67,7 @@ console-to-KDE plan.
- `../local/docs/ACPI-IMPROVEMENT-PLAN.md` — ACPI ownership, robustness, validation
- `../local/docs/legacy-obsolete-2026-07-25/IRQ-AND-LOWLEVEL-CONTROLLERS-ENHANCEMENT-PLAN.md` — PCI/IRQ quality, MSI/MSI-X
- `../local/docs/legacy-obsolete-2026-07-25/DRM-MODERNIZATION-EXECUTION-PLAN.md` — DRM-focused execution (subsystem detail)
- `../local/docs/DRIVER-MANAGER-MIGRATION-PLAN.md` (v4.0, 2026-07-24) — migration from `pcid-spawner` to `driver-manager`. **CUTOVER COMPLETE (2026-07-23, operator-ratified):** driver-manager owns the boot-time PCI match/claim/spawn path in every `redbear-*` config; pcid-spawner is retired from configs and gated behind `/etc/driver-manager.d/disabled` as the operator fallback (never deleted). See `../local/docs/evidence/driver-manager/ASSESSMENT-2026-07-22.md` (major assessment, findings B1G10 + § 11 services integration). Delivered: claim-via-channel collapse (pcid `ENOLCK` exclusivity — the pcid-spawner model); init `ConditionPathExists` gate (systemd-style, `!` negation); spawned-mode `pci_register_driver` in linux-kpi (honors `PCID_CLIENT_CHANNEL` — single ownership of match-claim-spawn for native and Linux-port daemons); linux-kpi real MSI/MSI-X via pcid_interface + `pci_request_regions` + `pcie_capability_*` + PM state; redbear-iwlwifi `--daemon` onboarding + `70-wifi.toml`; `--import-linux-ids` Linux id_table→TOML pipeline; scheme operator surface (`bind`/`unbind`/`new_id`/`remove_id`/`driver_override`/`rescan`); Tier-1 driver_override; success-triggered deferred retry; concurrent probes with real `Driver::probe()`; real SIGCHLD/SIGHUP handlers; heartbeat counters; AER `route_to_driver`; `exclusive_with` mutual exclusion; `pci=nomsi` env var; PciQuirkFlags spawn env hints + `REDBEAR_DRIVER_{IOMMU_GROUP,NUMA_NODE,MSIX_VECTORS}`; driver-params bridge live; D-Bus correctly absent (bridge-on-demand). Gate: PASSED in QEMU q35 (initfs ahcid bind, rootfs e1000d concurrent bind, scheme live, resident hotplug). Platform finding: `thread::scope` hangs on Redox (spawn+join used instead). Cookbook now hashes Cargo path-dep sources (staleness hole closed). Open: P2-1 pcid AER/pciehp producers, P3 policy/hygiene. 93 tests pass; 0 audit-no-stubs violations; zero crate-local warnings on host and redox target.
- `../local/docs/DRIVER-MANAGER.md` (consolidated 2026-07-27, post-v5.9 systematic assessment) — canonical current-state doc for `driver-manager` (`../local/recipes/system/driver-manager/`). **CUTOVER COMPLETE (2026-07-23, operator-ratified):** driver-manager owns the boot-time PCI match/claim/spawn path in every `redbear-*` config; pcid-spawner is retired from configs and gated behind `/etc/driver-manager.d/disabled` as the operator fallback (never deleted). See `../local/docs/evidence/driver-manager/ASSESSMENT-2026-07-22.md` (major assessment, findings B1G10 + § 11 services integration) and `../local/docs/archived/DRIVER-MANAGER-MIGRATION-PLAN.md` (round-by-round v1.0 → v5.9 history). Delivered: claim-via-channel collapse (pcid `ENOLCK` exclusivity — the pcid-spawner model); init `ConditionPathExists` gate (systemd-style, `!` negation); spawned-mode `pci_register_driver` in linux-kpi (honors `PCID_CLIENT_CHANNEL` — single ownership of match-claim-spawn for native and Linux-port daemons); linux-kpi real MSI/MSI-X via pcid_interface + `pci_request_regions` + `pcie_capability_*` + PM state; redbear-iwlwifi `--daemon` onboarding + `70-wifi.toml`; `--import-linux-ids` Linux id_table→TOML pipeline; scheme operator surface (`bind`/`unbind`/`new_id`/`remove_id`/`driver_override`/`rescan`); Tier-1 driver_override; success-triggered deferred retry; concurrent probes with real `Driver::probe()`; real SIGCHLD/SIGHUP handlers; heartbeat counters; AER `route_to_driver`; `exclusive_with` mutual exclusion; `pci=nomsi` env var; PciQuirkFlags spawn env hints + `REDBEAR_DRIVER_{IOMMU_GROUP,NUMA_NODE,MSIX_VECTORS}`; driver-params bridge live; D-Bus correctly absent (bridge-on-demand). Gate: PASSED in QEMU q35 (initfs ahcid bind, rootfs e1000d concurrent bind, scheme live, resident hotplug). Platform finding: `thread::scope` hangs on Redox (spawn+join used instead). Cookbook now hashes Cargo path-dep sources (staleness hole closed). 148 tests pass; 0 audit-no-stubs violations; zero crate-local warnings on host and redox target.
- `../local/docs/WAYLAND-IMPLEMENTATION-PLAN.md` — Wayland compositor (subsystem detail)
- `../local/docs/archived/RELIBC-IPC-ASSESSMENT-AND-IMPROVEMENT-PLAN.md` — relibc IPC surface
- `../local/docs/GREETER-LOGIN-IMPLEMENTATION-PLAN.md` — greeter/login design
+4 -4
View File
@@ -1431,10 +1431,10 @@ When mainline updates affect our work:
also be treated as first-class subsystem plans, not as side notes.
- `local/docs/legacy-obsolete-2026-07-25/IRQ-AND-LOWLEVEL-CONTROLLERS-ENHANCEMENT-PLAN.md` is the current umbrella plan for
IRQ delivery, MSI/MSI-X quality, IOMMU validation, and other low-level controller completeness work.
- `local/docs/DRIVER-MANAGER-MIGRATION-PLAN.md` (v4.0, 2026-07-24) is the canonical planning
authority for the migration from `pcid-spawner` (retired and removed 2026-07-24;
source preserved in git history) to
`driver-manager` (`local/recipes/system/driver-manager/`). **CUTOVER COMPLETE (2026-07-23,
- `local/docs/DRIVER-MANAGER.md` (consolidated 2026-07-27, post-v5.9 systematic assessment) is the canonical
current-state document for `driver-manager` (`local/recipes/system/driver-manager/`). The
historical round-by-round v1.0 → v5.9 migration plan is archived at
`local/docs/archived/DRIVER-MANAGER-MIGRATION-PLAN.md`. **CUTOVER COMPLETE (2026-07-23,
operator-ratified):** driver-manager owns the boot-time PCI match/claim/spawn path in every
`redbear-*` config, unconditionally; pcid-spawner is fully retired from configs, services,
build wiring, and the tree. init supports
+8 -6
View File
@@ -14,9 +14,10 @@
### What Changed in v6.0 (2026-07-27)
v5.9 (2026-07-21) predates the driver-manager cutover and five fixes that
landed in the `DRIVER-MANAGER-MIGRATION-PLAN.md` v5.x program. v6.0 realigns
this canonical desktop plan with that ground truth. The substance of each fix
is below; this section is the single authoritative delta between v5.9 and v6.0.
landed in the `local/docs/DRIVER-MANAGER.md` consolidation (post-v5.9 systematic
assessment). v6.0 realigns this canonical desktop plan with that ground truth.
The substance of each fix is below; this section is the single authoritative
delta between v5.9 and v6.0.
| Fix | DM-plan milestone | Impact on this desktop plan |
|--------|-------------------|-----------------------------|
@@ -30,8 +31,9 @@ is below; this section is the single authoritative delta between v5.9 and v6.0.
### Completed Milestones (v5.0v5.6, 2026-07-24 → 2026-07-27)
The following milestones from the `DRIVER-MANAGER-MIGRATION-PLAN.md` v5.x
program are **DONE** and reflected in this plan's status tables:
The following milestones from the `local/docs/DRIVER-MANAGER.md` v5.x
consolidation are **DONE** and reflected in this plan's status tables
(per-round history archived in `local/docs/archived/DRIVER-MANAGER-MIGRATION-PLAN.md`):
| Milestone | Version | Date | Key commits | Summary |
|-----------|---------|------|-------------|---------|
@@ -290,7 +292,7 @@ interface, the add_listener call dereferences NULL+8 (the listener pointer offse
the null guards are no longer a "candidate" — comprehensive null guards are committed in
both `qtwaylandscanner` (init_listener wrap, emitting `if (proxy) wl_*_add_listener(...)`
guards) and libwayland (all `wl_proxy_*` entry points). This matches the README status
("✅ Comprehensive null guards ... committed") and `DRIVER-MANAGER-MIGRATION-PLAN.md` v5.6.
("✅ Comprehensive null guards ... committed") and `local/docs/DRIVER-MANAGER.md` (post-v5.6).
What remains open is **runtime validation**: the full Qt6→libwayland→qtwayland rebuild chain
must be exercised end-to-end and a QML window must render under redbear-compositor to prove
the guards actually fire at the right place. The root cause of why the proxy is ever NULL is
+2 -2
View File
@@ -32,7 +32,7 @@ display) so cannot be excluded.
> and the driver-manager cutover completed (operator-ratified, 2026-07-23/24):
> `driver-manager` is the sole PCI match/claim/spawn daemon in every
> `redbear-*` config and compiles cleanly. `pcid-spawner` is fully retired.
> See `local/docs/DRIVER-MANAGER-MIGRATION-PLAN.md` (v5.6). The ISO now
> See `local/docs/DRIVER-MANAGER.md` (current-state consolidated doc). The ISO now
> assembles via `make live`; the open work is **runtime display validation in
> QEMU** (seeing the SDDM/greeter prompt on the framebuffer), not compilation.
@@ -74,7 +74,7 @@ guard, kf6-kwindowsystem Wayland-plugin disable, mesa patch-path linking, stale
| 2 | **VirGL determinism:** redox-drm wins virtio-gpu bind (priority-61 vendor 0x1AF4) so KWin gets a real `card0` instead of virtio-gpud's VT scanout | **DONE** `a00c13e5` |
| R | Rust components compile-verified: `redox-drm` ✓, `redbear-compositor` ✓ (x86_64-redox) | **DONE** |
| 3 | Full build campaign: mesa → libdrm → qt6 → kf6 → kwin → sddm; fix each compile failure | **TODO** (needs cook) |
| 4 | Qt6 Wayland `null+8`: comprehensive null guards committed in qtwaylandscanner (init_listener wrap) and libwayland (all `wl_proxy_*` entry points) per README + `DRIVER-MANAGER-MIGRATION-PLAN.md` v5.6; **runtime not yet validated** in isolation (root cause of why the proxy is ever NULL still open — see `QT6-WAYLAND-NULL8-DIAGNOSIS.md` §7 runbook) | **GUARDS COMMITTED, RUNTIME OPEN** |
| 4 | Qt6 Wayland `null+8`: comprehensive null guards committed in qtwaylandscanner (init_listener wrap) and libwayland (all `wl_proxy_*` entry points) per README + `local/docs/DRIVER-MANAGER.md` (post-v5.6); **runtime not yet validated** in isolation (root cause of why the proxy is ever NULL still open — see `QT6-WAYLAND-NULL8-DIAGNOSIS.md` §7 runbook) | **GUARDS COMMITTED, RUNTIME OPEN** |
| 5 | Boot redbear-full (QEMU virtio-gpu, `-m 4G`) → observe SDDM greeter on framebuffer | **TODO** |
## Upstream cherry-pick candidates (enabling, not required yet)
+15 -2
View File
@@ -13,6 +13,7 @@ current plans. They are kept for reference only.
|----------|--------|
| `ACPI-I2C-HID-IMPLEMENTATION-PLAN.md` | Deferred; USB HID remains the primary input path. |
| `BUILD-SYSTEM-IMPROVEMENTS.md` | Historical build-system improvement plan; absorbed into `../../AGENTS.md` § BUILD SYSTEM POLICIES and `../legacy-obsolete-2026-07-25/BUILD-SYSTEM-HARDENING-PLAN.md`. |
| `DRIVER-MANAGER-MIGRATION-PLAN.md` | v1.0 → v5.9 round-by-round migration plan (2861 lines, 182 KB). Historical record of pcid-spawner → driver-manager cutover and all v5.x work. Superseded by `../DRIVER-MANAGER.md` (post-v5.9 systematic assessment). Read the current-state doc; read this archive for round-by-round history. |
| `IMPLEMENTATION-MASTER-PLAN.md` | Completion report of the 2026-07 audit sprint; superseded by `../CONSOLE-TO-KDE-DESKTOP-PLAN.md`. |
| `IMPROVEMENT-PLAN.md` | RESOLVED quality-audit plan (38/38); historical reference only. |
| `INTEL-HDA-IMPLEMENTATION-PLAN.md` | Deferred; audio remains a later priority. |
@@ -24,7 +25,7 @@ current plans. They are kept for reference only.
| `SOURCE-ARCHIVAL-POLICY.md` | Absorbed into `../../AGENTS.md` § RELEASE MODEL / SOURCE-OF-TRUTH RULE. |
| `STUBS-FIX-PROGRESS.md` | Final-state log of the completed stub→real-code campaign. |
| `SYSTEM-STABILITY-AND-UPSTREAM-SYNC-PLAN.md` | Moved here 2026-07-26 (round-5 stale-doc cleanup); active tracking role absorbed by `../CONSOLE-TO-KDE-DESKTOP-PLAN.md` and the current subsystem plans. |
| `UPSTREAM-SYNC-PROCEDURE.md` | Moved here 2026-07-27 from `../legacy-obsolete-2026-07-25/`. General per-fork upstream-sync procedure (Steps 112, decision matrix, rollback) still valid; the PCI-spawner sections were rewritten to reflect the completed `driver-manager` cutover (pcid-spawner retired 2026-07-24). Superseded for PCI-driver architecture by `../DRIVER-MANAGER-MIGRATION-PLAN.md` (v5.6). |
| `UPSTREAM-SYNC-PROCEDURE.md` | Moved here 2026-07-27 from `../legacy-obsolete-2026-07-25/`. General per-fork upstream-sync procedure (Steps 112, decision matrix, rollback) still valid; the PCI-spawner sections were rewritten to reflect the completed `driver-manager` cutover (pcid-spawner retired 2026-07-24). Superseded for PCI-driver architecture by `../DRIVER-MANAGER.md`. |
| `USB-BOOT-INPUT-PLAN.md` | Superseded by the current USB implementation planning. |
| `USB-VALIDATION-RUNBOOK-2026-07.md` | Historical validation runbook for the earlier USB phase. |
| `XHCID-DEVICE-IMPROVEMENT-PLAN.md` | Superseded by the current USB implementation planning. |
@@ -54,5 +55,17 @@ current plans. They are kept for reference only.
as historical reference. Inbound references in `DRIVER-MANAGER-MIGRATION-PLAN.md`,
`NETWORKING-IMPROVEMENT-PLAN.md`, and `PACKAGE-BUILD-QUIRKS.md` were
repointed to this `archived/` path in the same pass.
- 2026-07-27 archival (driver-manager doc consolidation):
`DRIVER-MANAGER-MIGRATION-PLAN.md` moved here. The 2861-line v1.0 → v5.9
round-by-round plan was replaced by `../DRIVER-MANAGER.md` (~685 lines,
current-state focused). The new doc adds the post-v5.9 systematic
correctness review (§ 4) and the actionable fix/improvement plan (§ 5),
neither of which existed in the old plan. Historical round-by-round
detail is preserved in this archive. Inbound references in
`../HARDWARE-VALIDATION-MATRIX.md`, `../CONSOLE-TO-KDE-DESKTOP-PLAN.md`,
`../REDBEAR-FULL-SDDM-BRINGUP.md`, `../evidence/driver-manager/D5-AUDIT.md`,
`../../AGENTS.md`, `../../../docs/README.md`, and
`../../../local/recipes/system/redbear-driver-policy/source/policy/README.md`
were repointed to `../DRIVER-MANAGER.md` in the same pass.
## Date archived: 2026-05-03 (first batch); 2026-07-18 (second batch)
## Date archived: 2026-05-03 (first batch); 2026-07-18 (second batch); 2026-07-27 (driver-manager consolidation)
+3 -1
View File
@@ -1 +1,3 @@
pub struct Connection;
// This crate is a build-ordering marker only. The real zbus crate is
// fetched by Cargo when downstream crates (e.g. redbear-sessiond) build.
// See local/recipes/libs/zbus/recipe.toml for the marker rationale.
@@ -2,7 +2,8 @@
Curated driver-policy file set for the Red Bear OS driver-manager. This
package is **dormant** until Phase **C3** of the migration plan (see
`local/docs/DRIVER-MANAGER-MIGRATION-PLAN.md` § 5.2 C3).
`local/docs/DRIVER-MANAGER.md` for current state; round-by-round history in
`local/docs/archived/DRIVER-MANAGER-MIGRATION-PLAN.md` § 5.2 C3).
Files staged to `/etc/driver-manager.d/` once the package is installed:
@@ -3,7 +3,10 @@ use std::{
env,
error::Error,
process,
sync::atomic::{AtomicU32, Ordering},
sync::{
Mutex,
atomic::{AtomicU32, Ordering},
},
};
use tokio::runtime::Builder as RuntimeBuilder;
@@ -16,15 +19,22 @@ use zbus::{
const BUS_NAME: &str = "org.freedesktop.Notifications";
const OBJECT_PATH: &str = "/org/freedesktop/Notifications";
const NOTIFICATION_CLOSED_REASON: u32 = 3;
struct Notifications {
next_id: AtomicU32,
/// Record of (notification_id, close_reason) pairs, in close order.
closed_notifications: Mutex<Vec<(u32, u32)>>,
/// Record of (notification_id, action_key) pairs, in invocation order.
invoked_actions: Mutex<Vec<(u32, String)>>,
}
impl Notifications {
fn new() -> Self {
Self {
next_id: AtomicU32::new(1),
closed_notifications: Mutex::new(Vec::new()),
invoked_actions: Mutex::new(Vec::new()),
}
}
}
@@ -43,7 +53,7 @@ impl Notifications {
_hints: HashMap<String, Value<'_>>,
_expire_timeout: i32,
) -> u32 {
let id = self.next_id.fetch_add(1, Ordering::Relaxed);
let id = self.allocate_id();
eprintln!("notification: [{app_name}] {summary}: {body}");
@@ -60,29 +70,20 @@ impl Notifications {
#[zbus(signal_emitter)] signal_emitter: SignalEmitter<'_>,
id: u32,
) {
self.record_close(id, NOTIFICATION_CLOSED_REASON);
eprintln!("notification: closed {id}");
let _ = Self::notification_closed(&signal_emitter, id, 3).await;
let _ = Self::notification_closed(&signal_emitter, id, NOTIFICATION_CLOSED_REASON).await;
}
#[zbus(name = "GetCapabilities")]
fn get_capabilities(&self) -> Vec<String> {
vec![
"body".to_owned(),
"body-markup".to_owned(),
"actions".to_owned(),
"persistence".to_owned(),
]
Self::capabilities()
}
#[zbus(name = "GetServerInformation")]
fn get_server_information(&self) -> (String, String, String, String) {
(
String::from("redbear-notifications"),
String::from("Red Bear OS"),
String::from("0.2.0"),
String::from("1.2"),
)
Self::server_information()
}
#[zbus(property(emits_changed_signal = "const"), name = "Idle")]
@@ -106,6 +107,7 @@ impl Notifications {
id: u32,
action_key: &str,
) {
self.record_action(id, action_key);
eprintln!("redbear-notifications: invoke action {id:?} -> {action_key:?}");
let _ = Self::action_invoked(&signal_emitter, id, action_key).await;
}
@@ -125,6 +127,56 @@ impl Notifications {
) -> zbus::Result<()>;
}
impl Notifications {
fn allocate_id(&self) -> u32 {
self.next_id.fetch_add(1, Ordering::Relaxed)
}
fn capabilities() -> Vec<String> {
vec![
"body".to_owned(),
"body-markup".to_owned(),
"actions".to_owned(),
"persistence".to_owned(),
]
}
fn server_information() -> (String, String, String, String) {
(
String::from("Red Bear Notifications"),
String::from("redbear"),
String::from("0.3.0"),
String::from("1.2"),
)
}
fn record_close(&self, id: u32, reason: u32) {
if let Ok(mut log) = self.closed_notifications.lock() {
log.push((id, reason));
}
}
fn record_action(&self, id: u32, action_key: &str) {
if let Ok(mut log) = self.invoked_actions.lock() {
log.push((id, action_key.to_owned()));
}
}
fn closed_notifications_snapshot(&self) -> Vec<(u32, u32)> {
self.closed_notifications
.lock()
.map(|g| g.iter().cloned().collect())
.unwrap_or_default()
}
fn invoked_actions_snapshot(&self) -> Vec<(u32, String)> {
self.invoked_actions
.lock()
.map(|g| g.iter().cloned().collect())
.unwrap_or_default()
}
}
enum Command {
Run,
Help,
@@ -216,3 +268,178 @@ fn main() {
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn notify_returns_monotonically_increasing_ids() {
let n = Notifications::new();
let id1 = n.allocate_id();
let id2 = n.allocate_id();
let id3 = n.allocate_id();
assert_eq!(id1, 1, "first id should be the initial counter value 1");
assert_eq!(id2, 2, "second id should be 2");
assert_eq!(id3, 3, "third id should be 3");
assert!(
id2 > id1,
"ids must be monotonically increasing: id2 ({id2}) <= id1 ({id1})"
);
assert!(
id3 > id2,
"ids must be monotonically increasing: id3 ({id3}) <= id2 ({id2})"
);
}
#[test]
fn capabilities_are_non_empty_and_contain_required_specs() {
let caps = Notifications::capabilities();
assert!(!caps.is_empty(), "capabilities list must not be empty");
assert!(
caps.contains(&"body".to_owned()),
"capabilities must include 'body' per the freedesktop spec; got {caps:?}"
);
assert!(
caps.contains(&"actions".to_owned()),
"capabilities must include 'actions' per the freedesktop spec; got {caps:?}"
);
}
#[test]
fn server_information_returns_expected_strings() {
let (name, vendor, version, spec_version) = Notifications::server_information();
assert_eq!(
name, "Red Bear Notifications",
"server name must match the expected product name"
);
assert_eq!(
vendor, "redbear",
"vendor must match the expected Red Bear identifier"
);
assert_eq!(
version, "0.3.0",
"version must match the current Red Bear OS release"
);
assert_eq!(
spec_version, "1.2",
"spec_version must match the freedesktop Notifications spec version"
);
}
#[test]
fn close_notification_records_id_and_correct_reason() {
let n = Notifications::new();
n.record_close(42, NOTIFICATION_CLOSED_REASON);
n.record_close(99, NOTIFICATION_CLOSED_REASON);
let log = n.closed_notifications_snapshot();
assert_eq!(
log.len(),
2,
"expected exactly 2 recorded closes, got {}",
log.len()
);
assert_eq!(
log[0],
(42, NOTIFICATION_CLOSED_REASON),
"first close should record (id=42, reason={})",
NOTIFICATION_CLOSED_REASON
);
assert_eq!(
log[1],
(99, NOTIFICATION_CLOSED_REASON),
"second close should record (id=99, reason={})",
NOTIFICATION_CLOSED_REASON
);
}
#[test]
fn invoke_action_records_payload() {
let n = Notifications::new();
n.record_action(7, "default");
n.record_action(8, "reply");
let log = n.invoked_actions_snapshot();
assert_eq!(
log.len(),
2,
"expected exactly 2 recorded action invocations, got {}",
log.len()
);
assert_eq!(
log[0],
(7, "default".to_owned()),
"first action record should be (id=7, key='default')"
);
assert_eq!(
log[1],
(8, "reply".to_owned()),
"second action record should be (id=8, key='reply')"
);
}
#[test]
fn holding_multiple_notifications_preserves_ordering() {
let n = Notifications::new();
let ids: Vec<u32> = (0..5).map(|_| n.allocate_id()).collect();
for (i, &id) in ids.iter().enumerate() {
assert_eq!(
id,
(i + 1) as u32,
"id at position {i} should be {}, got {} — ordering must be preserved",
i + 1,
id
);
}
for i in 1..ids.len() {
assert!(
ids[i] > ids[i - 1],
"id at position {i} ({}) must exceed position {} ({})",
ids[i],
i - 1,
ids[i - 1]
);
}
}
#[test]
fn fresh_instance_has_no_recorded_closes_or_actions() {
let n = Notifications::new();
assert!(
n.closed_notifications_snapshot().is_empty(),
"a fresh instance should have no recorded closes"
);
assert!(
n.invoked_actions_snapshot().is_empty(),
"a fresh instance should have no recorded action invocations"
);
}
#[test]
fn close_and_action_records_are_independent() {
let n = Notifications::new();
n.record_close(1, NOTIFICATION_CLOSED_REASON);
n.record_action(1, "default");
n.record_close(2, NOTIFICATION_CLOSED_REASON);
assert_eq!(
n.closed_notifications_snapshot().len(),
2,
"close log should have 2 entries"
);
assert_eq!(
n.invoked_actions_snapshot().len(),
1,
"action log should have 1 entry"
);
}
}
@@ -2,5 +2,14 @@
name = "redbear-statusnotifierwatcher"
version = "0.1.0"
# redbear-statusnotifierwatcher — org.freedesktop.StatusNotifierWatcher daemon.
# Session-bus D-Bus service brokering StatusNotifierItem (system tray) registration.
# Pure-Rust (zbus + tokio); no libdbus build dependency.
[source]
path = "source"
[build]
template = "cargo"
[package.files]
"/usr/bin/redbear-statusnotifierwatcher" = "redbear-statusnotifierwatcher"
+11 -9
View File
@@ -73,12 +73,14 @@ case "$MODE" in
FIXED=0
find "$LOCAL_RECIPES" -name "recipe.toml" -type f | while read -r local_recipe; do
rel="${local_recipe#$LOCAL_RECIPES/}"
# Compute relative symlink path
depth=$(echo "$rel" | tr -cd '/' | wc -c)
up=""
for ((i=0; i<depth; i++)); do up="../$up"; done
target="$up$local_recipe"
main="$MAIN_RECIPES/${rel%/*}/recipe.toml"
# Relative symlink target from the link's directory to the real
# recipe under local/recipes/. Computed with realpath so the depth
# is always correct. The previous "$up$local_recipe" form glued a
# relative prefix onto an ABSOLUTE path (local_recipe comes from
# `find "$LOCAL_RECIPES"`, which is absolute), producing malformed
# dangling links like "../..//mnt/.../recipe.toml".
target="$(realpath -m --relative-to="$(dirname "$main")" "$local_recipe")"
if [ ! -L "$main" ] || [ "$(readlink "$main")" != "$target" ]; then
# If the parent directory is a symlink into local/recipes/, the
@@ -148,11 +150,11 @@ case "$MODE" in
echo "Restoring all symlinks from local/recipes/..."
find "$LOCAL_RECIPES" -name "recipe.toml" -type f | while read -r local_recipe; do
rel="${local_recipe#$LOCAL_RECIPES/}"
depth=$(echo "$rel" | tr -cd '/' | wc -c)
up=""
for ((i=0; i<depth; i++)); do up="../$up"; done
target="$up$local_recipe"
main="$MAIN_RECIPES/${rel%/*}/recipe.toml"
# See --fix branch above: use realpath so the relative target is
# always well-formed (never a relative prefix glued onto an
# absolute path).
target="$(realpath -m --relative-to="$(dirname "$main")" "$local_recipe")"
mkdir -p "$(dirname "$main")"
rm -f "$main"
+1 -1
View File
@@ -93,7 +93,7 @@ them (see "OWNERSHIP RULE FOR UPSTREAM WIP" above).
## KDE STATUS
- Older WIP KDE app notes here are stale relative to `local/recipes/kde/` and `config/redbear-full.toml`
- See `docs/05-KDE-PLASMA-ON-REDOX.md` top-level status note plus `local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md` for current state
- See `local/docs/legacy-obsolete-2026-07-25/05-KDE-PLASMA-ON-REDOX.md` top-level status note plus `local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md` for current state
## CONVENTIONS
+1 -1
View File
@@ -1 +1 @@
../../../../local/recipes/wayland/qt6-wayland-smoke
../../../local/recipes/wayland/qt6-wayland-smoke