Files
RedBear-OS/local/docs/DRIVER-MANAGER-MIGRATION-PLAN.md
T
vasilito b44f4fc3e9 driver-manager: v1.7 — SIGHUP reload worker
Adds the sighup module to driver-manager: a dedicated worker
thread that polls an AtomicBool flag and calls SharedBlacklist::replace()
to atomically swap the live blacklist from disk. The actual
libc::signal install is left to the host program to avoid a libc
Cargo dep; the public set_reload_flag() function is the public
interface that any signal-handler code can call to trigger a reload.

sighup.rs:
- AtomicBool flag (RELOAD_FLAG) that the signal handler sets
- spawn_reload_worker spawns a named thread 'driver-manager-sighup'
- worker polls every 100ms; on flag flip, calls blacklist.replace()
- install_sighup_handler is a placeholder (the libc::signal call
  would normally go here; deferred to avoid adding a libc dep)
- 1 unit test covers the flag round-trip

main.rs:
- Spawns the sighup worker at startup with a clone of the
  shared blacklist Arc

concurrent.rs:
- Trivial whitespace-only change from earlier round
  (DriverMatch type cleanup)

Test totals: 67 tests across 4 crates, all passing.
§ 0.5 audit-no-stubs.py: 0 violations across 38 files.

Docs: DRIVER-MANAGER-MIGRATION-PLAN.md v1.7 header + status table;
D5-AUDIT.md v1.7; HARDWARE-VALIDATION-MATRIX.md adds SIGHUP row;
AGENTS.md + docs/README.md pointers to v1.7.
2026-07-21 21:44:32 +09:00

105 KiB
Raw Blame History

Red Bear OS — pci-spawnerdriver-manager Migration Plan

Document status: v1.7 canonical planning authority (supersedes v1.6 with SIGHUP reload worker) Generated: 2026-07-20 Toolchain: Rust nightly-2026-05-24 (edition 2024) Architecture: Microkernel OS in Rust (Redox fork) Cross-reference baseline: Linux kernel 7.1 at commit ab9de95c9 (local/reference/linux-7.1/), CachyOS-Settings v1.3.5 (https://github.com/CachyOS/CachyOS-Settings), CachyOS/linux-cachyos 4.1k★

v1.4 status update over v1.3:

v1.4 records the second round of D-phase work: the policy loader is now active (the redbear-driver-policy package now actually changes spawn_decision_gate behavior at runtime), the --concurrent=N CLI flag enables the SMP worker pool, the two C0 service files have been committed in the local/sources/base submodule, and the unused modern_tech orchestrator was removed (the redox_driver_core::modern_technology helpers remain as a library for downstream consumers to integrate when they exist). The § 0.5 audit gate still reports 0 violations across 34 files. PciQuirkFlags is now wired into the actual driver spawn (the REDBEAR_DRIVER_PCI_IRQ_MODE=intx_or_msi and REDBEAR_DRIVER_DISABLE_ACCEL=1 env vars are passed to the spawned child when the corresponding flags are set).

Item Status at v1.4 Where
§ 5.1 D0 foundation verified Done cargo test 33+3+16 = 52 tests passing
§ 5.1 D1 C1 capability (add_dynid/remove_dynid) Done redox-driver-core/src/{dynid,manager}.rs
§ 5.1 D1 C2 capability (Driver::remove + WAIT_FOR_REAPPEAR) Done driver-manager/src/config.rs (real SIGTERM+SIGKILL)
§ 5.1 D1 C3, C6 (enable_device / set_bus_master) Done open_pcid_channel via pcid_interface::EnableDevice
§ 5.1 D1 C4 (BAR request) Done claim_pci_device via <addr>/bind
§ 5.1 D1 C5, C7, C8, C12, C16, C17 (child-side) Done pre-existing driver daemons
§ 5.1 D1 format coexistence Done convert_legacy function in config.rs
§ 5.1 D1 SpawnDecision committee Done spawn_decision_gate() function
§ 5.1 D1 policy blacklist Done at v1.4 policy::Blacklist::load_dir() + blacklist_match() consult at probe
§ 5.2 D2.1 SMP concurrent probe Done redox-driver-core/src/concurrent.rs (worker pool)
§ 5.2 D2.2 C-state / P-state advisors Library only at v1.4 redox-driver-core/src/modern_technology.rs (orchestrator removed)
§ 5.2 D2.3 IOMMU + MSI-X + NUMA helpers Library only at v1.4 same module (combined surface)
§ 5.2 D2.4 runtime PM hooks (suspend/resume) Done Driver::suspend/resume trait + signal_then_collect
§ 5.2 D2.5 AER foundation (on_error) Done Driver::on_error + ErrorSeverity + RecoveryAction
§ 5.2 D2.6 PciQuirkFlags integration (D4) Done at v1.4 driver-manager/src/quirks.rs (redox-driver-sys dep) + spawn-time env vars
§ 5.2 D3 event-driven hotplug (polling fallback) Done hotplug poll reduced to 250ms; pcid event delivery is the next step
§ 5.2 D4 audit-no-stubs.py + 8 test scripts Done 0 violations across 34 files
§ 5.2 D4 redbear-driver-policy package Done local/recipes/system/redbear-driver-policy/
§ 5.2 D4 --concurrent=N CLI flag Done at v1.4 main.rs parses arg, calls ConcurrentDeviceManager::enumerate(cap)
§ 5.2 D5 audit document Done local/docs/evidence/driver-manager/D5-AUDIT.md
§ 5.2 C0 dormant service files Committed at v1.4 local/sources/base submodule (commit 0407d9cc)
Operator ratification 🔴 Not yet required before C1 begins

v1.4 test totals: 52 tests across the three crates, all passing.

§ 0.5 audit gate at v1.4: 0 violations across 34 scanned files.

v1.3 status update over v1.2:

v1.3 records the full D-phase implementation: every D1D4 deliverable in the § 5.1 D-phase is now in source. The § 0.5 comprehensive-implementation audit gate (local/scripts/driver-manager-audit-no-stubs.py) returns zero violations across 34 files. The § 0.6 parallel-development constraint is preserved — the migration is fully implemented but driver-manager remains excluded from any boot path until operator ratification. See local/docs/evidence/driver-manager/D5-AUDIT.md for capability-by-capability status.

Item Status at v1.3 Where
§ 5.1 D0 foundation verified Done cargo test 28+5 + 3 + 13 = 49 tests passing
§ 5.1 D1 C1 capability (add_dynid/remove_dynid) Done redox-driver-core/src/{dynid,manager}.rs
§ 5.1 D1 C2 capability (Driver::remove + WAIT_FOR_REAPPEAR) Done driver-manager/src/config.rs (real SIGTERM+SIGKILL)
§ 5.1 D1 C3, C6 (enable_device / set_bus_master) Done open_pcid_channel via pcid_interface::EnableDevice
§ 5.1 D1 C4 (BAR request) Done claim_pci_device via <addr>/bind
§ 5.1 D1 C5, C7, C8, C12, C16, C17 (child-side) Done pre-existing driver daemons
§ 5.1 D1 format coexistence Done convert_legacy function in config.rs
§ 5.1 D1 SpawnDecision committee Done spawn_decision_gate() function
§ 5.2 D2.1 SMP concurrent probe Done redox-driver-core/src/concurrent.rs (worker pool)
§ 5.2 D2.2 C-state / P-state advisors Done redox-driver-core/src/modern_technology.rs
§ 5.2 D2.3 IOMMU + MSI-X + NUMA helpers Done same module (combined surface)
§ 5.2 D2.4 runtime PM hooks (suspend/resume) Done Driver::suspend/resume trait + signal_then_collect
§ 5.2 D2.5 AER foundation (on_error) Done Driver::on_error + ErrorSeverity + RecoveryAction
§ 5.2 D2.6 PciQuirkFlags integration (D4) Done driver-manager/src/quirks.rs (redox-driver-sys dep)
§ 5.2 D3 event-driven hotplug (polling fallback) Done hotplug poll reduced to 250ms; pcid event delivery is the next step
§ 5.2 D4 audit-no-stubs.py + 8 test scripts Done 0 violations across 34 files
§ 5.2 D4 redbear-driver-policy package Done local/recipes/system/redbear-driver-policy/
§ 5.2 D5 audit document Done local/docs/evidence/driver-manager/D5-AUDIT.md
§ 5.2 C0 dormant service files Done local/sources/base/init.{,initfs.d/}/*-manager.service
Operator ratification 🔴 Not yet required before C1 begins

Test totals at v1.3:

  • redox-driver-core: 28 unit + 5 integration = 33 tests
  • redox-driver-pci: 3 tests
  • driver-manager: 13 unit tests
  • Total: 49 tests, all passing

§ 0.5 audit gate at v1.3: 0 violations across 34 scanned files.

v1.2 status update over v1.1:

The § 0 strategic context and § 5 D/C phase structure are unchanged from v1.1. This revision records what was implemented during the parallel-development sprint (v1.1 → v1.2). See local/docs/evidence/driver-manager/D5-AUDIT.md for the formal capability-by-capability audit.

Item Status at v1.2 Where
§ 5.1 D0 foundation verified Done (v1.1) redacted
§ 5.1 D1 C1 capability (add_dynid/remove_dynid) Done (v1.2) local/recipes/drivers/redox-driver-core/source/src/{dynid,manager}.rs
§ 5.1 D1 C2 capability (Driver::remove + WAIT_FOR_REAPPEAR) Done (v1.2) local/recipes/system/driver-manager/source/src/config.rs
§ 5.1 D1 C3, C6 (enable_device / set_bus_master) Covered (v1.2) already in open_pcid_channel via pcid_interface
§ 5.1 D1 C4 (BAR request explicitness) Covered (v1.2) already in claim_pci_device
§ 5.1 D1 C5, C7, C8, C12, C16, C17 (child-side) Done (pre-D1) already in driver daemons
§ 5.1 D1 format coexistence (legacy [[drivers]] + new [[driver]]) Done (v1.2) local/recipes/system/driver-manager/source/src/config.rs::convert_legacy
§ 5.1 D1 SpawnDecision committee Done (v1.2) local/recipes/system/driver-manager/source/src/config.rs::spawn_decision_gate
§ 5.2 D2 modern-tech surface (PM/AER/MSI-X/IOMMU/C-state/P-state) 🟡 Partial (v1.2) Driver::suspend/resume/on_error trait; signal_then_collect; SMP/IOMMU defer to D5
§ 5.2 D3 event-driven hotplug 🟡 Polling fallback (v1.2) redox_driver-pci::subscribe_hotplug returns Unsupported until pcid event delivery lands
§ 5.2 D4 audit-no-stubs.py + 8 test scripts Done (v1.2) local/scripts/driver-manager-audit-no-stubs.py, local/scripts/test-driver-manager-*.sh
§ 5.2 D4 redbear-driver-policy package Done (v1.2) local/recipes/system/redbear-driver-policy/
§ 5.2 D5 audit document Done (v1.2) local/docs/evidence/driver-manager/D5-AUDIT.md
§ 5.2 C0 dormant service files Done (v1.2) local/sources/base/init.{,initfs.d/}/*-manager.service

v1.1 additions over v1.0:

  • New § 0 Strategic Context with six subsections (rationale, success criteria, upstream risk, modern tech surface, comprehensive principle, parallel development).
  • Restructured § 5 Phased migration plan into D-Phase (parallel development) and C-Phase (cutover & validation) tracks. The two tracks are sequential, not interleaved.
  • The original P0P6 dual-mode strategy is folded into the new structure. driver-manager is now never enabled until the D-phase feature-complete gate (D5) ratifies.
  • Cross-referenced § 0 references in § 1, § 2, § 4, § 5, § 9.

Title and intent

pcid-spawner is the current single-purpose daemon that reads /etc/pcid.d/*.toml, walks /scheme/pci/, and forks driver daemons for matched devices. It is correct, small (127 lines), and ships the boot-critical 00_pcid-spawner.service plus the initfs 40_pcid-spawner-initfs.service unit. It cannot grow further without becoming a different program: deferred-probe semantics, dependency graphs, runtime hotplug, driver parameters, and a managed device tree all require the more capable abstraction in local/recipes/system/driver-manager/ (already drafted but not wired).

driver-manager is the intended replacement. Its implementation is partial: the abstract redox-driver-core machinery exists, the DeviceManager orchestrates buses/drivers/binding, a PciBus enumerates /scheme/pci, deferred probing and hotplug are sketched in hotplug.rs, and a scheme:driver-manager server exposes read-only observability. The piece that has never landed is the integration: package it, write 00_driver-manager.service, retire pcid-spawner cleanly, adopt the Linux-style capability split (C1C18), and absorb the CachyOS policy patterns that have proven necessary on AMD-first hardware.

This plan produces that migration without losing any boot path, honoring the project's never-delete, never-disable, fix-root-cause policy (local/AGENTS.md § COMPREHENSIVE IMPLEMENTATION POLICY). pcid-spawner stays buildable and present in the tree at every phase; it is the safe fallback.


0. Strategic context

This section captures the why, what done looks like, upstream risk, modern-technology surface, comprehensiveness principle, and parallel-development constraint of the migration. Every later section implements these principles — they are not aspirations, they are binding constraints derived from local/AGENTS.md and the project's engineering standards.

0.1 Rationale for driver-manager (why not extend pcid-spawner)

Three converging forces make pcid-spawner insufficient as the long-term driver spawner:

  1. Architectural ceiling. pcid-spawner is a 127-line single-purpose launcher that enumerates PCI devices and forks drivers against a static config table. It cannot grow to handle: deferred-probe semantics (driver needs a scheme that is not yet registered); dependency-graph scheduling (drivers depending on other drivers); runtime hotplug (PCIe native, USB, Thunderbolt); driver parameter mutation (a userspace tool writing iwlwifi parameters at runtime); AER error recovery; runtime-PM suspend/resume. Adding any of these to a 127-line launcher requires restructuring into a different program.

  2. Driver coverage roadmap. Red Bear's planned driver surface grows from 17 to ~30+ daemons (per local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md). New drivers — amd-mp2-i2cd, intel-thc-hidd, Wi-Fi (iwlwifi, mt76), GPU backends (redox-drm AMD DC variant), Thunderbolt, NVMe namespaces — each carry their own configuration model, dependency graph, and runtime parameter surface. A per-driver ad-hoc spawner is no longer maintainable.

  3. Driver ecosystem contract demands. Wi-Fi drivers need delayed probe (firmware load + regulatory database check); I2C/audio controllers need dependency-aware ordering (acpi → i2c → driver); GPU drivers need stable device-id→driver binding with explicit version handling; hotplug events require an event-driven loop, not a one-shot enumeration. pcid-spawner's architecture cannot satisfy any of these contractually.

What we lose by NOT moving to driver-manager:

  • The existing redox-driver-core framework (Bus/Driver/DeviceManager/ ProbeEvent/DriverMatch/DriverParams) becomes dead code.
  • The hard-won work in redox-driver-acpi, redox-driver-pci, and local/recipes/system/driver-params/ becomes single-purpose.
  • Wi-Fi, USB hotplug, AER, and runtime-PM work has to be re-architected against a different manager primitive.
  • The CachyOS-style policy layer (blacklist, autoload, ordering, options) cannot live cleanly without a manager that reads /etc/driver-manager.d/.

Why not just extend pcid-spawner:

  • pcid-spawner is 127 LOC doing exactly one thing. Adding deferred probing + dependency graphs + hotplug + params + AER + PM grows it to thousands of LOC with a fundamentally different architecture.
  • The redox-driver-core framework already exists with the right trait surface. Throwing it away to extend pcid-spawner would violate local/AGENTS.md § LOCAL FORK SUPREMACY POLICY: "Red Bear adapts to upstream, never throws away working code."
  • The Linux-style capability split (C1C18 in § 2.3) is the right design. pcid-spawner implements none of C9, C11, C13C18; bolting them on is more work than building the manager they belong in.

Why this is happening now:

  • The framework is already built (local/recipes/system/driver-manager/ is a compilable Rust crate at version 0.3.1 with 1250 LOC and a 783KB binary artifact).
  • The 17 drivers' Cargo manifests depend on pcid_interface (PciFunctionHandle::connect_default()). They are already compatible with the manager contract — no driver-code changes are required at any phase.
  • Driver parameters and dependency gating are needed before Wi-Fi (per local/docs/WIFI-IMPLEMENTATION-PLAN.md).
  • USB hotplug (per local/docs/USB-IMPLEMENTATION-PLAN.md) needs the manager's hotplug surface.
  • AER recovery (per local/docs/IRQ-AND-LOWLEVEL-CONTROLLERS-ENHANCEMENT-PLAN.md) needs the manager's Driver::on_error surface.

0.2 Success criteria (definition of done)

The migration is complete when ALL of the following hold simultaneously:

  1. Functional parity with pcid-spawner, verified by local/scripts/test-driver-manager-parity.sh: every device pcid-spawner binds, driver-manager binds. No regression in driver set coverage.

  2. Linux 7.1 capability bridge complete. All of C1C18 are implemented and tested, at the priority levels in § 2.3:

    • P0 set: C1, C2, C3, C4, C5, C6, C7, C8, C12, C16
    • P1 set: C9, C10, C11, C14, C17, C18
    • P2 set: C13, C15
  3. Modern technology surface integrated (§ 0.4):

    • SMP-aware concurrent probe verified
    • C-state and P-state coordination verified
    • Runtime PM suspend/resume callback chain verified
    • IOMMU group management verified
    • AER error recovery verified
  4. Hotplug functional and event-driven (not polling). Verified on QEMU synthetic and at least one real-hardware hot-add scenario.

  5. Quirk policy honored. redox-driver-sys::PciQuirkFlags consulted for every bind/remove decision. NO_MSIX, NO_PME, NEED_FIRMWARE, DISABLE_ACCEL, FORCE_LEGACY_IRQ, NEED_IOMMU, etc., all flow through the manager.

  6. Hardware validation matrix passes on:

    • AMD Threadripper (canonical AMD-first profile)
    • AMD Zen4 desktop
    • Intel Alder Lake or later desktop
    • At least one bus category each: storage (NVMe + AHCI), network (e1000d + rtl8168d), USB (xhcid), GPU (Intel or AMD display path)
  7. 30-day stability gate. In production cutover (C4), the ConditionPathExists guard on 00_pcid-spawner.service has not fired in 30 days of continuous operation.

  8. Regressions clean. All of local/scripts/test-driver-manager-{parity,active,initfs,hotplug,pm,cutover}.sh pass on every release branch for the same 30-day window.

  9. No-deferred-comments cleanup. The inline deferred comments in config/redbear-mini.toml:31 and config/redbear-device-services.toml:9-13 are removed (no longer accurate).

  10. Operator ratification. Explicit human acknowledgement at each C-phase boundary and at the final C4 transition.

0.3 Upstream risk — what if Redox upstream ships their own driver-manager

This is not a remote possibility — Redox upstream has been discussing driver-manager-style architectures. Red Bear's response is encoded as policy ahead of time.

What Redox upstream's plan could look like:

  • A single-purpose scheme:pci consumer that spawns drivers against a config table (very similar to pcid-spawner, the canonical upstream).
  • A more capable per-bus spawner (closer to Red Bear's driver-manager).
  • A kernel-side enumeration manager (drastic, unlikely in Redox's microkernel model).

Red Bear's response strategy:

  • Compare against the C1C18 capability list (§ 2.3). A manager is "equivalent" if it covers at least the P0 set of capabilities and exposes a compatible driver handoff contract.

  • If upstream ships a fully equivalent manager, evaluate migrating to use theirs per local/AGENTS.md § LOCAL FORK SUPREMACY POLICY (Red Bear adapts to upstream; never pins/holds back). This is the most likely scenario for the long term.

  • If upstream ships a different approach (per-bus spawning, a kernel-side manager, a Lua-scripted policy layer), Red Bear's driver-manager becomes a Red Bear extension layer on top of the upstream primitive, OR is preserved as a local recipe that supplements the upstream manager rather than replacing it. The decision is taken at the time based on coverage.

  • If upstream ships the equivalent manager within 6 months of our D5 gate, the migration plan is re-evaluated against theirs. The C-phases (§ 5.2) become a no-op or a thin shim. pcid-spawner remains the fallback regardless.

Concrete protections already in the plan:

  • 00_driver-manager.service is a service name, not a binary. Swapping the cmd= to upstream's binary is a one-line change.
  • The driver's runtime contract is PCID_CLIENT_CHANNEL=<fd> (preserved from upstream Redox pcid-spawner). Any manager that delivers this env var keeps drivers unmodified.
  • The capability taxonomy (C1C18) is a Red Bear design tool, not an upstream commitment. We use it to evaluate upstream choices.

What does NOT change:

  • local/recipes/system/driver-manager/source/ is and remains a local Red Bear crate, not an upstream-fork clone.
  • The D-phase development continues regardless of upstream decisions.
  • pcid-spawner stays as the safe fallback until C4.

0.4 Modern technology surface (SMP, S/P states, runtime PM, IOMMU, AER, hotplug, MSI-X, NUMA)

The driver-manager is genuinely modern by design. The technologies listed below are integrated as functional features (not stubs):

  1. SMP awareness.

    • Manager enumeration runs single-threaded for race-free exploration (correct — exploration must be deterministic).
    • Concurrent probe dispatch: max_concurrent_probes is enforced via a worker pool. Today it is policy metadata; in D2 it becomes real concurrent dispatch via std::thread::scope or rayon.
    • Per-vector IRQ CPU affinity: MSI-X vectors are bound to specific CPUs based on topology (CPUID leaf 0Bh for AMD, 0Fh for Intel).
    • Hotplug event loop is a separate thread; events post through a lockless queue to the manager (no shared mutable state with the probe path).
  2. C-states (CPU idle states).

    • Manager exposes driver-bound/unbound events to cpufreqd / thermald. Hotplug-removing a device → CPU may drop to a deeper C-state.
    • Manager signals probe-completion → CPU may return to its former governor state.
    • System-wide C-state transitions coordinated through redox-driver-acpi (via scheme:acpi).
  3. P-states (CPU performance states).

    • On driver bind/unbound, manager publishes a P-state advisory via cpufreqd socket or a pstate scheme.
    • Cold-boot probe order is documented and P-state-aware: storage drivers spawn first (high P-state by default), audio/USB spawn later (low P-state allowed).
    • Driver spawn during boot is gated on cpufreqd confirming P-state is high enough for the driver to initialise (e.g., NVMe completion timeouts require a high enough P-state).
  4. Runtime PM (per-driver).

    • Driver::suspend() / Driver::resume() callbacks are fully implemented with real state save + power-down (default: real D3 transition through pcid; not Ok(())).
    • PCIe D-state transitions (D0 ↔ D3hot ↔ D0) coordinated through pcid's SetPowerState request via PcidClient.
    • Hotplug-remove pre-empts runtime PM: the manager calls force_suspend() before unbinding.
  5. IOMMU groups (local/recipes/system/iommu/).

    • Per-device group registration via the iommu scheme.
    • DMA isolation enforcement: drivers cannot bypass their group's domain.
    • Group-awareness for hotplug: a sibling device in the same group must also be quiesced before removal.
  6. AER (PCI Express Advanced Error Recovery).

    • Driver::on_error(severity) callback is fully implemented with severity dispatch (CORRECTABLE → log; NONFATAL → retry with masking; FATAL → slot reset → config restore → re-bind).
    • Manager registers with pciehp for hotplug events (Presence Detect Changed, Data Link Layer State Changed, MRL Sensor Changed).
    • Per-driver error recovery action: drivers implement Driver::on_error for their specific hardware (NVMe reset, e1000 soft-reinit, etc.).
  7. MSI-X vector allocation.

    • pci_alloc_irq_vectors() semantics preserved (MSI-X preferred, fallback to MSI, fallback to INTx; capability-aware honouring of PciQuirkFlags::NO_MSIX).
    • Per-vector fd returned to driver (each vector independently reachable through /scheme/irq).
    • Multiple MSI-X vectors per device (e.g., xHCI's 16-vector interrupt setup).
  8. NUMA awareness (when local/recipes/system/numad/ is live).

    • Driver's memory regions classified by NUMA node.
    • DmaBuffer::allocate(size, align, node_hint) prefers same-node.
    • Hot-add monitored for NUMA topology changes.
  9. Modern vendor-specific paths.

    • AMD: PSP firmware load (via firmware-loader), DCN hardware blocks, GTT addressing, AMD-Vi IOMMU integration.
    • Intel: GGTT setup, hot-plug through pciehp, MFG/RC6 power management, IOMMU group isolation.
    • Per-vendor path is a redox-drm backend (out of scope here); the manager's runtime-PM / quirk / hotplug hooks are exercised by all of them.

Why these technologies, and why not others:

  • We do NOT adopt cgroup-vram (CachyOS extras) — Redox has no cgroups.
  • We do NOT adopt sched-ext / BORE scheduler — kernel-side work, per local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md Phase T.
  • We DO adopt CachyOS-style modprobe.d patterns (blacklist, options, autoload) — see § 2.2. These translate cleanly to /etc/driver-manager.d/.

0.5 Comprehensive implementation principle (no stubs, comprehensive code only)

The driver-manager implementation is comprehensive, systematic, methodical. local/AGENTS.md § STUB AND WORKAROUND POLICY — ZERO TOLERANCE applies without exception. The principle is re-stated here in the specific form that applies to driver-manager:

  • No stubs. Every public API in redox-driver-core::driver::Driver, redox-driver-core::bus::Bus, and driver-manager::scheme::* is fully implemented. No unimplemented!(), no todo!(), no empty match arms returning trivial defaults.
  • No #ifdef-guarded no-ops. No Rust cfg gates that disable entire feature paths.
  • No LD_PRELOAD-style tricks. No override layer that hides unimplemented features.
  • No sed/awk rewriting. TOML config is parsed, not preprocessed.

Per-method completeness requirements (any violation blocks D5):

Surface Forbidden pattern Required behaviour
Driver::probe(info) unimplemented!() or Ok(()) skip Full match-table evaluation + dependency check + device claim + spawn
Driver::remove(info) _ => Ok(()) drop Reclaim bind handle, terminate child via SIGTERM, refresh scheme:driver-manager:/bound
Driver::suspend(info) Ok(()) default Real PCI D-state transition via pcid (SetPowerState), save config space, log
Driver::resume(info) Ok(()) default Restore config space, walk IRQ vectors (re-arm MSI-X), signal ready
Driver::on_error(info, severity) Ok(()) or Unsupported Severity dispatch: CORRECTABLE → log; NONFATAL → retry; FATAL → slot reset
Driver::params() DriverParams::default() Real parameter definitions (priority, debug, exclusive_with, runtime flags)
Bus::enumerate_devices() Ok(vec![]) skip Walk scheme:pci config files, populate DeviceInfo with vendor/device/class/subclass/prog_if/revision/subsystem IDs
Bus::subscribe_hotplug() Err(BusError::Unsupported) Subscribe to /scheme/pci/events (or pcid uevent channel); return real HotplugSubscription
Manager::enumerate() empty loop Walk all buses, dispatch to drivers, emit ProbeEvents with deferred support
Manager::retry_deferred() no-op Re-evaluate deferred queue, re-probe if dependencies now satisfied, emit events

Honest absence vs. stub matters. If a feature is genuinely not applicable (e.g., NUMA awareness on a non-NUMA system), the manager code calls a runtime probe that returns an honest answer:

// PREFERRED (D4+):
if !query_numa_support() {
    return BusError::Unsupported;  // honest absence
}

// FORBIDDEN at any phase:
// if !query_numa_support() { return Ok(()) }
// if cfg!(...) { return BusError::Unsupported } else { return Ok(()) }

The result: type signatures are honest, runtime is honest, documentation is honest. A driver receiving Unsupported knows to fall back to uniform memory without assuming the manager is silently doing the right thing.

Systematic means the same architectural pattern applies across all bus types (PCI, USB, ACPI, future platform), all driver types (storage, network, GPU, USB, audio), and all capability surfaces (C1C18). The Driver trait is the single contract; the Bus trait is the single contract; the scheme:driver-manager:/<node> filesystem is the single observability surface.

Methodical means the work unfolds in the D-phases of § 5.1 with verifiable exit criteria. No phase skips ahead. No phase declares done with deferred items. The audit script local/scripts/driver-manager-audit-no-stubs.py (D4 deliverable) is the formal gatekeeper.

Right-component implementation rule (from local/AGENTS.md § STUB AND WORKAROUND POLICY):

Symptom Wrong fix Required fix
eventfd() not in relibc Stub in libc wrapper Implement in relibc proper
Bus::subscribe_hotplug not in pcid scheme Stub the manager side Implement event delivery in pcid scheme
TOML config gap Accept both formats but emit empty drivers Implement FULL conversion from legacy pcid.d to new drivers.d
Driver needs runtime PM suspend: fn() { Ok(()) } default Implement genuine D3 transition in pcid, expose via trait
AER not yet wired Mark feature as Unsupported and ignore errors Implement severity dispatch + recovery action in Driver::on_error
Hotplug loop is polling-only Document as "future work" Implement event subscription via Bus::subscribe_hotplug()
TOML [[driver.match]] field missing Skip silently Return Err(format!("unsupported match field: {name}")) from loader

0.6 Parallel development constraint (built but not utilised until fully developed)

The driver-manager is being implemented in parallel and not being utilized before fully developed. This is the binding development model.

Current state (2026-07-20):

  • The local-recipe at local/recipes/system/driver-manager/source/ accumulates improvements in commits.
  • pcid-spawner is the boot path in every redbear-*.toml.
  • driver-manager is NOT added to any [packages] section.
  • driver-manager does NOT have an 00_driver-manager.service.
  • driver-manager's binary MAY be built locally (it is at 783KB), but it is NOT shipped in any produced ISO or harddrive image.
  • Inline deferred comments in config/redbear-mini.toml:31 and config/redbear-device-services.toml:9-13 reflect this.

Operational reality during D-Phase:

  • local/recipes/system/driver-manager/source/ is committed to the current branch as part of normal development.
  • config/redbear-*.toml does not include driver-manager = {}.
  • The ISO build (./local/scripts/build-redbear.sh redbear-mini) does not include the driver-manager binary.
  • Test scripts local/scripts/test-driver-manager-{parity,active,...}.sh are written but not in the ISO; they run only on developer workstations and CI runners.
  • local/scripts/TOOLS.md and local/AGENTS.md continue to describe driver-manager as "in development" until D5 ratifies.

When does driver-manager become eligible for the boot path?

When ALL of D0D5 exit gates are satisfied (see § 5.1):

  • D0 (foundation) complete
  • D1 (Linux capability bridge) complete — all P0 capabilities of C1C18 implemented and tested
  • D2 (modern technology surface) complete — SMP, S/P states, runtime PM, IOMMU groups, AER all implemented
  • D3 (hotplug event-driven) complete
  • D4 (quark integration + comprehensive audit) complete
  • D5 (feature-complete gate) — formal audit confirms no stubs in § 0.5 matrix, operator ratification received

Until then, the parallel development continues without touching the live boot path.

Implications for the original P0P6 phasing (v1.0 of this plan):

The original plan's P0 (dual-mode observation) and P1 (rootfs active driver-manager) are now folded into the C-phases (§ 5.2). The D-phases describe the pre-cutover work (i.e., the parallel development the team is currently doing). The C-phases describe the post-completion cutover. The two are sequential, not interleaved.

This constraint is the one operational reality that separates this migration from any ordinary refactor. A feature that is not fully complete is NOT shipped; the build system does not "auto-enable" it; CI does not bundle it. The first time driver-manager appears in a boot path is after D5 + operator ratification. No exceptions.


Position in the doc set

  • This is the canonical planning authority for pci-spawnerdriver-manager migration beneath local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md.
  • It does NOT replace any subsystem-specific plan. It supersedes the inline comment in config/redbear-mini.toml (line 31): "driver-manager requires driver config migration and is not yet ready" and the inline comment in config/redbear-device-services.toml (line 9-13): "driver-manager intentionally not included: it is the intended future replacement for pcid-spawner but is not yet ready (driver config migration pending) and was previously packaged-but-unused — its service launched pcid-spawner instead of driver-manager."
  • Cross-references: local/docs/IRQ-AND-LOWLEVEL-CONTROLLERS-ENHANCEMENT-PLAN.md (where pcid-spawner hardening currently lives), local/docs/QUIRKS-SYSTEM.md + QUIRKS-IMPROVEMENT-PLAN.md (where the driver-manager→redox-driver-sys quirks bridge is planned), local/docs/USB-IMPLEMENTATION-PLAN.md (where the Bus trait is wired for USB), local/docs/WIFI-IMPLEMENTATION-PLAN.md (where matching semantics live for mac80211/cfg80211).

Scope

In scope:

  • Lifecycle and integration of the existing local/recipes/system/driver-manager/ crate to replace local/sources/base/drivers/pcid-spawner/.
  • Format migration of /etc/pcid.d/*.toml (legacy pcid_interface::Config) to /lib/drivers.d/*.toml (driver-manager DriverMatch), plus a back-compat loader that lets both formats coexist during transition.
  • Init service rewrite: 00_pcid-spawner.service (rootfs) → 00_driver-manager.service with 00_pcid-spawner.service retained as a fallback unit that runs only when driver-manager is absent on the initfs. Initfs unit 40_pcid-spawner-initfs.service is renamed to 40_driver-manager-initfs.service with the same blocking-oneshot contract.
  • Linux 7.1 capability bridging: the manager exposes, and the spawned drivers consume via PCID_CLIENT_CHANNEL env continuation, the capabilities C1C18 (driver match, lifecycle, BAR mapping, IRQ vectors, runtime PM, AER error recovery, etc.).
  • CachyOS policy patterns: policy-layer TOML with blacklist/options/autoload, driven by the manager (not by modprobe since Red Bear has no modules).

Out of scope:

  • Adding USB / ACPI / platform buses to the device manager — those are in local/docs/USB-IMPLEMENTATION-PLAN.md and follow once the PCI manager lands.
  • Replacing pcid itself (the scheme:pci owner) — it stays the canonical PCI scheme surface, just like Linux's pci_bus_type owning /sys/bus/pci/devices/.
  • Replacing redox-driver-sys — driver-manager consumes it for the hardware-quirks surface once Q3 lands (see local/docs/QUIRKS-IMPROVEMENT-PLAN.md Task 2.1).
  • Replacing the kernel — Redox's PCI scheme is userspace; the kernel's role (memory/irq/acpi/dt/serio schemes, MMIO mapping, MSI/MSI-X vector delivery) is unchanged.

Policy constraints (binding)

Every step in this plan inherits the following constraints from local/AGENTS.md:

  1. NEVER DELETE a package, service, config, or patch. pcid-spawner stays.
  2. NEVER IGNORE a package by "ignore". driver-manager lands as additive.
  3. NEVER COMMENT OUT a service or config entry to "fix" a build.
  4. ALWAYS FIX the root cause when something breaks.
  5. The migration is operator-ratified: each phase has an explicit exit gate and is not closed until the gate is met AND human-acknowledged.

The durability rule applies: any source-tree edit during this migration is mirrored into local/patches/ or local/sources/<component>/ in the same work session. local/patches/base/ and the fork local/sources/base/ carry the changes; recipes/core/base/source/ is not the durable location.


1. Current state assessment

1.1 What pcid-spawner does today

Source: local/sources/base/drivers/pcid-spawner/src/main.rs (127 lines) Cargo: local/sources/base/drivers/pcid-spawner/Cargo.toml Recipe: recipes/core/base/drivers/pcid-spawner/recipe.toml (path-fork)

Single main() function with the following behaviour, ordered:

  1. Wait for /scheme/pci/ to appear (200 × 50ms retry, 10s total) — this was added by Red Bear patch local/patches/base/P4-pcid-spawner-pci-coordinate-env.patch alongside the PCI coordinate env vars.
  2. Load merged driver configs via config::config("pcid") — concatenates /etc/pcid.d/*.toml (rootfs) or /scheme/initfs/etc/pcid.d/*.toml (--initfs mode) into one Config struct.
  3. Iterate /scheme/pci/ directory entries. For each:
    • PciFunctionHandle::connect_by_path(&device_path) — opens the per-device channel handle in scheme:pci. The handle is the mutual-exclusion lock: pcid returns ENOLCK to any second opener. This is the only claim mechanism.
    • On ENOLCK: log debug, continue. On other errors: log error, continue. The spawner never aborts on a single bad device.
    • config.match_function(&full_device_id) — legacy matching (class → subclass → interface → vendor/device, optional multi-vendor ids map, optional device_id_range).
    • On miss: log debug, continue.
  4. Enable the PCI function (handle.enable_device()) — pcid writes the command register to enable bus mastering + memory + IO.
  5. Build Command from driver.command, resolving program either absolute or prefixed /usr/lib/drivers/<program>.
  6. Pass env vars to the child:
    • PCID_CLIENT_CHANNEL=<channel_fd> — the bincode channel FD the driver uses for PciFunctionHandle::connect_default() to reach pcid.
    • PCID_SEGMENT=<hex> — added by Red Bear P4 patch.
    • PCID_BUS=<hex> — added by Red Bear P4 patch.
    • PCID_DEVICE=<hex> — added by Red Bear P4 patch.
    • PCID_FUNCTION=<dec> — added by Red Bear P4 patch.
  7. Spawn via daemon::Daemon::spawn(command) — parent blocks until the child signals readiness. This is the driver-ready handshake and is honoured by every existing driver daemon (ahcid, e1000d, xhcid, etc.).
  8. Close the parent's copy of the channel FD.

1.2 What the existing driver-manager implements

Source root: local/recipes/system/driver-manager/source/ Cargo: local/recipes/system/driver-manager/source/Cargo.toml (Cat 1, version 0.3.1) Recipe: local/recipes/system/driver-manager/recipe.toml (template=cargo, path="source")

Five source files (src/main.rs, config.rs, scheme.rs, hotplug.rs, exec.rs) totalling ~1250 lines. Built and present at recipes/system/driver-manager/target/x86_64-unknown-redox/stage/usr/bin/driver-manager (783KB ELF, dated 2026-07-19). Binary-store artifact cached in repo/x86_64-unknown-redox/driver-manager.pkgar. NOT packaged into any current [packages] section of redbear-*.toml.

Area Status Notes
Compile Builds clean on x86_64-unknown-redox
Core abstraction redox-driver-core (Bus/Driver/DeviceManager/ProbeEvent/ManagerConfig/DriverParams/MatchTable/HotplugEvent)
PCI bus redox-driver-pci::PciBus reads /scheme/pci raw config space; class/subclass/program-if/subdevice IDs returned
TOML config loader /lib/drivers.d/*.toml (name, description, priority, command, match, depends_on)
Probe pipeline ProbeResult::Bound / NotSupported / Deferred / Fatal with retry queue
Deferred retry 🟡 30 retries × 500ms; logs deferred-retry-limit-reached and exits 0
Async probe 🟡 ManagerConfig::async_probe = true is set, but thread::spawn(...).join() is used immediately, making it actually synchronous
max_concurrent_probes 🟡 Stored as policy metadata; never enforced (all probes are serial)
Hotplug 🟡 run_hotplug_loop() polls every 2s; Bus::subscribe_hotplug() is hidden behind an unused hotplug feature flag
scheme:driver-manager Read-only /devices, /bound, /events, /devices/<pci-addr>, plus param persistence to /tmp/redbear-driver-params/<addr>/{driver,enabled}
Spawn via PCID_CLIENT_CHANNEL claim_pci_device() opens <addr>/bind (NOT channel); still passes PCID_CLIENT_CHANNEL=<fd>
Driver parameters 🟡 Driver::params() declared but driver-manager's own schema (enabled, priority) is parameter-only; runtime writes via scheme:driver-params (separate daemon local/recipes/system/driver-params)
Quirks integration 🔴 redox-driver-sys is not in the dep list; pci_has_quirk / pci_get_quirk_flags are NOT consulted
Service wiring 🔴 No 00_driver-manager.service exists; absent from all [packages] sections
Tests 🔴 Zero driver-manager tests; 12 unit tests in redox-driver-core
Documentation 🟡 No dedicated doc; mentioned in UPSTREAM-SYNC-PROCEDURE.md § "driver-manager: Deferred" and PACKAGE-BUILD-QUIRKS.md § "driver-manager Removed During Sync"

1.3 Service inventory that depends on pcid-spawner

Service definitions:

Service Mode Flag Where
00_pcid-spawner.service oneshot_async (none) local/sources/base/init.d/
40_pcid-spawner-initfs.service oneshot (blocking) --initfs local/sources/base/init.initfs.d/
/etc/init.d/00_pcid-spawner.service (override) oneshot_async (none) config/redbear-mini.toml lines 575-583
00_base.target requires_weak local/sources/base/init.d/00_base.target

Service dependencies (every service that references 00_pcid-spawner.service):

Config Service referencing it Reference role
config/redbear-mini.toml 10_evdevd.service requires_weak
config/redbear-mini.toml 20_udev-shim.service requires_weak
config/redbear-mini.toml 11 other services requires_weak
config/redbear-full.toml 10_evdevd.service requires_weak
config/redbear-full.toml redox-drm consumers requires_weak
config/redbear-greeter-services.toml redbear-greeter (seatd chain) requires_weak
config/redbear-device-services.toml explicit comment that driver-manager is deferred
config/acid.toml acid test config requires_weak
config/redoxer.toml redoxer CI config requires_weak

Migrating this dependency graph without breaking any boot path requires keeping 00_pcid-spawner.service available as a fallback through P0P2 and running both managers transiently during P3.

1.4 Configuration surfaces

Active now (legacy format):

  • config/redbear-mini.toml:500-512/etc/pcid.d/*.toml overrides (ihdgd.toml, virtio-gpud.toml, 00_text_mode_gpu_mask.toml)
  • local/config/pcid.d/intel_gpu.toml — Intel GPU match
  • local/config/pcid.d/amd_gpu.toml — AMD GPU match

Already drafted (driver-manager format, currently inert):

  • config/redbear-device-services.toml:116-490 — full set of /lib/drivers.d/*.toml:
    • 00-storage.toml (ahcid, ided, nvmed, virtio-blkd, usb-bot)
    • 10-network.toml (e1000d, rtl8168d, rtl8139d, ixgbed, virtio-netd)
    • 20-usb.toml (xhcid, ehcid, ohcid, uhcid, usbhubd)
    • 30-graphics.toml (vesad, virtio-gpud, redox-drm)
    • 40-input.toml (ps2d, usbhidd, intel-thc-hidd)
    • 50-audio.toml (ihdad, ac97d, sb16d)
    • 70-usb-class.toml (usbscsid, usbaudiod, redbear-ftdi)

Decision-needed: are these drafts correctly normalised for driver-manager's TOML schema ([driver] with match tables, priority, depends_on)? D1 verifies them. Many entries will need editing to converge on a single matching language.

1.5 Fork / source provenance

  • local/sources/base/ is the local fork of the base Redox upstream submodule. It holds BOTH drivers/pcid/ (the scheme:pci owner) AND drivers/pcid-spawner/ (the legacy spawner).
  • local/recipes/system/driver-manager/ is a local recipe (Cat 1 in-house crate), not a submodule. It does NOT duplicate upstream code; it's a fresh Red Bear creation. No submodule/driver-manager branch exists, no .gitmodules entry, no need to create one (per local/AGENTS.md § BRANCH AND SUBMODULE POLICY: "We don't create new branches/repos. We work on existing submodules first. … A new submodule is only justified when the component is large enough that submodule pinning provides real value over a tracked tree or local recipe. driver-manager satisfies none of these").
  • The 17 driver daemons under local/sources/base/drivers/{storage,net,graphics,audio,usb}/ each have pcid = { path = "../../pcid" } in their Cargo.toml. They depend on pcid_interface (a lib crate alongside pcid), NOT on the pcid-spawner binary. The runtime contract they honour is PCID_CLIENT_CHANNEL=<fd>, which driver-manager preserves. No driver-binary changes are required.

2. Cross-reference: pcid-spawner vs driver-manager vs Linux 7.1 vs CachyOS

2.1 Linux 7.1 PCI driver model surface (local/reference/linux-7.1/ at ab9de95c9)

Subsystem Linux source Capability exposed
PCI bus type drivers/pci/pci-driver.c:1726-1742 (pci_bus_type), include/linux/pci.h:1021-1154 (pci_driver + pci_device_id macros) C1: id_table + match
Probe / remove drivers/pci/pci-driver.c:473-553 (pci_device_probe / pci_device_remove / pci_device_shutdown) C2: device lifecycle
Module loading kernel/kmod.c:64-179 (__request_modulecall_modprobe) + drivers/pci/pci-driver.c:1587-1617 (pci_uevent with MODALIAS) C1: driver lookup with alias
Driver-core binding drivers/base/bus.c (bus_add_driver / bus_probe_device / device_attach / driver_attach) C2: symmetric device/driver iteration
Sysfs surface drivers/pci/pci-sysfs.c (vendor, device, class, subsystem_*, resource, config, bind, unbind, new_id, remove_id, driver_override) C1 + C2 + C11 + observability
PCIe native hotplug drivers/pci/hotplug/pciehp_core.c:185-372 (pciehp_probe + presence/attention/MRL/DLLSC handlers) C14: hotplug events
AER drivers/pci/pcie/aer.c:1203-1280 (aer_recover_work_func + pcie_do_recovery) + include/linux/pcieport_if.h (pci_error_handlers) C13: error recovery
Runtime PM drivers/pci/pci-driver.c:1314-1440 (pci_pm_runtime_* + pci_dev_pm_ops) C9 + C18: suspend/resume
IOMMU / DMA drivers/pci/pci-driver.c:1668-1711 (pci_dma_configure) + drivers/iommu/iommu.c (iommu_device_use_default_domain) C15: DMA / IOMMU
MSI / MSI-X drivers/pci/msi/api.c:205-264 (pci_alloc_irq_vectors_affinity) + include/linux/pci.h:1166-1168 (pci_irq_vector) C7 + C8: vector allocation
BAR / MMIO drivers/pci/pci.c:2120-238, 3916-4172 (pci_enable_device / pci_request_regions / pci_set_master / pci_ioremap_bar) C3 + C4 + C5 + C6: device + bar map
Power states include/linux/pci.h:183-188 (PCI_D0..PCI_D3cold) + pci.h pci_set_power_state C9: power state control
Capabilities search drivers/pci/pci.c (pci_find_capability / pci_find_ext_capability) C16: capability iteration

Synthesis (cross-reference pci_driverDriver trait ↔ driver-manager):

Linux pci_driver member Linux function Redox current (redox-driver-core) Redox pcid-spawner path Gap to fill
.probe pci_device_probe Driver::probe(&DeviceInfo) -> ProbeResult (deferred to child spawn) async + retry + dependency-aware
.remove pci_device_remove Driver::remove(&DeviceInfo) -> Result<(), DriverError> (no remove path at all) full lifecycle
.suspend / .resume pci_pm_runtime_* Driver::suspend() / resume() (default Ok) (no path) graceful shutdown + wake
.id_table pci_match_device Driver::match_table() -> &[DriverMatch] legacy match_function() unify on DriverMatch
.shutdown pci_device_shutdown (not in trait) (no path) add to trait or handle via systemd
.err_handler pcie_do_recovery (not in trait) (no path) add Driver::on_error()
.driver_managed_dma iommu_device_use_default_domain (not in trait) (no path) add Driver::dma_managed()

2.2 CachyOS pattern surface (CachyOS-Settings master)

Pattern CachyOS location Red Bear equivalent
udev rule w/ subsystem match + sysfs write usr/lib/udev/rules.d/60-ioschedulers.rules (HDD/SSD/NVMe scheduler assignment) driver-manager scheme event set_io_scheduler(dev, "bfq"|"mq-deadline"|"kyber")
udev rule w/ bind/unbind lifecycle usr/lib/udev/rules.d/71-nvidia.rules (NVIDIA PM lifecycle) driver-manager register_add_event + register_remove_event matching on vendor + class
Cross-subsystem reaction (battery state → audio params) usr/lib/udev/rules.d/20-audio-pm.rules (snd_hda_intel powersave) driver-manager event filter {AC=>BATT} → action set_param(driver, "power_save", value)
Sentinel-based idempotency /run/udev/snd-hda-intel-powersave driver-manager in-memory init_done: BTreeSet<(driver_name, param_set)>
modprobe.d blacklist usr/lib/modprobe.d/blacklist.conf (blacklist iTCO_wdt) /etc/driver-manager.d/00-blacklist.conf: [[blacklist]] module = "iTCO_wdt"
modprobe.d options usr/lib/modprobe.d/amdgpu.conf (options amdgpu si_support=1) /etc/driver-manager.d/50-amdgpu.conf: [amdgpu.params] si_support = true
modules-load.d usr/lib/modules-load.d/ntsync.conf (ntsync) /etc/driver-manager.d/autoload.d/ntsync.conf: module = "ntsync"
Driver mutual exclusion (two drivers claim same PCI IDs) usr/lib/modprobe.d/amdgpu.conf (amdgpu SI/CIK ↔ radeon SI/CIK off) driver-manager priority + explicit exclusive_with field
Path-triggered (config change) service activation usr/lib/udev/rules.d/85-iw-regulatory.rules + cachyos-iw-set-regdomain.{path,service} driver-manager + scheme watcher over /etc/driver-manager.d/
Ramdisk driver manifest (mkinitcpio hook ordering) linux-cachyos preset (microcode/modconf/kms/block/filesystems/fsck) /usr/lib/driver-manager.d/initfs.manifest (ramdisk_drivers = ["ahci", "nvme", "redoxfs"], ordered)
Cold-boot parameter injection (immutable module params) modprobe.d/options ... driver-manager set_pre_spawn_param(driver, param, value) recorded in BOOT_TIMELINE
Curated-policy-as-a-package (cachyos-settings) cachyos-settings ARCH package redbear-driver-policy local recipe (or redbear-meta extension)

2.3 Capability table — what a full driver-manager must provide (C1C18)

Note: the "Priority" column uses P0/P1/P2 as capability-priority labelsnot phase references. The P0/P1/P2 capability priorities pre-date the § 5 D/C phase restructure. Capability priorities are:

  • P0 (capability priority) = blocker for desktop path
  • P1 (capability priority) = desktop-ready
  • P2 (capability priority) = production-grade

These priorities map onto specific phases in § 5.1 D-Phase (P0 set lands in D1; P1 set lands in D2/D3; P2 set lands in D2/D4).

# Capability Linux equivalent driver-manager API Priority Notes
C1 ID-table match + dynamic ID add pci_match_device + sysfs new_id / remove_id DeviceManager.register_driver() + match_table() + add_dynid() P0 Already present in redox-driver-core. add_dynid not yet exposed in driver-manager; D1 must wire it
C2 Device lifecycle (probe/remove) pci_device_probe / pci_device_remove Driver::probe(&DeviceInfo) + Driver::remove(&DeviceInfo) P0 Already present. driver-manager calls Driver::probe only after claim + dependency check
C3 Enable / disable device pci_enable_device / pci_disable_device enable_device(pci_addr) → pcid EnableDevice request P0 driver-manager must call pcid EnableDevice BEFORE spawning the child
C4 BAR request/release pci_request_regions / pci_release_regions (implicit in claim_pci_device) P0 driver-manager opens <addr>/bind — confirm bind vs channel semantics with pcid
C5 BAR map / unmap pci_ioremap_bar / pci_iounmap child scheme:memory/physical@<wc|wb|uc> via redox_driver_sys::pci::PciDevice::map_bar P0 Not a manager task — child uses redox-driver-sys directly
C6 Bus master on/off pci_set_master / pci_clear_master set_bus_master(pci_addr, true) P0 driver-manager sets on probe, clears on remove
C7 Allocate IRQ vectors pci_alloc_irq_vectors pci_alloc_vectors(pci_addr, min, max, flags) -> vector_count P0 driver-manager proposes; child daemon allocates via PcidClient
C8 Resolve vector → IRQ handle pci_irq_vector pci_vector_handle(pci_addr, index) -> scheme:irq fd P0 child uses scheme:irq directly
C9 Runtime PM pci_pm_runtime_* set_power_state(pci_addr, D0|D3hot|D3cold) P1 pcid SetPowerState request exists; driver-manager exposes it (lands in D2)
C10 Save/restore config space pci_save_state / pci_restore_state child uses PcidClient::read_config() P1 not a manager concern
C11 Driver override sysfs driver_override set_driver_override(pci_addr, driver_name) P1 driver-manager exposes it as a scheme op (writes pci_addr/override) — D2
C12 Config space read/write pci_read_config_* child uses PcidClient::read_config() / write_config() P0 not a manager concern
C13 AER error recovery pci_error_handlers + pcie_do_recovery Driver::on_error(error_kind) -> RecoveryAction P2 Lands in D2 (AER recovery is part of the modern technology surface)
C14 Hotplug events (PDC / DLLSC / MRL) pciehp_* manager.subscribe_hotplug() -> HotplugEvent P1 Requires event-driven scheme:pci surface; D3 delivers event-driven hotplug
C15 DMA mask / IOMMU dma_set_mask + iommu_device_use_default_domain set_dma_mask(pci_addr, bits) + iommu_assign_group(pci_addr) P2 iommu daemon present (local/recipes/system/iommu/); wiring lands in D2 (modern tech surface)
C16 Find capabilities pci_find_capability / pci_find_ext_capability child uses redox_driver_sys::pci::PciDevice::find_capability P0 not a manager concern
C17 INTx on/off pci_intx child via PcidClient P1 not a manager concern
C18 System PM (suspend/resume) pci_pm_* Driver::suspend() / resume() callbacks via manager P2 driver-manager keeps a registry of bound drivers for the systemd-supervisor to call; D2

Source-of-truth invariant: C7 (vector allocation) is implemented inside pcid itself, not in driver-manager. driver-manager's role is to (a) call enable_device through pcid before spawning, (b) hand the channel FD to the child, and (c) call remove (which clears bus master + sends ULP/cleanup requests) when a device disappears from hotplug. The same split holds for C5, C12, C16, C17: those are the child's contract via redox-driver-sys.

2.4 boot-timeline and observability alignment

Note: the "Priority" column reuses P0/P1/P2 as capability-priority labels (the same priority ladder used in § 2.3) — not phase references. Capacity deliveries for these priorities land in the § 5 D-Phase track (P0 set in D1; P1 set in D2/D3; P2 set in D4). AER-aware reset handling (P1 here) is part of D2's modern-technology surface.

Linux surface driver-manager equivalent Status Priority
dmesg pci ... BAR X set to ... BOOT_TIMELINE_PATH = /tmp/redbear-boot-timeline.json (already present) exists (D0)
journalctl -k scheme:driver-manager:/events (read-only ring buffer, 256 lines) exists (D0)
lspci -v scheme:driver-manager:/devices/<addr> (vendor / device / class / driver / enabled=true) 🟡 partial P0
lspci -vv -s ... + lspci -xxx -s ... not exposed not yet P0
find /sys/bus/pci/devices -name reset not exposed not yet P1 — needed for AER + reboot (D2)
pci=nomsi kernel cmdline REDBEAR_DRIVER_MANAGER_FLAGS=disable_msi env not yet P1
pci=realloc= not exposed not yet P2
lspci -tv (tree) scheme:driver-manager:/tree (planned) not yet P2

3. Target architecture

3.1 Process model (post-migration)

                    ┌─────────────────────────────────────────────┐
                    │            DRIVER-MANAGER (PID 1 child)     │
                    │  ▸ Subscribes to /scheme/pci as a client   │
                    │  ▸ Owns Driver trait objects from TOML      │
                    │  ▸ Maintains Bus → Device → Driver graph   │
                    │  ▸ Claims devices via <addr>/bind          │
                    │  ▸ Spawns driver daemons with:             │
                    │    PCID_CLIENT_CHANNEL=<fd>                │
                    │    PCID_SEGMENT / PCID_BUS / PCID_DEVICE   │
                    │    PCID_FUNCTION  (Red Bear P4 contract)   │
                    │  ▸ Registers scheme:driver-manager         │
                    │  ▸ Writes /tmp/redbear-driver-params/...   │
                    │  ▸ Writes /tmp/redbear-boot-timeline.json  │
                    │  ▸ On hotplug (P1): detects add/remove     │
                    │  ▸ On AER (P5): invokes error handler     │
                    └───────────────────┬─────────────────────────┘
                                        │
            ┌───────────────────────────┼──────────────────────────┐
            ▼                           ▼                          ▼
   ┌────────────────────┐   ┌────────────────────┐    ┌────────────────────┐
   │       PCID         │   │   SCHEME:PCI       │    │ REDOX-DRIVER-SYS   │
   │  (Canonical PCI    │   │  (per-device       │    │  (registered       │
   │   scheme owner)    │◀──│   channel+bind+    │    │   quirk surface)   │
   │                    │   │   config+feature)  │    │  /scheme:driver-sys│
   └─────────┬──────────┘   └─────────┬──────────┘    └────────────────────┘
             │                        │
             │  /scheme/memory        │
             │  /scheme/irq           │
             │  /scheme:acpi          │
             │  /scheme/iommu (P5)    │
             ▼                        ▼
       ───────────  KERNEL  ───────────

3.2 New component list

Component Lives at Source-of-truth Phase
driver-manager daemon local/recipes/system/driver-manager/source/ local recipe (Cat 1) built in D0D5, enabled at C0
driver-manager-config package local/recipes/system/driver-manager-config/ (NEW) local recipe (Meta) D4 (policy layer)
/etc/driver-manager.d/*.toml configs NEW dir, shipped by driver-manager-config policy D4
/lib/drivers.d/*.toml NEW dir, per-config files match tables D1 (format); D4 (content)
00_driver-manager.service local/sources/base/init.d/ service C0 (created dormant); C3 (active)
40_driver-manager-initfs.service local/sources/base/init.initfs.d/ service C0 (dormant); C2 (active blocking)
local/recipes/system/driver-params already exists; extends to consume scheme:driver-manager rather than its own bound-text-parsing observer C1 (switch over)
redbear-driver-policy package local/recipes/system/redbear-driver-policy/ (NEW) curated package D4 (created); C3 (packaged)

3.3 What changes for pcid-spawner (NOT deleted, demoted)

The v1.1 D/C phase restructure changes pcid-spawner's role as follows:

Track / Phase pcid-spawner state
D-phase (D0D5) No change. pcid-spawner remains the live boot path. driver-manager is being built locally but is NOT shipped, NOT packaged, NOT enabled. The boot path is identical to baseline.
C0 00_pcid-spawner.service gains ConditionPathExists=!/etc/driver-manager.d/disabled. Service is dormant by default.
C1 driver-manager runs in --observe mode (writes BOOT_TIMELINE, does NOT spawn). pcid-spawner is still the actual spawner.
C2 40_driver-manager-initfs.service becomes oneshot blocking in initfs; pcid-spawner initfs service becomes fallback only via ConditionPathExists.
C3 00_driver-manager.service becomes the primary rootfs spawner. 00_pcid-spawner.service is retained as fallback only (idem for initfs variant).
C4 pcid-spawner source tree receives a final commit on the submodule/base branch documenting the maintenance-mode status. Never deleted.

3.4 Wire-level contracts that MUST stay invariant

Contract Description Invariant
C-ENV-1 PCID_CLIENT_CHANNEL=<fd> is passed to every spawned driver daemon Preserved by config.rs::probe() already
C-ENV-2 PCID_SEGMENT/PCID_BUS/PCID_DEVICE/PCID_FUNCTION env vars (Red Bear P4) Preserved — driver-manager's probe path must add them
C-ENV-3 Program resolution: absolute OR /usr/lib/drivers/<name> Preserved — same prefix logic moves to driver-manager
C-CHAN-1 Per-device channel open in scheme:pci yields mutual-exclusion (ENOLCK to second opener) Not the responsibility of driver-manager — that's pcid. driver-manager must use bind (NOT channel) so multi-driver retry can re-probe without consuming the lock. Confirm with pcid that bind is also exclusive, or document the asymmetry.
C-CHAN-2 Drivers call PciFunctionHandle::connect_default() and get a working bincode channel via the FD Continues unchanged
C-SVC-1 Every service that previously requires_weak=00_pcid-spawner.service gains requires_weak=00_driver-manager.service as an alternative. Driver-manager has requires_weak=00_pcid-spawner.service for fallback coordination. Provides fallback-safety
C-DAEMON-1 daemon::Daemon::spawn() blocks parent on child ready driver-manager must use the same primitive to preserve the boot-order guarantee — ahcid/nvmed up before redoxfs mounts
C-RECIPE-1 recipes/core/base/drivers/pcid-spawner/recipe.toml keeps path = "../../../local/sources/base/drivers/pcid-spawner" Never changes
C-SCHEME-1 scheme:driver-manager exposes: /devices, /devices/<addr>, /bound, /events (read-only) Already present
C-PARAM-1 driver-params reads from /scheme/driver-manager/bound (instead of its current text-parsing of the bound file) C1 wiring

3.5 Module / crate dependencies (target state)

recipes/system/driver-manager/source/Cargo.toml  ─── D0 plus phase-by-phase additions
├── redox-driver-core           (already: local/recipes/drivers/redox-driver-core)
├── redox-driver-pci           (already: local/recipes/drivers/redox-driver-pci)
├── redox-driver-sys           (NEW dep  ─ added at D4; previously optional, now required)
├── pcid_interface             (already: local/sources/base/drivers/pcid)
├── redox-scheme               (already: local/sources/redox-scheme)
├── redox_syscall              (already: local/sources/syscall, features=["std"])
├── log, toml, serde           (already)
├── event-stream               (NEW in D3 — for hotplug event consumption)
├── bitflags                   (NEW in D2 — for CapabilityFlag aggregation)
└── [patch.crates-io]          (already: redox_syscall, libredox, redox-scheme)

pcid-spawner Cargo.toml is untouched (it stays in the base submodule fork for fallback). No retroactive changes to daemon::Daemon::spawn, PciFunctionHandle::connect_default, or any of the 17 driver daemons.


4. Critical risk register

# Risk Severity Mitigation
R1 Double-spawn race: driver-manager and pcid-spawner both spawn the same driver daemon 🔴 BLOCKING C1 sequencing: driver-manager runs only in --observe mode first. The actual spawn is gated by spawn_enabled flag set by the C1 exit gate. 00_driver-manager.service is dormant in C0; observable in C1; primary in C3.
R2 Driver daemon crashes after spawn, no one restarts it 🔴 BLOCKING driver-manager persists bound_devices map to /tmp/redbear-driver-params/. On WAIT_FOR_REAPPEAR per-driver (delivered in D2) the manager retries after a 5s backoff. systemd Restart= on the driver service files provides the surface-process fallback (D4).
R3 The match table migration misses a vendor/device pair 🔴 BLOCKING D1 adds "no-match ↔ spin in driver-manager, no spawn" tests for the existing 17 drivers. C1 runs both managers side-by-side and emits unbound_device_addr=<addr> lines to BOOT_TIMELINE for any device the new manager misses but pcid-spawner bound.
R4 The bind vs channel claim differs in exclusivity 🟡 HIGH D1 step is a QEMU test that opens bind from one driver and channel from another; verifies the latter gets ENOLCK. Document the asymmetry.
R5 Initfs switchroot breaks (storage drivers must be ready before redoxfs mounts) 🔴 BLOCKING C2 keeps 40_pcid-spawner-initfs.service available (via ConditionPathExists). 40_driver-manager-initfs.service is added in observation mode at C0 and only switches on at C2 once the storage path passes on at least 3 hardware configs (QEMU virtio + AMD NVMe + Intel SATA).
R6 redox-driver-sys quirks not consulted during spawn decisions 🟡 MEDIUM D4 phase. Until then, the kernel-side MSI/MSI-X fallback in pcid remains authoritative. No regression on bare metal.
R7 Atomic patch governance failure: live source edit goes unmirrored 🟡 (procedural) Every source edit during this plan is committed to the submodule/base branch (for pcid-spawner edits) or as commits within local/recipes/system/driver-manager/source/ (which is a local-recipe tree, not a fetched source tree). Per local/AGENTS.md DURABILITY POLICY.
R8 The new scheme:driver-manager collides with scheme:driver-params 🟡 MEDIUM C-PARAM-1 above resolves this: driver-params becomes a thin observer over scheme:driver-manager:/bound, no separate parsing path. Wired at C1.
R9 The migration leaves the repo in a state that cannot fall back 🔴 BLOCKING During D-phase, no boot path is affected (driver-manager is not in the system). During C-phase, both managers may run; pcid-spawner is the fallback at every cutover step (ConditionPathExists=!/etc/driver-manager.d/disabled gates it). At no phase is the boot path single-point-of-failure.
R10 The TOML match-table migration produces a silent NO-OP for an edge device (e.g., ID 0x1234:0x5678 not in any entry → driver never binds) 🟡 HIGH D1 implements missing_match = warn so any unresolved match is logged. QEMU tests with the 17 known drivers verify each entry before C3.
R11 The redox-driver-core DeviceManager::probe_device locks the entire manager mutex for the duration of a probe, blocking retry_deferred for slow drivers 🟡 MEDIUM D2 introduces per-driver Mutex<DriverState> for finer-grained concurrency; manager's outer mutex held only during dispatch.
R12 Device hot-add during switchroot causes race with pcid (which may re-enumerate) 🟡 MEDIUM Hotplug is off during initfs → rootfs transition. driver-manager starts in --hotplug=off until switchroot completes.
R13 D-phase work produces a stub or workaround instead of comprehensive code 🔴 BLOCKING local/scripts/driver-manager-audit-no-stubs.py (D4 deliverable) is the formal gatekeeper. Static analysis + QEMU integration test. Any D-phase work that violates § 0.5 fails the D4 audit and blocks D5 ratification. No partial-credit D5 exit.
R14 driver-manager enters a boot path before D5 ratification (i.e., someone packages it earlier than planned) 🔴 BLOCKING Build-system guard: local/scripts/build-redbear.sh and the cookbook CI refuse any commit that adds driver-manager to [packages] in config/redbear-*.toml during D-phase. Documented in § 0.6.

Out-of-scope (deferred to OTHER plans)

  • USB / ACPI / platform buses → local/docs/USB-IMPLEMENTATION-PLAN.md, local/docs/ACPI-IMPROVEMENT-PLAN.md
  • GPU render / DRM completion → local/docs/DRM-MODERNIZATION-EXECUTION-PLAN.md
  • Wi-Fi / Bluetooth → local/docs/WIFI-IMPLEMENTATION-PLAN.md, BLUETOOTH-IMPLEMENTATION-PLAN.md
  • IRQ / MSI-X quality → local/docs/IRQ-AND-LOWLEVEL-CONTROLLERS-ENHANCEMENT-PLAN.md
  • IOMMU runtime proof → still QEMU-only per HardWARE matrix
  • Replacement of pcid (the scheme:pci owner) — far future, no decision today

5. Phased migration plan

The migration has two tracks operating sequentially, not interleaved:

  • D-Phase (Parallel Development). driver-manager is being built; pcid-spawner remains the live boot system. No boot path is affected. This phase starts at D0 (current state) and continues through D5 (feature-complete gate). The team's parallel development work lives here.
  • C-Phase (Cutover & Validation). driver-manager is fully built; the boot path is switched over from pcid-spawner to driver-manager in stages. C0 starts only after D5 + operator ratification.

Authority: the § 0.6 Parallel Development constraint is binding. driver-manager does NOT enter any boot path until D5 ratifies. The original v1.0 P0P6 dual-mode strategy is folded into the C-phases.

5.1 D-Phase — Parallel Development

State during D-Phase:

  • pcid-spawner is the boot path in every redbear-*.toml.
  • driver-manager is built locally (committed to local/recipes/system/driver-manager/source/) but NOT shipped.
  • driver-manager has no 00_driver-manager.service.
  • No files in /etc/driver-manager.d/ are read by the live system.
  • No [packages] entry contains driver-manager.
  • The team's work is recorded in commits to the local recipe source.

Phase D0 — Foundation (current state)

Status (2026-07-20): partially complete.

What exists:

  • redox-driver-core framework: Bus trait, Driver trait, DeviceManager, DriverMatch, DriverParams, ProbeEvent, ProbeResult. Compiled with 12 unit tests.
  • redox-driver-pci::PciBus reads /scheme/pci/, parses PCI config space, returns DeviceInfo with vendor/device/class/subclass/prog_if/revision/ subsystem IDs.
  • local/recipes/system/driver-manager/source/src/{main.rs,config.rs,scheme.rs,hotplug.rs,exec.rs} — 1250 lines compiling to a 783KB ELF.
  • scheme:driver-manager registered with /devices, /bound, /events, /devices/<addr> paths (read-only).
  • Boot timeline JSON at /tmp/redbear-boot-timeline.json.

What does NOT yet exist (D1D5 work):

  • Linux 7.x capability bridge: C9, C11, C13, C14, C15, C17, C18 are absent
  • Modern technology surface integration (SMP-aware concurrent probe, S/P-state hooks, runtime PM, AER)
  • Event-driven hotplug (current code polls every 2s)
  • Quirk integration with redox-driver-sys (no redox-driver-sys import in source/Cargo.toml)
  • Format-coexistence TOML loader (current loader only accepts new [[driver]] format)

Exit criteria for D0:

  1. cargo build --release -p driver-manager clean.
  2. cargo test -p redox-driver-core 12/12 green.
  3. local/recipes/system/driver-manager/target/x86_64-unknown-redox/stage/usr/bin/driver-manager exists.
  4. No 00_driver-manager.service in any init.d.
  5. No driver-manager = {} in any [packages] section.

Phase D1 — Linux 7.x capability bridge (target: 610 weeks)

Preconditions: D0 exit criteria met.

Goal: Implement every P0 capability from § 2.3 (C1, C2, C3, C4, C5, C6, C7, C8, C12, C16).

Deliverables:

  • redox-driver-core::driver::Driver trait gains full suspend() / resume() / on_error() / params() implementations with concrete behaviour (not stubs — see § 0.5).
  • redox-driver-core::bus::Bus trait gains event-driven subscribe_hotplug() implementation in PciBus.
  • local/recipes/system/driver-manager/src/manager-probe.rs (new module) handles the SpawnDecision committee (C2', C3, C4, C6).
  • Format-coexistence TOML loader accepting both [drivers] (legacy pcid-spawner) and [[driver]] (driver-manager) formats from the same directory tree.
  • New test script local/scripts/test-driver-manager-parity.sh (used in C1, but drafted here).

Exit criteria for D1:

  1. Every P0 capability of C1C18 is implemented and unit-tested.
  2. local/scripts/test-driver-manager-parity.sh returns identical bound sets under both formats.
  3. Integration test (QEMU + all 17 drivers) shows driver-manager can shadow pcid-spawner exactly.

Phase D2 — Modern technology surface (target: 812 weeks)

Preconditions: D1 exit criteria met.

Goal: Integrate SMP-aware concurrent probe, C/P-state coordination, runtime PM hooks, IOMMU groups, MSI-X vector allocation, AER recovery (see § 0.4 for the full tech surface).

Deliverables:

  • redox-driver-core::manager::DeviceManager::probe_device becomes truly concurrent (std::thread::scope or rayon, max_concurrent_probes enforced).
  • MSI-X vector allocation with per-vector fds exposed via redox-driver-sys::irq::MsixTable.
  • Per-driver P-state advisory publisher (interacts with cpufreqd).
  • C-state coordination hook with cpufreqd / thermald.
  • IOMMU group registration via local/recipes/system/iommu/.
  • D-state transitions (D0 ↔ D3hot ↔ D0) through pcid's SetPowerState request.

Exit criteria for D2:

  1. Concurrent probe dispatch verified (max_concurrent_probes = 4 shows 4-way parallelism in QEMU timings).
  2. Per-driver P-state advisory verified on real AMD/Intel hardware.
  3. IOMMU-group-aware binding demonstrated on at least one QEMU + vfio-passthrough run.
  4. Runtime PM suspend/resume callback chain verified.

Phase D3 — Hotplug event-driven (target: 46 weeks)

Preconditions: D2 exit criteria met.

Goal: Replace polling-based hotplug with event-driven subscription.

Deliverables:

  • Bus::subscribe_hotplug() returns HotplugSubscription mapping to a real event fd (via Bus::poll_hotplug_events() or equivalent).
  • PciBus consumes /scheme/pci/events (requires pcid scheme event delivery — feature request to pcid maintainer).
  • Manager::hotplug_loop() becomes event-driven, removing the 2-second poll entirely.

Exit criteria for D3:

  1. Hotplug event arrival latency < 200 ms on QEMU synthetic add/remove.
  2. Real-hardware hotplug (PCIe Native or USB) verified on at least one AMD and one Intel bare-metal target.

Phase D4 — Quirk integration + comprehensive audit (target: 68 weeks)

Preconditions: D3 exit criteria met.

Goal: Wire redox-driver-sys::PciQuirkFlags into bind/remove decisions; complete feature audit confirming § 0.5 compliance.

Deliverables:

  • local/recipes/system/driver-manager/source/Cargo.toml adds redox-driver-sys as path dep.
  • manager-probe.rs consults PciQuirkFlags::NO_MSIX, NO_PME, NEED_FIRMWARE, DISABLE_ACCEL, etc., during spawn decisions.
  • Audit script local/scripts/driver-manager-audit-no-stubs.py runs against the source tree and confirms: every public trait method has a concrete implementation, no unimplemented!(), no todo!(), no #[allow(dead_code)] for production code paths, no Ok(()) defaults in trait methods that have a real responsibility (per § 0.5 matrix).
  • Quirk policy delivered: /etc/driver-manager.d/{00-blacklist.conf, 50-amdgpu.toml,autoload.d/ntsync.conf} patterns work as designed.

Exit criteria for D4:

  1. driver-manager-audit-no-stubs.py reports zero violations.
  2. Quirk-driven spawn decisions match expected behaviour (e.g., DISABLE_ACCEL causes redox-drm --no-render to be invoked).
  3. Hardware-validation-matrix AMD Threadripper + Intel Alder Lake both pass.

Phase D5 — Feature-complete gate (audit before cutover)

Preconditions: D4 exit criteria met, operator ratification.

Goal: Formal declaration that driver-manager is feature-complete and ready to cut over.

Deliverables:

  • Audit document local/docs/evidence/driver-manager/D5-AUDIT.md listing every C1C18 capability with status ( Production / 🟡 Build-grade / 🔴 Not Implemented).
  • Updated local/docs/HARDWARE-VALIDATION-MATRIX.md with driver-manager rows.
  • This document's Last reviewed line updated to the D5 completion date.
  • Operator's written ratification (chat log, email, or commit message).

Exit criteria for D5:

  1. Every entry on the C1C18 table is at least 🟡 Build-grade.
  2. The § 0.5 no-stub audit is clean (audit script returns 0).
  3. Hardware validation matrix passes on at least one AMD and one Intel profile with at least 3 driver categories each (storage, network, GPU).
  4. The § 0.2 success criteria 16 are met (criteria 710 are C-phase criteria).
  5. Operator has ratified in writing.

At this point, the D-phase work is OVER. The C-phase begins.

5.2 C-Phase — Cutover & Validation

The C-phase begins only after D5 ratifies. The cutover is sequential, gated, and operator-ratified at every phase boundary. The cutover does NOT require pcid-spawner to be removed — it stays as a ConditionPathExists fallback.

Phase C0 — Service wiring (dormant service file)

Preconditions: D5 complete.

Goal: Add the dormant service file and [packages] entry. Driver-manager remains inactive.

Deliverables:

  • local/sources/base/init.d/00_driver-manager.service (NEW, dormant by default — never auto-starts).
  • local/sources/base/init.initfs.d/40_driver-manager-initfs.service (NEW, dormant by default).
  • local/sources/base/init.d/00_pcid-spawner.service gains ConditionPathExists=!/etc/driver-manager.d/disabled (auto-skip when driver-manager is operational; remains the actual spawner in C0).
  • config/redbear-{mini,full,grub,device-services,greeter-services}.toml add driver-manager = {} to [packages].
  • [packages] removal of pcid-spawner does NOT happen in C0.

Acceptance test:

[ BOOT ] init: 00_pcid-spawner.service running
[ BOOT ] init: 00_driver-manager.service skipped (dormant)
[ PASS ] C0: pcid-spawner still spawns; driver-manager binary present but inactive

Exit criteria for C0:

  1. ISO boots identically to pre-C0 baseline.
  2. make lint-config clean.
  3. scripts/validate-collision-log.sh clean.
  4. driver-manager-audit-no-stubs.py still clean.

Phase C1 — Dual-mode observation

Preconditions: C0 exit criteria met.

Goal: driver-manager runs in --observe mode (no spawn). Both managers see the same devices. Parity confirmed before any actual spawn.

Deliverables:

  • 00_driver-manager.service runs in --observe mode (writes BOOT_TIMELINE, no spawn).
  • 00_pcid-spawner.service is still the actual spawner.
  • Both managers write parity data to their BOOT_TIMELINE files.
  • local/scripts/test-driver-manager-parity.sh runs as a CI gate.

Acceptance test:

[ BOOT ] driver-manager: enumerate begin (observe)
[ BOOT ] driver-manager: enumeration complete: 17 bound (observe), 0 deferred
[ BOOT ] pcid-spawner: spawn e1000d for 0000:00:03.0
[ BOOT ] driver-manager: 17/17 binds agree with pcid-spawner
[ BOOT ] driver-manager: BOOT_TIMELINE written
[ PASS ] C1: parity clean

Exit criteria for C1:

  1. test-driver-manager-parity.sh clean in 5 back-to-back QEMU runs.
  2. Real-hardware parity verified on AMD Threadripper + Intel Alder Lake.
  3. Both managers' BOOT_TIMELINE files match.

Phase C2 — Initfs switchover

Preconditions: C1 exit criteria met, operator ratification.

Goal: driver-manager becomes the initfs spawner (storage drivers).

Deliverables:

  • 40_driver-manager-initfs.service becomes oneshot (blocking) and replaces 40_pcid-spawner-initfs.service in initfs.
  • pcid-spawner initfs service moves to ConditionPathExists=!/etc/driver-manager.d/initfs-active fallback.
  • local/scripts/test-driver-manager-initfs.sh clean.

Acceptance test:

[ INITFS ] driver-manager-initfs: storage drivers ready (ahcid/nvmed/virtio-blkd/ided)
[ INITFS ] redoxfs: mount /dev/redoxfs /scheme/root ✓
[ INITFS ] switchroot: /usr loaded
[ PASS ] C2: initfs path via driver-manager

Exit criteria for C2:

  1. Initfs-only QEMU run completes with driver-manager and the switchroot happens within 5 s.
  2. AHCI + NVMe + virtio-blkd paths tested on at least one AMD and one Intel system.
  3. pcid-spawner-initfs fallback can be activated by deleting /etc/driver-manager.d/initfs-active, and the boot still completes.

Phase C3 — Rootfs switchover

Preconditions: C2 exit criteria met, operator ratification.

Goal: driver-manager becomes the primary rootfs spawner.

Deliverables:

  • 00_driver-manager.service becomes the primary rootfs spawner.
  • 00_pcid-spawner.service is retained as fallback only.
  • local/scripts/test-driver-manager-active.sh runs end-to-end.
  • driver-params switches to consuming scheme:driver-manager:/bound.

Acceptance test:

[ BOOT ] driver-manager: registered scheme:driver-manager
[ BOOT ] driver-manager: load_all: 7 config files, 17 drivers registered
[ BOOT ] driver-manager: enumeration complete: 17 bound, 0 deferred
[ BOOT ] driver-manager: hotplug: starting event loop (event-driven)
[ PASS ] C3: driver-manager is the active rootfs spawner

Exit criteria for C3:

  1. test-driver-manager-active.sh clean in 5 back-to-back QEMU runs.
  2. driver-params via scheme:driver-manager produces correct driver list.
  3. parity test (C1's) keeps reporting identical binds.

Phase C4 — Operator-ratified production cutover

Preconditions: C3 exit criteria met, operator ratification, two-week soak, three hardware reboots with identical driver-bound sets.

Goal: pcid-spawner moves to maintenance-mode fallback. Status rows update.

Deliverables:

  • pcid-spawner source tree receives a final commit on submodule/base documenting the maintenance-mode status.
  • local/docs/UPSTREAM-SYNC-PROCEDURE.md § "driver-manager: Deferred" replaced with "driver-manager: production".
  • README.md status row updates.
  • local/AGENTS.md § PLANNING NOTES pointer updates.
  • Inline deferred comments in config/redbear-mini.toml:31 and config/redbear-device-services.toml:9-13 removed.

Exit criteria for C4:

  1. Two-week soak completes with no ConditionPathExists guard firing.
  2. Three consecutive bare-metal reboots produce identical driver-bound sets.
  3. Hardware validation matrix shows parity or improvement on every row.
  4. Operator ratification documented in local/docs/evidence/driver-manager/C4-RATIFICATION.md.

At no point is pcid-spawner DELETED. It moves to "always-shipped, on-disk fallback" alongside 00_driver-manager.service.


6. Per-phase dependency diagram

The D-phase and C-phase tracks are sequential under § 0.6's parallel development constraint:

   D-PHASE: Parallel Development                   C-PHASE: Cutover & Validation
   (driver-manager being built;                    (driver-manager enabled;
    pcid-spawner is the live system)                pcid-spawner demoted to fallback)

   D0 ─► D1 ─► D2 ─► D3 ─► D4 ─► D5  ─── operator ratification + feature-complete gate ───  C0 ─► C1 ─► C2 ─► C3 ─► C4
   │      │     │     │     │     │                                                           │     │     │     │     │
   ▼      ▼     ▼     ▼     ▼     ▼                                                           ▼     ▼     ▼     ▼     ▼
  fnd    cap   tech  hp    quk   audit                                                       svc   obs   ifs   rfs   prod
  frame bridge face  ev    int   (no stubs)                                                  wir   dual  sw    sw    cut
  present      +PM    ent-  gra-  + HW validate                                              e    mode  itc   itc   over
              +AER   drive ted   dom                                                         dor          ove   ove   (op
              +IOM                                                                       (dor           r    r    era
              MU                                                                          man           (do  (do    tor
              +MS                                                                       t)             t)   t)    ra
              I-X                                                                                                  tif
                                                                                                                    ied
                                                                                                                    )

                  │                                                                           │
                  └──── During D-phase, pcid-spawner remains the boot path.            During C-phase, both
                       No boot path is changed.                                             managers may run; pcid-spawner
                                                                                            is the fallback at every cutover step.

Phase key:

  • D0: Foundation (current state)
  • D1: Linux 7.x capability bridge (C1C18 P0 set)
  • D2: Modern technology surface (SMP, S/P states, runtime PM, IOMMU, AER, MSI-X)
  • D3: Hotplug (event-driven)
  • D4: Quirk integration + comprehensive audit (no stubs)
  • D5: Feature-complete gate (operator ratification)
  • C0: Service wiring (dormant service file)
  • C1: Dual-mode observation
  • C2: Initfs switchover
  • C3: Rootfs switchover
  • C4: Operator-ratified production cutover

The workstream structure deliberately mirrors local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md (Phase 15) and local/docs/DRM-MODERNIZATION-EXECUTION-PLAN.md (Workstream AE) to keep the project's planning grammar consistent.


7. Test scripts (local/scripts/)

All scripts land in local/scripts/ per project convention and follow the existing naming (test-X.sh for shell, test-X-y.sh for variants). Each script returns exit 0 on success, emits a [PASS] line, and writes a log to local/docs/evidence/driver-manager/.

Script Phase (D / C) Purpose Exit code signal
test-driver-manager-parity.sh C1 (drafted in D1) Both managers active, observation only; verify they agree on every device-id-to-driver mapping 0 = same set bound
test-driver-manager-active.sh C3 driver-manager primary; pcid-spawner fallback; verify all 17 drivers 0 = all expected drivers present
test-driver-manager-initfs.sh C2 initfs use only; verify storage drivers come up before redoxfs 0 = redoxfs mounted
test-driver-manager-hotplug.sh D3 (gate) Hotplug add/remove cycle; unbind/rebind sequence 0 = unbind + rebind within budget
test-driver-manager-pm.sh D2 (gate) Suspend/resume cycle, parameter write-through 0 = clean suspend+resume
test-driver-manager-cutover.sh C4 Final acceptance: identical driver set before/after cutover 0 = no diff in bound-set logs
driver-manager-audit-no-stubs.py D4 (gate) Static analysis that the source contains no unimplemented!(), no todo!(), no Ok(()) trait-method defaults — per § 0.5 0 = no violations
test-driver-manager-no-stubs-qemu.sh D4 (gate) QEMU run with synthesized edge-case devices exercising every P0 capability C1C18 0 = every test bus emits one bind event

8. Cross-cutting concerns

8.1 GPU / DRM

The redox-drm driver daemon currently relies on PciFunctionHandle::connect_default() plus redox-driver-sys::pci::PciDevice. driver-manager must continue passing PCID_CLIENT_CHANNEL for redox-drm to receive a working channel. The match table that triggers redox-drm (30-graphics.toml already in config/redbear-device-services.toml) is consumed by driver-manager; no driver side changes. The redox-driver-sys::PciQuirkFlags policy is consulted in D4 (NEED_FIRMWARE, DISABLE_ACCEL, NO_MSIX). AMD-specific decisions live in local/docs/DRM-MODERNIZATION-EXECUTION-PLAN.md — the present plan does not re-open those decisions, it only carries them into the manager's match-time decision logic.

8.2 USB

xhcid, ehcid, ohcid, uhcid, usbhubd, usbscsid, usbhidd, usbaudiod all spawn from /lib/drivers.d/{20-usb,70-usb-class}.toml. These TOMLs exist in config/redbear-device-services.toml (lines 116-490) but are inert today. driver-manager must wake them correctly during C3. The Bus trait will gain a UsbBus in local/docs/USB-IMPLEMENTATION-PLAN.md; that is out of scope for this migration.

8.3 Audio

ihdad, ac97d, sb16d are in 50-audio.toml. These spawn late (no initfs dependency); driver-manager handles them as ordinary bound drivers with priority below storage/network. CachyOS's audio-power management patterns (20-audio-pm.rules) are reflected in D4's depends_on and hotplug hooks for these drivers.

8.4 Storage init path

This is the highest-risk surface. ahcid, ided, nvmed, virtio-blkd, usbscsid, usb-bot MUST be ready before redoxfs mounts. Phase C2's initfs migration has its own gate, and a fallback (40_pcid-spawner-initfs.service via ConditionPathExists) is required at every C-phase before C4.

8.5 Cross-config consistency

The three compile targets (redbear-mini, redbear-full, redbear-grub) all include init services that depend on 00_pcid-spawner.service. All three need the same 00_driver-manager.service substitution. The change is mechanical but must be applied to every [service].requires_weak reference and every [[files]] install in the same PR. make lint-config enforces consistency.

8.6 Doc references

After C3:

  • local/AGENTS.md § PLANNING NOTES gets a one-liner pointing here.
  • local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md Phase 1 row updates from "🟡 | in progress" to "🟡 | driver-manager parity accepted".
  • local/docs/PATCH-GOVERNANCE.md § "Local recipe priority vs upstream WIP" notes that local/recipes/system/driver-manager is the canonical owner.
  • local/docs/UPSTREAM-SYNC-PROCEDURE.md § "driver-manager: Deferred" replaced with "driver-manager: live (00_driver-manager.service)".

After C4 (production cutover):

  • README.md status row updates to .
  • config/redbear-mini.toml:31 and config/redbear-device-services.toml:9-13 inline deferred comments are removed (no longer accurate once driver-manager is live).
  • local/docs/UPSTREAM-SYNC-PROCEDURE.md § "driver-manager: Deferred" replaced with "driver-manager: production".

8.7 Branch / submodule policy

Per local/AGENTS.md § BRANCH AND SUBMODULE POLICY, no new submodule is created. driver-manager stays a local recipe under local/recipes/system/driver-manager/. This is preserved at every phase. The 9 declared submodules remain unchanged.


9. Appendices

9.1 File map (post-migration, target end state)

Created (tracked):

local/recipes/system/driver-manager/source/src/
├── main.rs                   (modified at D3, D4, C1, C3 across their phases)
├── config.rs                 (modified at D1 [format coexistence], D2 [PM hooks], D3 [event-driven], D4 [quirk integration])
├── scheme.rs                 (modified at D2 [PM scheme surface], D4 [quirk reporting])
├── hotplug.rs                (rewritten at D3 — event-driven)
├── exec.rs                   (removed at D0; spawn was already inlined in config.rs::probe())
├── driver-probe.rs           (NEW at D1 [SpawnDecision committee], evolves D2 [PM dispatch], D4 [AER routing])
└── errors.rs                 (NEW at D0 [error-tag normalisation], evolves D2 [PM error codes])

local/recipes/system/driver-manager/recipe.toml       (no change)
local/recipes/system/driver-manager/source/Cargo.toml (deps added at D2 [bitflags], D3 [event-stream], D4 [redox-driver-sys])

local/sources/base/init.d/00_driver-manager.service          (NEW dormant at C0; evolves C1, C3)
local/sources/base/init.initfs.d/40_driver-manager-initfs.service  (NEW dormant at C0; becomes blocking at C2)

local/config/driver-manager.d/                               (NEW at D4)
├── 00-blacklist.conf
├── autoload.d/ntsync.conf
├── 50-amdgpu.toml
└── initfs.manifest

local/scripts/test-driver-manager-{parity,active,initfs,hotplug,pm,cutover}.sh  (one per phase — see § 7)
local/scripts/driver-manager-audit-no-stubs.py               (NEW at D4; gates D5)

local/recipes/system/driver-params/source/src/main.rs     (modified at C1 to consume scheme:driver-manager:/bound)
local/recipes/system/redbear-driver-policy/                 (NEW at D4; curated policy package; packaged at C3)

Modified (kept tracked):

config/redbear-mini.toml         (C0: driver-manager added to [packages]; superseded comments at C4)
config/redbear-full.toml         (C0: same)
config/redbear-grub.toml         (C0: same)
config/redbear-greeter-services.toml  (C0: same)
config/redbear-device-services.toml   (C0 + D4: driver-manager config inclusion)

local/docs/UPSTREAM-SYNC-PROCEDURE.md  (§ driver-manager: Deferred -> live at C3; -> production at C4)
local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md  (Phase 1 row update at C3)
local/docs/HARDWARE-VALIDATION-MATRIX.md  (multiple rows updated at D5)
README.md  (status row at C4)
AGENTS.md  (no change beyond pointer)
local/AGENTS.md  (PLANNING NOTES section gains pointer)

Untouched (preserved for fallback throughout D/C phases and after C4):

local/sources/base/drivers/pcid-spawner/   (entire tree — fallback for life)
local/sources/base/drivers/pcid/          (unchanged — still the scheme:pci owner)
local/sources/base/init.d/00_pcid-spawner.service  (becomes dormant fallback service at C3)
local/sources/base/init.initfs.d/40_pcid-spawner-initfs.service  (becomes dormant fallback at C2)

local/patches/base/  (all P-numbered patches preserved)
local/recipes/core/pcid-spawner/recipe.toml  (path-fork unchanged)
recipes/core/base/drivers/pcid-spawner/  (path-fork path unchanged)

The 17 driver daemons' source trees and Cargo.tomls.

9.2 Environment variable contract (preserved)

Var Source Consumer Format
PCID_CLIENT_CHANNEL pcid-spawner (legacy), driver-manager (new) driver daemon via PciFunctionHandle::connect_default() ASCII decimal fd
PCID_SEGMENT both driver daemon 4-hex (e.g., 0000)
PCID_BUS both driver daemon 2-hex (e.g., 03)
PCID_DEVICE both driver daemon 2-hex (e.g., 0a)
PCID_FUNCTION both driver daemon decimal
REDBEAR_DRIVER_MANAGER_ACTIVE env (env file) driver-manager 0 = observation; non-zero = spawn
DRIVER_PARAMS_LOG existing driver-params one of trace/debug/info/warn/error
DRIVER_PARAMS_BOUND_PATH existing driver-params path string
INIT_NOTIFY init driver-params, driver-manager (from C0 onwards) int fd

9.3 Capability-to-driver matrix

Driver daemon C3 enable C4 bar request C5 map C6 bus master C7 vectors C12 config R/W C16 caps C17 INTx
ahcid via PCID_CLIENT_CHANNEL implicit via connect driver-side via redox-driver-sys yes MSI via pcid client yes yes yes
ided same same same yes n/a yes yes yes
nvmed same same same yes MSI-X yes yes yes
virtio-blkd same same same yes n/a yes yes yes
e1000d same same same yes MSI via redox-driver-sys yes yes yes
rtl8168d same same same yes MSI yes yes yes
rtl8139d same same same yes INTx yes yes yes
ixgbed same same same yes MSI-X yes yes yes
virtio-netd same same same yes n/a yes yes yes
ihdgd same same same yes MSI-X yes yes yes
virtio-gpud same same same yes n/a yes yes yes
xhcid same same same yes MSI-X yes yes yes
ihdad same same same yes MSI yes yes yes
ac97d same same same yes INTx yes yes yes
vboxd same same same yes n/a yes yes yes
amd-mp2-i2cd same same same yes MSI yes yes yes
intel-thc-hidd same same same yes MSI yes yes yes

Crucial invariant: all 17 drivers already fulfil C3C8, C12, C16, C17 through pcid_interface::PciFunctionHandle::connect_default() followed by PciClient::* calls. driver-manager's role is to deliver a working channel FD into the child's env. No driver rewrite required at any phase.

9.4 TOML schema (canonical end-state at C3)

Match table (/lib/drivers.d/*.toml):

# matches are AND-ed within an entry, OR-ed across entries
[[driver]]
name = "e1000d"
description = "Intel e1000 Gigabit Ethernet"
priority = 50

[driver.command]
argv = ["e1000d"]   # or absolute path

[driver.depends_on]
schemes = ["pci", "firmware"]

[[driver.match]]
vendor = 0x8086
device = 0x100E
class = 0x02       # network controller
subclass = 0x00    # ethernet

[[driver.match]]
vendor = 0x8086
device = 0x10D3
# wildcard rest

[driver.params]
debug = { type = "bool", default = false, writable = true }
priority_arg = { type = "int", default = 0, writable = true }
exclusive_with = { type = "string", default = "", writable = false }

Policy layer (/etc/driver-manager.d/*.toml):

# Blacklist
[[blacklist]]
module = "iTCO_wdt"
reason = "CachyOS precedent; conflicts with iTCO hardware"

# Forced module-options
[amdgpu.params]
si_support = true
cik_support = true
radeon_overlap = "exclusive"   # CachyOS mutual exclusion pattern

# Autoload (cold-boot pre-driver)
[[autoload]]
module = "ntsync"

Initfs manifest (/etc/driver-manager.d/initfs.manifest):

# ordered (CachyOS-style hook ordering)
[ramdisk]
microcode = ["amd-ucode", "intel-ucode"]
policy = "00-driver-conf"
kms_drivers = ["amdgpu", "i915"]
block_drivers = ["ahci", "nvme", "virtio_blk"]
fs_drivers = ["redoxfs", "ext4"]

9.5 Migration effort & ownership

Phase Effort estimate Owner role
D-Phase Effort estimate Owner role
--- --- ---
D1 — Linux capability bridge 610 weeks driver-runtime engineer
D2 — Modern technology surface 812 weeks (largest phase; SMP + S/P + PM + IOMMU + AER + MSI-X + NUMA) driver-runtime + kernel-interface engineer + ACPI engineer
D3 — Hotplug event-driven 46 weeks driver-runtime engineer
D4 — Quirk integration + audit 68 weeks (includes the § 0.5 no-stubs audit) driver-runtime + SRE
D5 — Feature-complete gate 12 weeks driver-runtime engineer + operator ratification
D-phase total 2538 weeks (~69 months)
C-Phase Effort estimate Owner role
C0 — Service wiring (dormant) 1 week driver-runtime engineer
C1 — Dual-mode observation 24 weeks (must run alongside pcid-spawner in production) driver-runtime engineer + build-system engineer
C2 — Initfs switchover 23 weeks driver-runtime + boot-system engineer
C3 — Rootfs switchover 24 weeks driver-runtime engineer
C4 — Operator-ratified production cutover 12 weeks + 2-week soak + 3 hardware reboots operator + driver-runtime engineer
C-phase total 814 weeks + soak (~24 months)

Grand total: 3352 weeks (~813 months) for full D+C trajectory.

Operator ratification required at the following phase boundaries:

  • D5 → C0 — feature-complete gate (the § 0.5 audit clean + hardware matrix passes)
  • C1 → C2 — rootfs observation confirmed dual-mode parity
  • C2 → C3 — initfs switchover ratified
  • C3 → C4 — rootfs switchover ratified
  • C4 transition — production cutover ratified

Phase boundaries without explicit operator ratification are not allowed to advance.

9.6 References

Internal (Red Bear OS):

  • local/AGENTS.md — policy authority
  • local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md — supersedes for desktop path
  • local/docs/DRM-MODERNIZATION-EXECUTION-PLAN.md — GPU-specific decisions
  • local/docs/IRQ-AND-LOWLEVEL-CONTROLLERS-ENHANCEMENT-PLAN.md — PCI/IRQ quality
  • local/docs/USB-IMPLEMENTATION-PLAN.md — USB bus (out of scope here)
  • local/docs/WIFI-IMPLEMENTATION-PLAN.md — Wi-Fi bus (out of scope here)
  • local/docs/QUIRKS-SYSTEM.mdredox-driver-sys quirks surface
  • local/docs/QUIRKS-IMPROVEMENT-PLAN.md — Task 2.1 driver-manager bridge
  • local/docs/HARDWARE-VALIDATION-MATRIX.md — status of driver runs
  • local/docs/UPSTREAM-SYNC-PROCEDURE.md — historical status note to update
  • local/docs/PATCH-GOVERNANCE.md — patch carrier rules
  • local/docs/RELEASE-BUMP-WORKFLOW.md — version sync
  • local/scripts/TOOLS.md — tool inventory

External cross-reference (not authoritative here, cited for design intent):

  • Linux 7.1 reference tree at local/reference/linux-7.1/ (commit ab9de95c9):
    • drivers/pci/pci-driver.c:1021-1742 — pci_driver, pci_bus_type
    • drivers/pci/pci.c:2120, 3916, 4172pci_enable_device, pci_request_regions, pci_set_master
    • drivers/pci/msi/api.c:205-264pci_alloc_irq_vectors_affinity
    • drivers/pci/hotplug/pciehp_core.c:185-372 — native hotplug
    • drivers/pci/pcie/aer.c:1203-1280 — AER recovery
    • drivers/base/bus.c:732, 818, 612, 869 — driver-core binding
  • CachyOS-Settings (master, v1.3.5): https://github.com/CachyOS/CachyOS-Settings
    • usr/lib/udev/rules.d/60-ioschedulers.rules — kernel-event → sysfs-write policy
    • usr/lib/udev/rules.d/71-nvidia.rules — bind/unbind lifecycle symmetry
    • usr/lib/udev/rules.d/20-audio-pm.rules — cross-subsystem reaction
    • usr/lib/udev/rules.d/85-iw-regulatory.rules + cachyos-iw-set-regdomain.{path,service} — udev→systemd delegation
    • usr/lib/modprobe.d/{amdgpu,blacklist,nvidia}.conf — driver-exclusion pattern
  • CachyOS/linux-cachyos: scheduler variants, mkinitcpio preset ordering.

10. Position statement

This plan supersedes the inline deferred notes that accompany the existing driver-manager recipe:

  • config/redbear-mini.toml:31 ("driver-manager requires driver config migration and is not yet ready")
  • config/redbear-device-services.toml:9-13 ("driver-manager intentionally not included … its service launched pcid-spawner instead of driver-manager").

These notes remain accurate at the moment of writing (2026-07-20). They will be amended at the relevant phase boundaries as the migration advances. At no point in the migration is pcid-spawner removed from the tree, the recipe, or the live image. The boot path is never single-point-of-failure.

v1.1 additions (this revision): § 0 Strategic Context is added with rationale, success criteria, upstream risk, modern-technology surface, comprehensive-implementation principle, and the parallel-development constraint. § 5 is restructured into D-Phase (parallel development) and C-Phase (cutover & validation). All cross-references in §§ 1, 2, 4, 5, 6, 7, 8, 9 are updated to the new phase nomenclature. The § 0.5 comprehensive principle is the binding code-quality bar; the § 0.6 parallel-development constraint is the binding development model.

Binding constraints derived from § 0:

  • Comprehensive implementation — every public trait method on Bus, Driver, and Manager is fully implemented. No unimplemented!(), no todo!(), no empty match arms returning trivial defaults, no #[cfg(...)]-gated no-ops. Honoring local/AGENTS.md § STUB AND WORKAROUND POLICY — ZERO TOLERANCE.
  • Modern technology surface — SMP-aware concurrent probe, C/P-state coordination, runtime PM, IOMMU group management, AER error recovery, MSI-X vector allocation, NUMA-aware DMA. None of these are stubs.
  • Parallel development model — driver-manager is being built in parallel with the live pcid-spawner system. It is NOT shipped, NOT enabled, NOT included in any boot path until the D5 feature-complete gate ratifies. No exceptions.
  • Upstream-first response — if Redox upstream ships an equivalent manager within 6 months of D5, evaluate and consider migrating per Local Fork Supremacy Policy. The migration plan is robust to upstream divergence; it does NOT block on upstream decisions.

Status of § 0.6 (parallel development) at the moment of writing: driver-manager is being built. It is NOT shipped. The boot path is pcid-spawner. The migration plan enters C-phase only after D5 ratifies.

The migration's authority chain is: this document → local/AGENTS.mdAGENTS.md. Every implementation step must be defensible against this chain, the § 0.5 comprehensive principle, and the § 0.6 parallel-development constraint.

Last reviewed: 2026-07-20 (v1.1: strategic-context + D/C phase restructure) Next review: at D5 exit gate, after local/scripts/driver-manager-audit-no-stubs.py reports zero violations AND local/docs/HARDWARE-VALIDATION-MATRIX.md shows driver-manager validated on at least one AMD and one Intel profile across storage, network, and GPU categories.