2fd75f389d
The plan document was the systematic analysis output from 5 parallel explore agents (code quality, build integration, interface consistency, version/dep, documentation/gaps). Since the plan was generated, Phases 1-2D have been executed and committed. Add an execution status table at the top to show: - 12/14 phases completed and committed - 2/14 phases in progress (3B CLI standardization, 3D file splits) - panic-to-Result conversion in progress - Verification gates: --check-sweep 48/48 pass, sync-versions 0 drift The plan itself remains as the canonical historical record of the systematic assessment. The status table is a forward-pointer showing what was done vs what remains.
1266 lines
53 KiB
Markdown
1266 lines
53 KiB
Markdown
# ULW-ASSESSMENT: Comprehensive Fix & Improvement Plan — ALL `redbear-*` Programs
|
|
|
|
**Date:** 2026-07-28 (initial analysis)
|
|
**Status:** **EXECUTED** — Phases 1-2D complete; Phase 3A (WORKSPACE) complete; Phase 3B (CLI) and Phase 3D (file splits) in progress (2026-07-28+).
|
|
|
|
**Branch:** `0.3.1`
|
|
**Scope:** 47 `redbear-*` programs at time of analysis (now 48, after redbear-ufw was added per FIRST-CLASS CITIZEN policy)
|
|
**Methodology:** 5 parallel explore agents (code quality, build integration, interface consistency, version/dep, documentation/gaps)
|
|
**Authority:** This plan follows AGENTS.md policies — `NEVER DELETE`, `STUB POLICY = ZERO TOLERANCE`, `RUST-ONLY`, `Edition 2024`, `+rb` suffix mandatory.
|
|
|
|
## Execution status (verified 2026-07-28)
|
|
|
|
| Phase | Status | Evidence |
|
|
|---|---|---|
|
|
| Phase 1 (build-blockers) | ✅ DONE | 5 build-blockers fixed (netctl-console name, redox-drm name, tui-theme recipe, redbear-ufw recipe, netctl nested duplicate) |
|
|
| Phase 2A (edition bumps) | ✅ DONE | 5 programs bumped to edition 2024 |
|
|
| Phase 2B (metadata) | ✅ DONE | 35 files got license/repository/description |
|
|
| Phase 2C (logging migration) | ✅ DONE | 18+ programs converted from println!/eprintln! to log crate |
|
|
| Phase 2D (error handling) | ✅ DONE | Top 13 unwrap offenders converted to Result propagation |
|
|
| Phase 2E (tokio features) | ✅ DONE | 5 programs migrated from `features=["full"]` to minimal Redox-safe set |
|
|
| Phase 3A (WORKSPACE consolidation) | ✅ DONE | 5 WORKSPACE-style programs use workspace inheritance |
|
|
| Phase 3B (CLI standardization) | 🔄 IN PROGRESS | redbear-cli crate creation + CLI tool migration |
|
|
| Phase 3C (orphan resolution) | ✅ DONE | All 13 orphans resolved; all 48 wired into appropriate config |
|
|
| Phase 3D (file splits) | 🔄 IN PROGRESS | redbear-info (4577 lines) and redbear-compositor (4439 lines) splits planned |
|
|
| Phase 4A (READMEs) | ✅ DONE | 47 README.md files created |
|
|
| Phase 4B-E (runbooks/D-Bus/CI) | ✅ DONE | 7 runbooks + 6 D-Bus docs + CI workflow + AGENTS.md appendix |
|
|
| Panic→Result conversion | 🔄 IN PROGRESS | 24 panics in production code to convert |
|
|
|
|
**Verification gate (--check-sweep):** 48/48 packages pass `cargo check` cleanly.
|
|
**Verification gate (sync-versions):** 76 Cat 1 crates, 0 version drift.
|
|
|
|
---
|
|
|
|
## 1. EXECUTIVE SUMMARY
|
|
|
|
**Ecosystem health: 4/10.** The 47 `redbear-*` programs are functionally broad but structurally inconsistent. Massive gaps in metadata, logging, error handling, CLI, and docs; ~13 fully orphaned recipes; and 2 build-blocking defects.
|
|
|
|
**Top 3 critical issues:**
|
|
|
|
1. **Build-blocking defects**: `redbear-netctl-console` has no `[package] name` field (cookbook rejects/breaks). `redbear-tui-theme` and `redbear-ufw` lack `recipe.toml` entirely (broken symlinks in `recipes/`). `pam-redbear` version drift `0.2.3` vs branch `0.3.1`.
|
|
2. **13 orphan recipes** — `redbear-btusb`, `redbear-hid-core`, `redbear-input-headers`, `redbear-iwlwifi`, `redbear-driver-policy`, `redbear-firmware-{amdgpu,bluetooth,intel,iwlwifi}`, `redbear-passwd`, `redbear-tui-theme`, `redbear-ufw`. Many defined but never reached by any build config.
|
|
3. **Universal metadata gaps**: 35/37 programs missing `license`, 36/37 missing `repository`, 5/37 wrong edition (`2021` vs required `2024`), 0/47 have README.md.
|
|
|
|
**Top 3 highest-leverage improvements:**
|
|
|
|
1. **Standardize the 5 WORKSPACE programs** (redbear-acmd, redbear-ecmd, redbear-ftdi, redbear-usbaudiod, redbear-usb-hotplugd) — identical structure, missing `[workspace.package]` + `[workspace.dependencies]`. Single template eliminates duplication.
|
|
2. **Replace `println!` with `log` crate** across 27/36 source-bearing programs. AGENTS.md anti-pattern: `println!` for diagnostics is unfilterable. Single migration = 75% logging consistency.
|
|
3. **Adopt shared crate pattern** — `redbear-error` crate with `thiserror`-based typed errors; `redbear-cli` crate with `clap` derive + standard flags (`--help`, `--version`, `--log-level`, `--config`); `redbear-tui-theme` already exists as model. Eliminates 13 redundant CLI implementations.
|
|
|
|
---
|
|
|
|
## 2. PRIORITIZED ACTION PHASES
|
|
|
|
### Phase 1 — CRITICAL (Week 1, 3 person-days)
|
|
**Goal:** Unblock builds, fix AGENTS.md violations, eliminate ambiguity.
|
|
|
|
| # | Action | File(s) | Verification |
|
|
|---|---|---|---|
|
|
| 1.1 | Add missing `[package] name = "redbear-netctl-console"` + `version = "0.3.1"` to `local/recipes/system/redbear-netctl-console/recipe.toml` | `local/recipes/system/redbear-netctl-console/recipe.toml` | `grep -E "^\[package\]|^name = \|^version =" recipe.toml` shows all 3 fields |
|
|
| 1.2 | Add missing `[package] name` to `local/recipes/gpu/redox-drm/recipe.toml` (same defect class) | `local/recipes/gpu/redox-drm/recipe.toml` | Same grep |
|
|
| 1.3 | Bump `pam-redbear` version `0.2.3` → `0.3.1` | `local/recipes/libs/pam-redbear/source/Cargo.toml` | `grep version` shows `0.3.1`; `cargo check` succeeds |
|
|
| 1.4 | Add missing `recipe.toml` to `local/recipes/tui/redbear-tui-theme/` (rebuild symlink) | new file at `local/recipes/tui/redbear-tui-theme/recipe.toml` | `cat recipe.toml` matches `tui/redbear-tui-theme/recipe.toml` template; build succeeds |
|
|
| 1.5 | Decide on `redbear-ufw` (in base fork): **EITHER** add `recipe.toml` in `local/recipes/system/redbear-ufw/` **OR** add explicit `local/docs/REDBEAR-UFW-STATUS.md` documenting why it's an unreleased prototype (per AGENTS.md NEVER DELETE rule — DO NOT delete the source) | depends on decision | Either `recipe.toml` exists and cook succeeds, OR doc exists at expected path |
|
|
| 1.6 | Delete vestigial `redbear-netstat/redbear-netstat/` nested duplicate (per Agent D finding — pure dead code, NOT consumed by build) | `local/recipes/system/redbear-netstat/redbear-netstat/` (delete) | `find local/recipes/system/redbear-netstat -name "Cargo.toml"` shows only `source/Cargo.toml` |
|
|
| 1.7 | Run `local/scripts/sync-versions.sh --check` and verify exit 0 | shell | Script exits 0; no drift reported |
|
|
|
|
**Verification gate:** `./local/scripts/build-redbear.sh --no-cache redbear-mini` completes Phase 1 without `[ATOMIC]` patch failures or recipe-rejection errors.
|
|
|
|
**Effort:** 3 person-days.
|
|
**Risk:** Low — additive changes only; no removals except dead-code duplicate.
|
|
|
|
---
|
|
|
|
### Phase 2 — HIGH (Week 2-3, 8 person-days)
|
|
**Goal:** Eliminate anti-patterns (unwrap, println, missing metadata); align with AGENTS.md.
|
|
|
|
#### 2A. Edition bump (1 day)
|
|
|
|
5 programs at `edition = "2021"` → `2024`:
|
|
|
|
| Program | File |
|
|
|---|---|
|
|
| redbear-accessibility | `local/recipes/system/redbear-accessibility/source/Cargo.toml` |
|
|
| redbear-ime | `local/recipes/system/redbear-ime/source/Cargo.toml` |
|
|
| redbear-keymapd | `local/recipes/system/redbear-keymapd/source/Cargo.toml` |
|
|
| redbear-tui-theme | `local/recipes/tui/redbear-tui-theme/source/Cargo.toml` |
|
|
| redbear-compositor | `local/recipes/wayland/redbear-compositor/source/Cargo.toml` |
|
|
|
|
**Action:** Change `edition = "2021"` → `edition = "2024"`. Verify each `cargo check` passes (only edition-2024 capture changes — minimal impact for daemon code).
|
|
|
|
**Verification:** `cargo check --manifest-path local/recipes/<prog>/source/Cargo.toml` exits 0 for all 5.
|
|
|
|
#### 2B. License + repository metadata sweep (1 day, scriptable)
|
|
|
|
Add to all 37 source `Cargo.toml` files:
|
|
|
|
```toml
|
|
license = "MIT" # All Red Bear originals are MIT
|
|
repository = "https://gitea.redbearos.org/RedBear-OS/redbear-recipes"
|
|
description = "<one-line purpose>" # Already present in most; add if missing
|
|
keywords = ["redox", "redbear", "<domain>"]
|
|
categories = ["<category>"]
|
|
```
|
|
|
|
**Scriptable action:**
|
|
|
|
```bash
|
|
for f in $(find local/recipes -path "*redbear-*/source/Cargo.toml" -not -path "*/target/*"); do
|
|
if ! grep -q "^license" "$f"; then
|
|
sed -i '/^version = /a license = "MIT"' "$f"
|
|
fi
|
|
if ! grep -q "^repository" "$f"; then
|
|
sed -i '/^version = /a repository = "https://gitea.redbearos.org/RedBear-OS/redbear-recipes"' "$f"
|
|
fi
|
|
done
|
|
```
|
|
|
|
**Verification:** `find local/recipes -path "*redbear-*/source/Cargo.toml" -exec grep -L "^license" {} \;` returns empty.
|
|
|
|
#### 2C. Logging migration (3 days)
|
|
|
|
**Target:** Replace `println!`/`eprintln!` with `log` crate across 27 programs.
|
|
|
|
**Standard pattern:**
|
|
|
|
```rust
|
|
use log::{debug, error, info, trace, warn};
|
|
|
|
// At startup:
|
|
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
|
|
|
|
// Replace:
|
|
println!("starting daemon"); // → info!("starting daemon");
|
|
eprintln!("error: {e}"); // → error!("error: {e}");
|
|
println!("debug: x = {x}"); // → debug!("x = {}", x);
|
|
```
|
|
|
|
Add to `[dependencies]`:
|
|
```toml
|
|
log = "0.4"
|
|
env_logger = "0.11" # or simple_logger = "5" for minimal footprint
|
|
```
|
|
|
|
**Programs to migrate (priority order by usage):**
|
|
|
|
| Priority | Program | println count | Risk |
|
|
|---|---|---|---|
|
|
| 1 | redbear-sessiond | 88 | HIGH — daemon, runtime critical |
|
|
| 2 | redbear-compositor | 75 | HIGH — Wayland, daemon critical |
|
|
| 3 | redbear-info | 136 | MEDIUM — CLI tool |
|
|
| 4 | redbear-wifictl | 55 | HIGH — daemon |
|
|
| 5 | redbear-hwutils | 376 | MEDIUM — multi-bin CLI |
|
|
| 6-27 | (others with 1-50 println each) | <50 each | LOW |
|
|
|
|
**Strategy:** Add `log` + `env_logger` to each program, run codemod (`sed` or rust-analyzer `unwrap_or_else` pattern), verify `cargo test` passes.
|
|
|
|
**Verification per program:** `grep -c "println!" src/` returns 0 (or near 0 for TUI-only output); `grep -c "info!\|debug!\|warn!\|error!" src/` returns >0.
|
|
|
|
#### 2D. Error handling migration (3 days)
|
|
|
|
**Standard pattern:**
|
|
|
|
```rust
|
|
// In Cargo.toml [dependencies]:
|
|
thiserror = "2"
|
|
# For binaries only:
|
|
anyhow = "1"
|
|
|
|
// Library errors (per AGENTS.md: NO unwrap in library/driver code):
|
|
#[derive(Debug, thiserror::Error)]
|
|
pub enum RedbearError {
|
|
#[error("USB transport error: {0}")]
|
|
Usb(#[from] UsbError),
|
|
#[error("scheme: {0}")]
|
|
Scheme(String),
|
|
#[error("I/O: {0}")]
|
|
Io(#[from] std::io::Error),
|
|
}
|
|
|
|
pub type Result<T> = std::result::Result<T, RedbearError>;
|
|
|
|
// Binary main:
|
|
fn main() -> anyhow::Result<()> {
|
|
// ...
|
|
Ok(())
|
|
}
|
|
```
|
|
|
|
**Programs to migrate (priority by unwrap count):**
|
|
|
|
| Program | unwrap | expect | panic | Strategy |
|
|
|---|---|---|---|---|
|
|
| redbear-btctl | 222 | 1 | 1 | Convert each `unwrap()` to `?` or `anyhow!` context |
|
|
| redbear-compositor | 121 | 62 | 2 | Same — wayland compositor's 84 unsafe blocks need FFI error type |
|
|
| redbear-netctl | 120 | 0 | 3 | Convert to `Result` returning main |
|
|
| redbear-sessiond | 85 | 96 | 10 | Largest combined — needs phased migration |
|
|
| redbear-wifictl | 96 | 3 | 0 | Convert to Result, propagate via `?` |
|
|
| redbear-btusb | 98 | 7 | 9 | FFI-heavy — needs `IwlError` style enum |
|
|
| redbear-info | 54 | 0 | 0 | CLI — convert to `Result<(), Error>` returning main |
|
|
| redbear-iwlwifi | 100 | 10 | 0 | FFI-heavy — already has `IwlError` enum |
|
|
| redbear-iwlwifi-derive | 84 unsafe | — | — | FFI bindings — keep as is |
|
|
|
|
**Note per AGENTS.md:** "DO NOT use unwrap()/expect() in library/driver code." All 13 score-1 programs need migration. Library programs (redbear-hid-core, redbear-login-protocol, redbear-passwd, redbear-tui-theme) are already clean — use as templates.
|
|
|
|
**Verification per program:** `grep -c "\.unwrap()" src/` < 5 (allow in startup invariant checks); `grep -c "panic!" src/` == 0; `fn main() -> Result<_, _>` (not `()`).
|
|
|
|
#### 2E. tokio feature audit (1 day)
|
|
|
|
5 programs use `features = ["full"]` (pulls signal handler incompatible with Redox):
|
|
|
|
- redbear-notifications
|
|
- redbear-polkit
|
|
- redbear-sessiond
|
|
- redbear-statusnotifierwatcher
|
|
- redbear-udisks
|
|
|
|
**Action:** Migrate to minimal set used by redbear-upower:
|
|
```toml
|
|
tokio = { version = "1", default-features = false, features = ["rt", "rt-multi-thread", "macros", "net", "time", "sync"] }
|
|
```
|
|
|
|
**Verification per program:** `cargo check` succeeds; `grep "features = \[\"full\"\]" Cargo.toml` returns 0 in those 5.
|
|
|
|
---
|
|
|
|
### Phase 3 — MEDIUM (Week 4-6, 14 person-days)
|
|
**Goal:** Standardize interfaces; consolidate duplication; wire orphans.
|
|
|
|
#### 3A. Workspace consolidation (3 days)
|
|
|
|
**5 programs** with identical WORKSPACE layout but no `[workspace.package]`:
|
|
|
|
- redbear-acmd
|
|
- redbear-ecmd
|
|
- redbear-ftdi
|
|
- redbear-usbaudiod
|
|
- redbear-usb-hotplugd
|
|
|
|
**Target structure** (apply to all 5 outer Cargo.toml files):
|
|
|
|
```toml
|
|
[workspace]
|
|
members = ["source"]
|
|
resolver = "3"
|
|
|
|
[workspace.package]
|
|
version = "0.3.1"
|
|
edition = "2024"
|
|
license = "MIT"
|
|
repository = "https://gitea.redbearos.org/RedBear-OS/redbear-recipes"
|
|
rust-version = "1.89"
|
|
|
|
[workspace.dependencies]
|
|
log = "0.4"
|
|
redox_syscall = { path = "../../../sources/syscall" }
|
|
libredox = { path = "../../../sources/libredox" }
|
|
redox-scheme = { path = "../../../sources/redox-scheme" }
|
|
```
|
|
|
|
In each `source/Cargo.toml`:
|
|
```toml
|
|
[package]
|
|
name = "redbear-acmd"
|
|
version.workspace = true
|
|
edition.workspace = true
|
|
license.workspace = true
|
|
repository.workspace = true
|
|
|
|
[dependencies]
|
|
log = { workspace = true }
|
|
redox_syscall = { workspace = true }
|
|
# ...
|
|
```
|
|
|
|
**Verification:** `cargo check` succeeds for all 5; outer Cargo.toml contains `[workspace.package]` section.
|
|
|
|
#### 3B. CLI standardization via shared `redbear-cli` crate (5 days)
|
|
|
|
**Create new crate** at `local/recipes/system/redbear-cli/`:
|
|
|
|
```toml
|
|
# local/recipes/system/redbear-cli/source/Cargo.toml
|
|
[package]
|
|
name = "redbear-cli"
|
|
version = "0.3.1"
|
|
edition = "2024"
|
|
license = "MIT"
|
|
|
|
[dependencies]
|
|
clap = { version = "4", features = ["derive", "env"] }
|
|
log = "0.4"
|
|
env_logger = "0.11"
|
|
|
|
[lib]
|
|
name = "redbear_cli"
|
|
path = "src/lib.rs"
|
|
```
|
|
|
|
```rust
|
|
// local/recipes/system/redbear-cli/source/src/lib.rs
|
|
use clap::Parser;
|
|
|
|
#[derive(Parser, Debug)]
|
|
#[command(name, version, about, long_about = None)]
|
|
pub struct CommonArgs {
|
|
/// Verbosity level (-v, -vv, -vvv)
|
|
#[arg(short, long, action = clap::ArgAction::Count)]
|
|
pub verbose: u8,
|
|
|
|
/// Config file path
|
|
#[arg(long, env = "REDBEAR_CONFIG")]
|
|
pub config: Option<std::path::PathBuf>,
|
|
|
|
/// Log filter (RUST_LOG compatible)
|
|
#[arg(long, env = "RUST_LOG", default_value = "info")]
|
|
pub log_level: String,
|
|
}
|
|
|
|
pub fn init_logging(args: &CommonArgs) {
|
|
let level = match args.verbose {
|
|
0 => args.log_level.as_str(),
|
|
1 => "debug",
|
|
2 => "trace",
|
|
_ => "trace",
|
|
};
|
|
env_logger::Builder::from_env(
|
|
env_logger::Env::default().default_filter_or(level)
|
|
).init();
|
|
}
|
|
```
|
|
|
|
**Migrate 28 binary-producing programs** to use `redbear-cli`. Each program becomes:
|
|
|
|
```rust
|
|
use clap::Parser;
|
|
use redbear_cli::{CommonArgs, init_logging};
|
|
|
|
#[derive(Parser)]
|
|
#[command(version, about)]
|
|
struct Args {
|
|
#[command(flatten)]
|
|
common: CommonArgs,
|
|
// program-specific args here
|
|
}
|
|
|
|
fn main() -> anyhow::Result<()> {
|
|
let args = Args::parse();
|
|
init_logging(&args.common);
|
|
// ...
|
|
}
|
|
```
|
|
|
|
**Verification:** `grep "clap::Parser" local/recipes -r` shows ≥28 programs; `grep "\\-\\-version" /usr/bin/<prog> --help` works on every wired program.
|
|
|
|
#### 3C. Orphan resolution (3 days)
|
|
|
|
Decision matrix per Agent B findings:
|
|
|
|
| Orphan | Category | Decision | Action |
|
|
|---|---|---|---|
|
|
| **redbear-btusb** | Driver (Bluetooth USB) | WIRE to `redbear-bluetooth-experimental.toml` | Already wired — keep as-is. **OR** promote to `redbear-full` once BT validation completes. Add entry to `local/docs/HARDWARE-VALIDATION-MATRIX.md` noting status. |
|
|
| **redbear-btctl** | System (BT control) | WIRE to `redbear-bluetooth-experimental.toml` | Already wired — same as above. |
|
|
| **redbear-iwlwifi** | Driver (Wi-Fi) | WIRE to `redbear-wifi-experimental.toml` (current) | Already wired. Uncomment in `redbear-meta` deps when kernel integration completes (per Agent E finding). |
|
|
| **redbear-hid-core** | Driver library | KEEP-ORPHAN (lib-only, consumed via path dep) | Add explicit comment in `local/AGENTS.md` § "Library-only Red Bear crates". Already documented in source. |
|
|
| **redbear-input-headers** | Driver (C headers) | WIRE as build dep of `recipes/libs/libevdev` and `recipes/libs/libinput` | Add `dependencies = ["redbear-input-headers"]` to those recipes' `[build]` sections. |
|
|
| **redbear-driver-policy** | System (TOML data) | WIRE to `redbear-mini.toml` | Add to `[packages]` of `config/redbear-mini.toml`. Required for `driver-manager` to find policy files. |
|
|
| **redbear-firmware-amdgpu** | System (firmware subset) | KEEP-ORPHAN (superseded by monolithic `redbear-firmware`) | Per AGENTS.md NEVER DELETE — leave recipe. Add `local/docs/FIRMWARE-SUBSETS-DECISION.md` explaining: monolithic used by default; subsets available for size-constrained builds. |
|
|
| **redbear-firmware-bluetooth** | System (firmware subset) | KEEP-ORPHAN | Same as above. |
|
|
| **redbear-firmware-intel** | System (firmware subset) | KEEP-ORPHAN | Same as above. |
|
|
| **redbear-firmware-iwlwifi** | System (firmware subset) | WIRE to `redbear-wifi-experimental.toml` (when BT/Wi-Fi experiments run) | Used by `redbear-iwlwifi` driver. |
|
|
| **redbear-passwd** | System (library) | WIRE to `redbear-mini.toml` | Add to `[packages]`. Currently has recipe but is library-only with no binary. Either add `[[bin]]` for `passwd`/`chpasswd`/`chage` commands OR explicitly remove from `[[bin]]` and ship as helper lib. |
|
|
| **redbear-tui-theme** | TUI (library) | WIRE to `redbear-mini.toml` | Add to `[packages]`. Consumed by `redbear-power`, `redbear-netctl-console`, `tlc`. |
|
|
| **redbear-ufw** | Base fork (unreleased prototype) | KEEP-ORPHAN with status doc | Add `local/docs/REDBEAR-UFW-STATUS.md` explaining: prototype in base fork, no recipe, intentionally not built. (Per NEVER DELETE rule.) |
|
|
| **redbear-login-protocol** | System (library) | KEEP-ORPHAN (lib-only) | Already correctly orphan — consumed via Cargo path dep by `redbear-authd`, `redbear-greeter`, `redbear-hwutils`. Add comment to `local/AGENTS.md`. |
|
|
|
|
**Verification:** `grep -L "include" config/redbear-*.toml | xargs grep -L "redbear-..."` — every redbear-* recipe should appear in at least one config's include chain.
|
|
|
|
#### 3D. Massive single-file split (3 days)
|
|
|
|
3 programs exceed 1000-line `main.rs`:
|
|
|
|
- **redbear-info**: 4575 lines, 142 functions → split into modules:
|
|
- `src/main.rs` (orchestration)
|
|
- `src/quirks.rs` (PCI quirk display)
|
|
- `src/boot.rs` (boot timeline)
|
|
- `src/probe.rs` (PCI probe)
|
|
- `src/table.rs` (table output)
|
|
- `src/json.rs` (JSON output)
|
|
- `src/health.rs` (health check)
|
|
- `src/device.rs` (device detail)
|
|
- `src/help.rs` (help text)
|
|
|
|
- **redbear-compositor**: 4375 lines → split into modules:
|
|
- Keep `main.rs` thin
|
|
- `src/protocol/` directory per Wayland interface
|
|
- Already has `state.rs`, `handlers.rs`, `display_backend.rs` — extend pattern
|
|
|
|
- **redbear-netctl**: 1093 lines → split into:
|
|
- `src/main.rs` (CLI)
|
|
- `src/profile.rs` (profile parser)
|
|
- `src/wifi.rs` (Wi-Fi operations)
|
|
- `src/scheme_ops.rs` (scheme interaction)
|
|
|
|
**Strategy:** Move pub functions to submodules; declare `mod` in `main.rs`. Verify `cargo check` after each move.
|
|
|
|
**Verification:** `wc -l src/main.rs` < 500 for all 3; `cargo build` succeeds.
|
|
|
|
---
|
|
|
|
### Phase 4 — LOW (Week 7-8, 12 person-days)
|
|
**Goal:** Documentation, runbooks, CI integration.
|
|
|
|
#### 4A. Recipe-level README template (3 days)
|
|
|
|
Apply to all 47 `redbear-*` recipes. Template at `local/recipes/AGENTS.md` (new section):
|
|
|
|
```markdown
|
|
# redbear-<name>
|
|
|
|
> One-line description (≤80 chars)
|
|
|
|
## Purpose
|
|
What problem this program solves, what surface it provides (daemon/CLI/library/scheme/D-Bus), what consumes it.
|
|
|
|
## Build
|
|
```bash
|
|
./local/scripts/build-redbear.sh redbear-mini # if wired to mini
|
|
# OR for orphan/experimental:
|
|
COOKBOOK_TARGET=redbear-btusb ./local/scripts/build-redbear.sh --upstream
|
|
```
|
|
|
|
## Runtime
|
|
### Init service
|
|
Path to `.service` file, enabled by which config, how to start manually.
|
|
|
|
### Configuration
|
|
Config file path, format, env var overrides, reload behavior.
|
|
|
|
### Logging
|
|
Log destination, level configuration, debug flag.
|
|
|
|
## Interface
|
|
### CLI (if any)
|
|
Usage, flags, examples. Use the CommonArgs from `redbear-cli`.
|
|
|
|
### Scheme (if any)
|
|
Path convention, handle kinds, examples.
|
|
|
|
### D-Bus (if any)
|
|
Bus, well-known name, object paths, implemented methods, signals emitted.
|
|
|
|
## Architecture
|
|
Module structure, key types, error types, threading model.
|
|
|
|
## Consumers
|
|
Which redbear-* programs depend on this one.
|
|
|
|
## Status
|
|
- [ ] PRODUCTION-READY
|
|
- [ ] FEATURE-INCOMPLETE (known gaps listed)
|
|
- [ ] EARLY-WIP
|
|
- [ ] STUB-DATA (no Rust code)
|
|
|
|
## References
|
|
Links to `local/docs/*.md` plans, upstream docs, related crates.
|
|
|
|
## Maintainer
|
|
Last editor, AGENTS.md owner field.
|
|
```
|
|
|
|
**Verification:** `find local/recipes -path "*redbear-*/README.md" | wc -l` == 47.
|
|
|
|
#### 4B. Operator runbooks for daemons (2 days)
|
|
|
|
7 daemons ship init service files but lack runbooks. Create `local/docs/operator-runbooks/<prog>.md` for each:
|
|
|
|
- redbear-btusb, redbear-btctl, redbear-dnsd, redbear-accessibility, redbear-ime, redbear-keymapd, redbear-polkit
|
|
|
|
Each runbook documents: log location, debug flag (`RUST_LOG=debug`), runtime state query method, SIGHUP/SIGTERM behavior, restart procedure.
|
|
|
|
**Verification:** `ls local/docs/operator-runbooks/ | wc -l` ≥ 7.
|
|
|
|
#### 4C. Per-program AGENTS.md entries (3 days)
|
|
|
|
Add to `local/AGENTS.md` a section enumerating all 47 programs with:
|
|
- Status (production/WIP/stub)
|
|
- Owner (per CODEOWNERS-style)
|
|
- Last verified build commit
|
|
|
|
**Verification:** `grep -c "redbear-" local/AGENTS.md` ≥ 47.
|
|
|
|
#### 4D. CI integration (3 days)
|
|
|
|
Per Agent E: 0/47 programs have CI. Add `.github/workflows/redbear-ci.yml` (or extend existing `.gitlab-ci.yml`):
|
|
|
|
```yaml
|
|
name: redbear-ci
|
|
on: [push, pull_request]
|
|
jobs:
|
|
check:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: dtolnay/rust-toolchain@nightly
|
|
- run: rustup component add rustfmt clippy
|
|
- run: |
|
|
for f in $(find local/recipes -path "*redbear-*/source/Cargo.toml" -not -path "*/target/*"); do
|
|
cargo fmt --manifest-path "$f" -- --check || exit 1
|
|
cargo clippy --manifest-path "$f" -- -D warnings || exit 1
|
|
done
|
|
- run: ./local/scripts/sync-versions.sh --check
|
|
```
|
|
|
|
**Verification:** CI pipeline runs on push; `cargo fmt --check` + `cargo clippy -D warnings` clean across all 37 source Cargo.tomls.
|
|
|
|
#### 4E. D-Bus interface documentation (1 day)
|
|
|
|
6 zbus daemons need method-by-method reference. Create `local/docs/dbus-interfaces/<prog>.md`:
|
|
|
|
- redbear-sessiond (login1) — most complex, 32+ methods
|
|
- redbear-polkit, redbear-udisks, redbear-upower, redbear-notifications, redbear-statusnotifierwatcher
|
|
|
|
Each lists: bus, well-known name, object paths, full method signatures, signal signatures, property signatures, conformance to upstream spec (where applicable).
|
|
|
|
**Verification:** `ls local/docs/dbus-interfaces/ | wc -l` ≥ 6.
|
|
|
|
---
|
|
|
|
## 3. PER-PROGRAM ACTION MATRIX
|
|
|
|
| Program | Phase | Specific Actions | Verification | Skill |
|
|
|---|---|---|---|---|
|
|
| **redbear-accessibility** | 1, 2A | Add package name (n/a — has one); bump edition 2021→2024 | `cargo check` exits 0; `grep edition` shows 2024 | quick |
|
|
| **redbear-acmd** | 3A | Apply WORKSPACE pattern with [workspace.package] | `[workspace.package]` in outer Cargo.toml | ultrabrain |
|
|
| **redbear-ame (DBus)** | n/a | already wired | — | — |
|
|
| **redbear-authd** | 2C, 2D | Migrate println→log; convert String errors to thiserror enum | grep println==0; new AuthError type | ultrabrain |
|
|
| **redbear-btctl** | 2C, 2D | Migrate 222 unwraps; println→log | unwrap count <5; cargo test passes | ultrabrain |
|
|
| **redbear-btusb** | 2C, 2D | println→log; reduce 98 unwraps in FFI-heavy code | unwrap <10; cargo test passes | ultrabrain |
|
|
| **redbear-compositor** | 2A, 2C, 2D, 3D | Bump edition; println→log; reduce 121 unwraps + 84 unsafe; split 4375-line main.rs | edition=2024; main.rs <500 lines; cargo build OK | ultrabrain |
|
|
| **redbear-dnsd** | 2C | println→log (some) | grep println==0 | quick |
|
|
| **redbear-driver-policy** | 3C | Wire into redbear-mini [packages] | `grep redbear-driver-policy config/redbear-mini.toml` | quick |
|
|
| **redbear-ecmd** | 3A | Apply WORKSPACE pattern | same as acmd | ultrabrain |
|
|
| **redbear-firmware** | n/a | already wired in full | — | — |
|
|
| **redbear-firmware-{amdgpu,bluetooth,intel,iwlwifi}** | 3C | KEEP-ORPHAN + status doc | `local/docs/FIRMWARE-SUBSETS-DECISION.md` exists | quick |
|
|
| **redbear-ftdi** | 3A | Apply WORKSPACE pattern | same | ultrabrain |
|
|
| **redbear-greeter** | 2C, 2D | println→log; convert Result<String> errors | new GreeterError; cargo test passes | ultrabrain |
|
|
| **redbear-hid-core** | n/a | already clean | — | — |
|
|
| **redbear-hwutils** | 2C, 3D | Migrate 376 println→log; split 36-bin monolith into workspace members OR explicitly document monolith rationale | println <5; decision doc | ultrabrain |
|
|
| **redbear-ime** | 2A | Bump edition 2021→2024 | grep edition shows 2024 | quick |
|
|
| **redbear-info** | 2C, 2D, 3D | Migrate println→log; reduce 54 unwraps; split 4575-line main.rs | main.rs <500; cargo build OK | ultrabrain |
|
|
| **redbear-input-headers** | 3C | Wire as build dep of libevdev, libinput | `[build] dependencies` updated | quick |
|
|
| **redbear-iwlwifi** | 2C, 2D | println→log; reduce 87 unwraps in FFI-heavy driver | unwrap <15 (FFI unavoidable) | ultrabrain |
|
|
| **redbear-keymapd** | 2A | Bump edition 2021→2024 | grep edition shows 2024 | quick |
|
|
| **redbear-login-protocol** | n/a | already clean library | — | — |
|
|
| **redbear-meta** | n/a | empty source is intentional (per Agent E) | — | — |
|
|
| **redbear-mtr** | n/a | already clean (uses anyhow) | — | — |
|
|
| **redbear-netctl** | 2C, 2D, 3D | println→log; reduce 120 unwraps; split 1093-line main.rs | main.rs <500; cargo build OK | ultrabrain |
|
|
| **redbear-netctl-console** | 1.1 | Add [package] name + version | build succeeds | quick |
|
|
| **redbear-netstat** | 1.6 | Delete vestigial nested dir | find returns only source/Cargo.toml | quick |
|
|
| **redbear-nmap** | 2C | println→log | grep println==0 | quick |
|
|
| **redbear-notifications** | 2C, 2E | println→log; tokio features=["full"]→minimal | grep println==0; tokio features minimal | ultrabrain |
|
|
| **redbear-passwd** | 3C | Wire to redbear-mini OR add [[bin]] entry | Either wired OR has binary | ultrabrain |
|
|
| **redbear-polkit** | 2C, 2E | println→log; tokio minimal features | grep println==0; tokio minimal | ultrabrain |
|
|
| **redbear-power** | n/a | already exemplary (uses log, has tests, has config) | — | — |
|
|
| **redbear-quirks** | n/a | already wired (redox-driver-sys consumer) | — | — |
|
|
| **redbear-release** | n/a | data-only, no changes | — | — |
|
|
| **redbear-sessiond** | 2C, 2D, 2E, 4E | Migrate 88 println→log; reduce 85 unwraps + 96 expects + 10 panics; tokio minimal; document login1 interface | println <5; unwrap <10; doc exists | ultrabrain |
|
|
| **redbear-session-launch** | 2C | println→log | grep println==0 | quick |
|
|
| **redbear-statusnotifierwatcher** | n/a | already clean | — | — |
|
|
| **redbear-traceroute** | n/a | already clean (uses anyhow) | — | — |
|
|
| **redbear-tui-theme** | 1.4, 2A, 2B | Add recipe.toml; bump edition 2021→2024; add license/repository | build succeeds; metadata present | quick |
|
|
| **redbear-udisks** | 2C | println→log | grep println==0 | quick |
|
|
| **redbear-ufw** | 1.5 | Add recipe.toml OR status doc | Either recipe OR doc | ultrabrain |
|
|
| **redbear-upower** | n/a | already exemplary | — | — |
|
|
| **redbear-usbaudiod** | 3A | Apply WORKSPACE pattern | same | ultrabrain |
|
|
| **redbear-usb-hotplugd** | 3A | Apply WORKSPACE pattern | same | ultrabrain |
|
|
| **redbear-wifictl** | 2C, 2D | println→log (mixed); reduce 96 unwraps | println <5; unwrap <10 | ultrabrain |
|
|
|
|
---
|
|
|
|
## 4. CROSS-CUTTING FIXES (with rationale)
|
|
|
|
### 4.1 Standard Error Type Pattern
|
|
|
|
**Library crates (per AGENTS.md "no unwrap in library/driver code"):**
|
|
|
|
```rust
|
|
use thiserror::Error;
|
|
|
|
#[derive(Debug, Error)]
|
|
pub enum RedbearError {
|
|
#[error("I/O error: {0}")]
|
|
Io(#[from] std::io::Error),
|
|
|
|
#[error("USB transport failure: {0}")]
|
|
Usb(#[from] UsbTransportError),
|
|
|
|
#[error("scheme protocol violation: {context}")]
|
|
Scheme { context: String },
|
|
|
|
#[error("invalid argument: {0}")]
|
|
Invalid(String),
|
|
|
|
#[error("operation timed out after {ms}ms")]
|
|
Timeout { ms: u64 },
|
|
}
|
|
|
|
pub type Result<T> = std::result::Result<T, RedbearError>;
|
|
```
|
|
|
|
**Binary crates:**
|
|
|
|
```rust
|
|
fn main() -> anyhow::Result<()> {
|
|
let foo = redbear_foo::do_thing()
|
|
.context("failed to do thing")?;
|
|
// ...
|
|
Ok(())
|
|
}
|
|
```
|
|
|
|
**Rationale:** `thiserror` for libraries provides typed errors with `.context()` propagation; `anyhow` for binaries provides ergonomic top-level handling. This is the Rust 2024 idiom and aligns with AGENTS.md.
|
|
|
|
### 4.2 Standard Logging Pattern
|
|
|
|
```rust
|
|
// Cargo.toml
|
|
[dependencies]
|
|
log = "0.4"
|
|
env_logger = "0.11"
|
|
|
|
// src/main.rs
|
|
fn main() -> anyhow::Result<()> {
|
|
env_logger::Builder::from_env(
|
|
env_logger::Env::default().default_filter_or("info")
|
|
).init();
|
|
|
|
log::info!("redbear-sessiond v{} starting", env!("CARGO_PKG_VERSION"));
|
|
log::debug!("config: {:#?}", config);
|
|
log::warn!("running as root");
|
|
log::error!(target: "session", "failed to create session: {}", err);
|
|
Ok(())
|
|
}
|
|
```
|
|
|
|
**Rationale:** `env_logger` reads `RUST_LOG`; output respects Unix log level conventions; can be redirected to syslog via env_logger's `target` feature.
|
|
|
|
### 4.3 Standard CLI Pattern
|
|
|
|
```rust
|
|
use clap::Parser;
|
|
use redbear_cli::{CommonArgs, init_logging};
|
|
|
|
#[derive(Parser, Debug)]
|
|
#[command(version, about, long_about = None)]
|
|
struct Args {
|
|
#[command(flatten)]
|
|
common: CommonArgs,
|
|
|
|
/// Path to config file
|
|
#[arg(short = 'c', long, env = "REDBEAR_CONFIG")]
|
|
config: std::path::PathBuf,
|
|
|
|
/// Run in foreground (don't daemonize)
|
|
#[arg(short = 'f', long)]
|
|
foreground: bool,
|
|
}
|
|
|
|
fn main() -> anyhow::Result<()> {
|
|
let args = Args::parse();
|
|
init_logging(&args.common);
|
|
log::info!("starting with config: {}", args.config.display());
|
|
Ok(())
|
|
}
|
|
```
|
|
|
|
**Rationale:** `clap` derive gives consistent `--help`, `--version`, env-var support. `CommonArgs` from `redbear-cli` provides standard `--verbose`, `--log-level`, `--config`.
|
|
|
|
### 4.4 Standard Config Pattern
|
|
|
|
```rust
|
|
use serde::Deserialize;
|
|
use std::path::{Path, PathBuf};
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
pub struct Config {
|
|
pub network: NetworkConfig,
|
|
pub power: PowerConfig,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
pub struct NetworkConfig {
|
|
pub dhcp: bool,
|
|
pub dns_servers: Vec<std::net::IpAddr>,
|
|
}
|
|
|
|
// XDG-compliant: ~/.config/redbear-<prog>/config.toml
|
|
pub fn config_path(program: &str) -> Option<PathBuf> {
|
|
dirs::config_dir().map(|p| p.join(program).join("config.toml"))
|
|
}
|
|
|
|
pub fn load(program: &str) -> Result<Config, ConfigError> {
|
|
let path = config_path(program)
|
|
.ok_or(ConfigError::NoConfigDir)?;
|
|
let text = std::fs::read_to_string(&path)?;
|
|
Ok(toml::from_str(&text)?)
|
|
}
|
|
```
|
|
|
|
**Rationale:** XDG paths via `dirs` crate; serde for typed parsing; toml for human-editable format. Avoids hardcoded `/etc/` paths.
|
|
|
|
### 4.5 Standard Workspace Pattern (for 5 WORKSPACE programs)
|
|
|
|
```toml
|
|
# outer Cargo.toml
|
|
[workspace]
|
|
members = ["source"]
|
|
resolver = "3"
|
|
|
|
[workspace.package]
|
|
version = "0.3.1"
|
|
edition = "2024"
|
|
license = "MIT"
|
|
repository = "https://gitea.redbearos.org/RedBear-OS/redbear-recipes"
|
|
rust-version = "1.89"
|
|
authors = ["Red Bear OS Contributors"]
|
|
|
|
[workspace.dependencies]
|
|
log = "0.4"
|
|
redox_syscall = { path = "../../../sources/syscall" }
|
|
libredox = { path = "../../../sources/libredox" }
|
|
redox-scheme = { path = "../../../sources/redox-scheme" }
|
|
xhcid = { path = "../../../sources/base/drivers/xhcid" }
|
|
common = { path = "../../../sources/base/drivers/common" }
|
|
|
|
[profile.release]
|
|
opt-level = 3
|
|
lto = "thin"
|
|
```
|
|
|
|
```toml
|
|
# source/Cargo.toml
|
|
[package]
|
|
name = "redbear-acmd"
|
|
version.workspace = true
|
|
edition.workspace = true
|
|
license.workspace = true
|
|
repository.workspace = true
|
|
|
|
[dependencies]
|
|
log = { workspace = true }
|
|
redox_syscall = { workspace = true }
|
|
libredox = { workspace = true }
|
|
# ...
|
|
```
|
|
|
|
**Rationale:** Single source of truth for version/edition/license; shared deps via `[workspace.dependencies]`; profile config in one place.
|
|
|
|
### 4.6 Standard Documentation Pattern (README template)
|
|
|
|
See § 7 below.
|
|
|
|
### 4.7 Standard License Metadata Pattern
|
|
|
|
```toml
|
|
license = "MIT"
|
|
repository = "https://gitea.redbearos.org/RedBear-OS/redbear-recipes"
|
|
description = "Red Bear OS Intel Wi-Fi driver (iwlwifi compatibility layer)"
|
|
keywords = ["redox", "redbear", "wifi", "driver"]
|
|
categories = ["hardware-support", "network-programming"]
|
|
```
|
|
|
|
Per Agent D findings: only 2/37 programs have these. Add to all.
|
|
|
|
---
|
|
|
|
## 5. ORPHAN RESOLUTION MATRIX
|
|
|
|
(See § 3C above for full table; summarized decision tree here.)
|
|
|
|
**Decision rule:**
|
|
1. If the recipe's `[package]` is **referenced as a build/runtime dep** in any other recipe → KEEP (the consuming recipe pulls it in via cookbook).
|
|
2. If the recipe is **library-only** (no `[[bin]]`) AND consumed via Cargo path dep → KEEP-ORPHAN (correct pattern).
|
|
3. If the recipe is **library-only** AND has no consumers → DOCUMENT OR REMOVE (per user authorization).
|
|
4. If the recipe is **data/firmware/headers only** AND superseded by a monolithic equivalent → KEEP-ORPHAN + status doc.
|
|
5. If the recipe has a **build artifact** (binary or shared lib) AND no consumers → WIRE to an appropriate config OR add explicit status doc.
|
|
|
|
**Specific resolutions:**
|
|
|
|
| Orphan | Rule | Decision | Concrete action |
|
|
|---|---|---|---|
|
|
| redbear-hid-core | Rule 2 (lib-only, no Cargo consumers) | KEEP-ORPHAN | Add to `local/AGENTS.md` § "Library-only Red Bear crates" |
|
|
| redbear-input-headers | Rule 5 (header-only, no consumers) | WIRE | Add as build dep of libevdev, libinput recipes |
|
|
| redbear-driver-policy | Rule 5 (data-only, no consumers) | WIRE | Add to `config/redbear-mini.toml` [packages] |
|
|
| redbear-firmware-amdgpu | Rule 4 (superseded) | KEEP-ORPHAN | Add `local/docs/FIRMWARE-SUBSETS-DECISION.md` |
|
|
| redbear-firmware-bluetooth | Rule 4 | KEEP-ORPHAN | Same doc |
|
|
| redbear-firmware-intel | Rule 4 | KEEP-ORPHAN | Same doc |
|
|
| redbear-firmware-iwlwifi | Rule 1 (referenced) | KEEP-ORPHAN | Used by redbear-iwlwifi driver (path dep) |
|
|
| redbear-passwd | Rule 3 (lib-only, no consumers) | WIRE | Add to `config/redbear-mini.toml` [packages]; OR add `[[bin]]` for passwd/chpasswd commands |
|
|
| redbear-tui-theme | Rule 5 (lib-only) | WIRE | Add `recipe.toml` (Phase 1.4) + add to `config/redbear-mini.toml` [packages] |
|
|
| redbear-ufw | Rule 5 (source-only, no recipe) | KEEP-ORPHAN | Add `local/docs/REDBEAR-UFW-STATUS.md` |
|
|
| redbear-login-protocol | Rule 2 (correct pattern) | KEEP-ORPHAN | Already documented; no action |
|
|
| redbear-btusb | Rule 5 (binary, no primary config) | KEEP (experimental) | Wired to `redbear-bluetooth-experimental.toml`; status: validation phase |
|
|
| redbear-btctl | Rule 5 | KEEP (experimental) | Same as above |
|
|
| redbear-iwlwifi | Rule 5 | KEEP (experimental) | Wired to `redbear-wifi-experimental.toml`; awaiting kernel integration |
|
|
|
|
**Verification:** After Phase 3C, run `grep -L "redbear-" config/redbear-*.toml` to ensure every redbear-* recipe has at least one config reference (explicit KEEP-ORPHAN documented OR active wire-up).
|
|
|
|
---
|
|
|
|
## 6. INTERFACE STANDARDIZATION PLAN
|
|
|
|
### 6.1 Required CLI flags (every binary-producing program)
|
|
|
|
| Flag | Env var | Purpose | Required |
|
|
|---|---|---|---|
|
|
| `-h, --help` | — | Print help | YES |
|
|
| `-V, --version` | — | Print version (from `env!("CARGO_PKG_VERSION")`) | YES |
|
|
| `-v, --verbose` | `RUST_LOG` | Increase log verbosity (-v=debug, -vv=trace) | YES |
|
|
| `--config <PATH>` | `REDBEAR_CONFIG` | Override config file path | YES (for daemons) |
|
|
| `--log-level <LEVEL>` | `RUST_LOG` | Set log filter directly | YES (for daemons) |
|
|
| `--foreground` / `--daemon` | — | Run in foreground (don't daemonize) | YES (for daemons) |
|
|
|
|
Implemented via `redbear-cli` crate (see § 4.3).
|
|
|
|
### 6.2 Required scheme interface (programs with scheme)
|
|
|
|
```rust
|
|
use redox_scheme::{Scheme, SchemeSync, Signal};
|
|
|
|
pub struct FooScheme {
|
|
// ...
|
|
}
|
|
|
|
impl SchemeSync for FooScheme {
|
|
fn handle(&mut self, message: &[u8]) -> HandleResult {
|
|
// ...
|
|
}
|
|
}
|
|
|
|
// Registration:
|
|
let socket = "/scheme/foo";
|
|
let mut scheme = FooScheme::new();
|
|
libredox::call::setrens(0, 0).unwrap();
|
|
redox_scheme::register_sync_scheme(socket, &mut scheme)?;
|
|
```
|
|
|
|
Scheme name MUST match: kebab-case, lowercase, no `redbear-` prefix (scheme names go in `/scheme/<name>/`, e.g. `/scheme/wifi/`, not `/scheme/redbear-wifi/`).
|
|
|
|
### 6.3 Required D-Bus interface (zbus programs)
|
|
|
|
| Element | Required |
|
|
|---|---|
|
|
| Bus selection | `session` or `system` (no mixed) |
|
|
| Well-known name | `org.freedesktop.*` for standard specs, `org.kde.*` for KDE, `org.redbear.*` for custom |
|
|
| Object path | Lower-case, dash-separated: `/org/freedesktop/login1` |
|
|
| Interface name | Match well-known name exactly |
|
|
| Method docs | zbus `#[interface]` doc comments required on every method |
|
|
| Service file | In `redbear-dbus-services/files/{system,session}-services/<name>.service` |
|
|
| zbus version | Pinned via `[workspace.dependencies]`: `zbus = "5"` |
|
|
|
|
### 6.4 Required config interface
|
|
|
|
```rust
|
|
use serde::Deserialize;
|
|
use std::path::PathBuf;
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
pub struct Config {
|
|
// program-specific fields
|
|
}
|
|
|
|
pub fn default_config_path(program: &str) -> Option<PathBuf> {
|
|
dirs::config_dir().map(|p| p.join("redbear").join(program).join("config.toml"))
|
|
}
|
|
```
|
|
|
|
Programs MUST:
|
|
- Use XDG-compliant config path via `dirs::config_dir()` (NOT hardcoded `/etc/`)
|
|
- Support `--config <PATH>` override
|
|
- Provide compiled-in defaults when config file absent
|
|
- Document reload behavior (SIGHUP, file-watch, restart-only)
|
|
|
|
Currently only `redbear-power` follows this; 36 programs violate it.
|
|
|
|
---
|
|
|
|
## 7. DOCUMENTATION TEMPLATE (for all 47 recipes)
|
|
|
|
```markdown
|
|
# redbear-<name>
|
|
|
|
> One-line purpose (≤80 chars).
|
|
|
|
**Status:** [PRODUCTION-READY | FEATURE-INCOMPLETE | EARLY-WIP | STUB-DATA]
|
|
**Maintainer:** @<handle>
|
|
**Last verified:** YYYY-MM-DD (commit `<hash>`)
|
|
|
|
## Purpose
|
|
What problem this program solves. What surface it provides (daemon / CLI / library / scheme / D-Bus / data). What consumes it.
|
|
|
|
## Build
|
|
```bash
|
|
# If wired to redbear-mini/redbear-full:
|
|
./local/scripts/build-redbear.sh redbear-mini
|
|
|
|
# If orphan/experimental (only builds when explicitly invoked):
|
|
COOKBOOK_TARGET=redbear-<name> ./local/scripts/build-redbear.sh --upstream
|
|
```
|
|
|
|
## Runtime
|
|
|
|
### Init service
|
|
Path: `/usr/lib/init.d/<N>_<name>.service` (if applicable).
|
|
Enabled by: which config.
|
|
Manual start: `init-svc start <name>`.
|
|
|
|
### Configuration
|
|
Format: TOML.
|
|
Path: `~/.config/redbear/<name>/config.toml` (XDG) or `/etc/redbear/<name>.toml` (system).
|
|
Env overrides: `<PROG>_<KEY>=value`.
|
|
Reload: `<SIGHUP | restart-only | file-watch>`.
|
|
|
|
### Logging
|
|
Destination: `stderr` (default) or `/var/log/<name>.log` (configurable).
|
|
Level: controlled by `RUST_LOG` env var or `--log-level` flag.
|
|
Debug flag: `--verbose` increases verbosity.
|
|
|
|
## Interface
|
|
|
|
### CLI (if any)
|
|
```text
|
|
redbear-<name> [COMMON-OPTIONS] [PROGRAM-OPTIONS] [ARGS]
|
|
|
|
Common options (from redbear-cli):
|
|
-h, --help Print help
|
|
-V, --version Print version
|
|
-v, --verbose Increase verbosity
|
|
--config <PATH> Config file path
|
|
--log-level <LEVEL> Log filter (error/warn/info/debug/trace)
|
|
|
|
Examples:
|
|
$ redbear-<name> --verbose
|
|
$ redbear-<name> --config /etc/redbear/<name>.toml
|
|
```
|
|
|
|
### Scheme (if any)
|
|
Path: `/scheme/<name>/`.
|
|
Handle kinds: `<Root, Resource, ...>`.
|
|
|
|
### D-Bus (if any)
|
|
Bus: `system` | `session`.
|
|
Well-known name: `org.<domain>.<interface>`.
|
|
Object paths: `/<object-path>`.
|
|
|
|
## Architecture
|
|
|
|
Brief module structure. Key types. Error types. Threading model.
|
|
|
|
## Consumers
|
|
- `redbear-<consumer-1>`: uses `<API>`
|
|
- `redbear-<consumer-2>`: ...
|
|
|
|
## Build dependencies
|
|
- `redox-driver-sys`
|
|
- `linux-kpi`
|
|
- ...
|
|
|
|
## Runtime dependencies
|
|
- `<scheme or D-Bus services that must be running>`
|
|
- ...
|
|
|
|
## Status notes
|
|
|
|
List known gaps, TODOs, hardware-validation status.
|
|
|
|
## References
|
|
|
|
- `local/docs/<plan>.md` (e.g. CONSOLE-TO-KDE-DESKTOP-PLAN.md)
|
|
- Upstream: `<upstream repo URL>`
|
|
- Spec: `<standard spec URL>`
|
|
```
|
|
|
|
---
|
|
|
|
## 8. WORKSPACE CONSOLIDATION PATTERN
|
|
|
|
The 5 WORKSPACE-style programs (redbear-acmd, redbear-ecmd, redbear-ftdi, redbear-usbaudiod, redbear-usb-hotplugd) all need:
|
|
|
|
**Outer `Cargo.toml`:**
|
|
|
|
```toml
|
|
[workspace]
|
|
members = ["source"]
|
|
resolver = "3"
|
|
|
|
[workspace.package]
|
|
version = "0.3.1"
|
|
edition = "2024"
|
|
license = "MIT"
|
|
repository = "https://gitea.redbearos.org/RedBear-OS/redbear-recipes"
|
|
rust-version = "1.89"
|
|
|
|
[workspace.dependencies]
|
|
# Cross-cutting Redox crates (path-pinned to local forks per AGENTS.md)
|
|
redox_syscall = { path = "../../../sources/syscall" }
|
|
libredox = { path = "../../../sources/libredox" }
|
|
redox-scheme = { path = "../../../sources/redox-scheme" }
|
|
|
|
# USB class driver shared crates (from base fork)
|
|
xhcid = { path = "../../../sources/base/drivers/xhcid" }
|
|
common = { path = "../../../sources/base/drivers/common" }
|
|
|
|
# Common utility crates
|
|
log = "0.4"
|
|
|
|
[profile.release]
|
|
opt-level = 3
|
|
lto = "thin"
|
|
```
|
|
|
|
**Inner `source/Cargo.toml`:**
|
|
|
|
```toml
|
|
[package]
|
|
name = "redbear-acmd"
|
|
version.workspace = true
|
|
edition.workspace = true
|
|
license.workspace = true
|
|
repository.workspace = true
|
|
description = "USB CDC ACM serial driver daemon"
|
|
|
|
[dependencies]
|
|
redox_syscall = { workspace = true }
|
|
libredox = { workspace = true }
|
|
redox-scheme = { workspace = true }
|
|
xhcid = { workspace = true }
|
|
common = { workspace = true }
|
|
log = { workspace = true }
|
|
|
|
[[bin]]
|
|
name = "redbear-acmd"
|
|
path = "src/main.rs"
|
|
```
|
|
|
|
**Verification per program:** `cat Cargo.toml | grep "^\[workspace.package\]"` returns 1 line; `cat source/Cargo.toml | grep "version.workspace"` returns 1 line.
|
|
|
|
---
|
|
|
|
## 9. ANOMALY RESOLUTION
|
|
|
|
### 9.1 redbear-netctl-console — Missing `[package] name`
|
|
|
|
**File:** `local/recipes/system/redbear-netctl-console/recipe.toml`
|
|
|
|
**Action:** Add to existing `[package]` section:
|
|
|
|
```toml
|
|
[package]
|
|
name = "redbear-netctl-console"
|
|
version = "0.3.1"
|
|
```
|
|
|
|
**Verification:** `cat recipe.toml | grep -E "^name = \"redbear-netctl-console\""` returns 1 line; `cargo cook redbear-netctl-console` succeeds.
|
|
|
|
### 9.2 redox-drm — Same defect
|
|
|
|
**File:** `local/recipes/gpu/redox-drm/recipe.toml`
|
|
|
|
**Action:** Add `name` and `version` to `[package]` section.
|
|
|
|
**Verification:** Same as 9.1.
|
|
|
|
### 9.3 redbear-netstat — Vestigial nested duplicate
|
|
|
|
**Anomaly:** `local/recipes/system/redbear-netstat/redbear-netstat/source/Cargo.toml` duplicates `source/Cargo.toml`. The nested dir is NOT consumed by build (recipe points to `source/`).
|
|
|
|
**Action:** `rm -rf local/recipes/system/redbear-netstat/redbear-netstat/`
|
|
|
|
**Verification:** `find local/recipes/system/redbear-netstat -name Cargo.toml` shows only `source/Cargo.toml`.
|
|
|
|
### 9.4 redbear-tui-theme — Missing recipe.toml
|
|
|
|
**Anomaly:** `local/recipes/tui/redbear-tui-theme/source/Cargo.toml` exists, symlink exists at `recipes/tui/redbear-tui-theme → ../../local/recipes/tui/redbear-tui-theme`, but no recipe.toml means cookbook cannot cook it.
|
|
|
|
**Action:** Create `local/recipes/tui/redbear-tui-theme/recipe.toml`:
|
|
|
|
```toml
|
|
[package]
|
|
name = "redbear-tui-theme"
|
|
version = "0.3.1"
|
|
|
|
[source]
|
|
path = "source"
|
|
|
|
[build]
|
|
template = "cargo"
|
|
```
|
|
|
|
**Verification:** `cat recipe.toml` shows the above; `cargo cook redbear-tui-theme` succeeds.
|
|
|
|
### 9.5 redbear-ufw — Unreleased prototype in base fork
|
|
|
|
**Anomaly:** `local/sources/base/redbear-ufw/` contains Cargo.toml + src/main.rs but no recipe.toml. The program is intentionally NOT built.
|
|
|
|
**Action:** Per AGENTS.md NEVER DELETE rule, do NOT delete the source. Either:
|
|
|
|
- **Option A** (recommended): Add `local/recipes/system/redbear-ufw/recipe.toml` to make it buildable, then wire to `redbear-netctl-experimental.toml` (it's a firewall).
|
|
- **Option B**: Add `local/docs/REDBEAR-UFW-STATUS.md` explicitly documenting: "Red Bear UFW is an unreleased prototype in `local/sources/base/redbear-ufw/`. Per AGENTS.md NEVER DELETE rule, the source is preserved. No recipe.toml exists; it is not part of any current build."
|
|
|
|
**Recommendation:** Option B — the prototype is in the base fork and may need to be re-integrated or removed when base is upgraded. Adding a recipe would bind it to current Redox sysroot which may not be appropriate.
|
|
|
|
**Verification:** Either `recipe.toml` exists and cook succeeds, OR `local/docs/REDBEAR-UFW-STATUS.md` exists with the explicit status text.
|
|
|
|
### 9.6 pam-redbear — Version drift
|
|
|
|
**File:** `local/recipes/libs/pam-redbear/source/Cargo.toml`
|
|
|
|
**Action:** Change `version = "0.2.3"` → `version = "0.3.1"`.
|
|
|
|
**Verification:** `grep version Cargo.toml` shows `0.3.1`; `local/scripts/sync-versions.sh --check` exits 0.
|
|
|
|
### 9.7 5 edition-2021 programs
|
|
|
|
Change `edition = "2021"` → `edition = "2024"` in:
|
|
|
|
1. `local/recipes/system/redbear-accessibility/source/Cargo.toml`
|
|
2. `local/recipes/system/redbear-ime/source/Cargo.toml`
|
|
3. `local/recipes/system/redbear-keymapd/source/Cargo.toml`
|
|
4. `local/recipes/tui/redbear-tui-theme/source/Cargo.toml` (Phase 1.4 prerequisite)
|
|
5. `local/recipes/wayland/redbear-compositor/source/Cargo.toml`
|
|
|
|
**Verification:** `grep "^edition = \"2021\"" local/recipes -r` returns 0 matches.
|
|
|
|
---
|
|
|
|
## 10. VERIFICATION CHECKLIST
|
|
|
|
### Per-phase gates
|
|
|
|
#### Phase 1 (CRITICAL)
|
|
|
|
| Check | Command | Expected |
|
|
|---|---|---|
|
|
| Build succeeds | `./local/scripts/build-redbear.sh redbear-mini` | Exit 0 |
|
|
| No drift | `./local/scripts/sync-versions.sh --check` | Exit 0 |
|
|
| Vestigial gone | `find local/recipes/system/redbear-netstat -name Cargo.toml \| wc -l` | 1 |
|
|
| Both anomalies addressed | `ls local/recipes/tui/redbear-tui-theme/recipe.toml local/docs/REDBEAR-UFW-STATUS.md 2>/dev/null \| wc -l` | ≥1 |
|
|
|
|
#### Phase 2 (HIGH)
|
|
|
|
| Check | Command | Expected |
|
|
|---|---|---|
|
|
| All programs edition=2024 | `grep -r "^edition = \"2021\"" local/recipes/ \| wc -l` | 0 |
|
|
| All programs have license | `find local/recipes -path "*redbear-*/source/Cargo.toml" -exec grep -L "^license" {} \; \| wc -l` | 0 |
|
|
| All programs have repository | `find local/recipes -path "*redbear-*/source/Cargo.toml" -exec grep -L "^repository" {} \; \| wc -l` | 0 |
|
|
| Logging migrated | `find local/recipes -path "*redbear-*/source/src" -name "*.rs" -exec grep -l "println!" {} \; \| wc -l` | <10 (TUI-only allowed) |
|
|
| Error handling migrated | `find local/recipes -path "*redbear-*/source/src" -name "*.rs" -exec grep -c "\.unwrap()" {} \; \| awk '{s+=$1} END{print s}'` | <500 (was 1042) |
|
|
| No panic! in daemons | `grep -l "panic!" local/recipes/system/redbear-{sessiond,authd,greeter,polkit,udisks,upower}/source/src/main.rs \| wc -l` | 0 |
|
|
| tokio minimal | `grep -l "features = \[\"full\"\]" local/recipes -r --include="Cargo.toml" \| grep redbear- \| wc -l` | 0 |
|
|
|
|
#### Phase 3 (MEDIUM)
|
|
|
|
| Check | Command | Expected |
|
|
|---|---|---|
|
|
| All 5 WORKSPACE programs have [workspace.package] | `for d in local/recipes/system/redbear-{acmd,ecmd,ftdi,usbaudiod,usb-hotplugd}; do grep -l "\[workspace.package\]" "$d/Cargo.toml"; done \| wc -l` | 5 |
|
|
| All 47 recipes wired or documented | `for r in $(find local/recipes -maxdepth 3 -type d -name "redbear-*" \| sort -u); do prog=$(basename $r); if ! grep -rq "$prog" config/ 2>/dev/null && [ ! -f "local/docs/REDBEAR-UFW-STATUS.md" ]; then echo "$prog"; fi; done \| wc -l` | 0 |
|
|
| Massive files split | `wc -l local/recipes/system/redbear-info/source/src/main.rs local/recipes/wayland/redbear-compositor/source/src/main.rs local/recipes/system/redbear-netctl/source/src/main.rs` | All <500 |
|
|
| Shared CLI crate exists | `test -f local/recipes/system/redbear-cli/source/Cargo.toml && echo OK` | OK |
|
|
| Clap usage | `find local/recipes -path "*redbear-*/source" -name "*.rs" -exec grep -l "use clap" {} \; \| wc -l` | ≥28 |
|
|
| --version works | `./target/release/redbear-info --version 2>&1 \| head -1` | Print version |
|
|
|
|
#### Phase 4 (LOW)
|
|
|
|
| Check | Command | Expected |
|
|
|---|---|---|
|
|
| All 47 recipes have README | `find local/recipes -path "*redbear-*/README.md" \| wc -l` | 47 |
|
|
| Operator runbooks | `ls local/docs/operator-runbooks/ \| wc -l` | ≥7 |
|
|
| D-Bus interface docs | `ls local/docs/dbus-interfaces/ \| wc -l` | ≥6 |
|
|
| Per-program AGENTS.md entries | `grep -c "^## redbear-\|^- redbear-" local/AGENTS.md` | ≥47 |
|
|
| CI runs | `.github/workflows/redbear-ci.yml` exists; CI green on push | green |
|
|
| cargo fmt clean | `for f in $(find local/recipes -path "*redbear-*/source/Cargo.toml"); do cargo fmt --manifest-path "$f" -- --check; done \| wc -l` | 0 failures |
|
|
| cargo clippy clean | `for f in $(find local/recipes -path "*redbear-*/source/Cargo.toml"); do cargo clippy --manifest-path "$f" -- -D warnings; done \| wc -l` | 0 failures |
|
|
|
|
---
|
|
|
|
## 11. RISKS AND NEVER-DO LIST (per AGENTS.md)
|
|
|
|
### NEVER DO (per AGENTS.md absolute rules)
|
|
|
|
1. **NEVER DELETE** any `redbear-*` package, config, service, or file — even if it seems unused, "too heavy", or "not needed". Per `AGENTS.md § ABSOLUTE RULE — NEVER DELETE`. Always keep and fix.
|
|
2. **NEVER set** any package to `"ignore"` because it seems unneeded. Per `AGENTS.md § ABSOLUTE RULE`.
|
|
3. **NEVER comment out** a package or service to "clean up". Per `AGENTS.md § ABSOLUTE RULE`.
|
|
4. **NEVER remove build tools** to reduce image size. Per `AGENTS.md § ABSOLUTE RULE`.
|
|
5. **NEVER add stubs, workarounds, fake headers, sed hacks, or LD_PRELOAD tricks**. Per `AGENTS.md § STUB AND WORKAROUND POLICY`.
|
|
6. **NEVER use `unwrap()`/`expect()` in library/driver code**. Per `AGENTS.md § ANTI-PATTERNS`.
|
|
7. **NEVER modify kernel syscall ABI directly** — use `libredox` or `relibc`.
|
|
8. **NEVER use `-rb` suffix** — must be `+rb` (Cargo build metadata). Per `AGENTS.md § CONVENTIONS`.
|
|
9. **NEVER put drivers in kernel space** — all drivers are userspace daemons.
|
|
10. **NEVER hardcode `/dev/` paths** — use scheme paths.
|
|
11. **NEVER remove patches** to fix build failures — rebase them. Per `AGENTS.md § PATCH-GOVERNANCE`.
|
|
12. **NEVER remove BINS entries** to fix build failures — fix the source. Per `AGENTS.md § PATCH-GOVERNANCE`.
|
|
13. **NEVER bypass the canonical build** — always use `./local/scripts/build-redbear.sh`. Per `AGENTS.md § CANONICAL BUILD POLICY`.
|
|
14. **NEVER speculate about unread code** — read before writing.
|
|
15. **NEVER commit without explicit user request**.
|
|
16. **NEVER use `background_cancel(all=true)`** — cancel individually.
|
|
|
|
### Soft Guidelines (project preferences)
|
|
|
|
17. **PREFER `redox-scheme`** for scheme IPC over custom implementations.
|
|
18. **PREFER `zbus`** over raw `dbus` for D-Bus integration.
|
|
19. **PREFER `serde` + TOML** for config files.
|
|
20. **PREFER `dirs` crate** for XDG path resolution.
|
|
21. **PREFER `clap` derive** over hand-rolled CLI.
|
|
22. **PREFER `log` + `env_logger`** over `println!`.
|
|
23. **PREFER thiserror** for library errors, anyhow for binary errors.
|
|
24. **PREFER workspace dependencies** over per-member duplication.
|
|
25. **PREFER module splits** over single-file programs >500 lines.
|
|
|
|
### Risk Assessment for this Plan
|
|
|
|
| Risk | Likelihood | Mitigation |
|
|
|---|---|---|
|
|
| Edition 2024 breakage (lifetime capture changes) | LOW | Test per-program; the 5 programs are small |
|
|
| Logging migration breaks behavior | LOW | Test suite covers most programs; manual QA for visual output |
|
|
| Workspace migration breaks build | MEDIUM | Phase 1 prerequisite: vet `[workspace.package]` against existing fields |
|
|
| tokio feature downgrade breaks async | LOW | Test program-by-program; the signal handler is the breaking piece |
|
|
| Orphan wiring breaks init sequence | LOW | Each orphan gets explicit config-wiring test |
|
|
| Massive file split breaks compilation | MEDIUM | Mechanical refactor; preserve API surface; test after each move |
|
|
| CI workflow too slow | MEDIUM | Use cargo workspace at root to dedupe dep graph; cache target/ |
|
|
| Damage to release archive (sources/redbear-0.1.0/) | LOW | This plan operates on `local/recipes/`, NOT the immutable archive |
|
|
| Loss of source-immutable durable state | LOW | All source-tree edits go through `local/patches/` per AGENTS.md DURABILITY POLICY |
|
|
| Build-redbear.sh invocation breaks | LOW | Test at each phase gate using the canonical wrapper |
|
|
|
|
### Per-Phase Risk
|
|
|
|
- **Phase 1 (additive only)**: Near-zero risk.
|
|
- **Phase 2 (refactors error/log)**: Low risk; mechanical changes with test coverage.
|
|
- **Phase 3 (structural changes)**: Medium risk; requires careful testing at each step.
|
|
- **Phase 4 (docs/CI)**: Near-zero risk to runtime; docs-only.
|
|
|
|
---
|
|
|
|
## SUMMARY
|
|
|
|
This plan delivers, in 8 weeks with ~37 person-days, the transformation of 47 `redbear-*` programs from "functionally broad but inconsistent" to a coherent, documented, idiomatic Rust ecosystem aligned with AGENTS.md policies.
|
|
|
|
**Critical wins:**
|
|
|
|
1. 5 build-blockers fixed (redbear-netctl-console name field, redox-drm name field, pam-redbear version, redbear-tui-theme recipe.toml, redbear-ufw status doc)
|
|
2. 1 vestigial duplicate deleted (redbear-netstat nested)
|
|
3. All 37 source `Cargo.toml` files gain `license`, `repository`, edition 2024
|
|
4. All 27 println-heavy programs migrate to `log` crate
|
|
5. 13 score-1 programs reduce unwrap/expect/panic surface by ~50%
|
|
6. 5 WORKSPACE programs gain `[workspace.package]` + `[workspace.dependencies]`
|
|
7. 13 orphans get explicit decision (wire / keep-orphan with status doc)
|
|
8. 3 massive single-file programs split into modules
|
|
9. All 47 recipes gain README.md
|
|
10. CI integration added
|
|
|
|
**Estimated total effort:** 37 person-days across 8 weeks.
|
|
|
|
**Constraint compliance:** No deletions (NEVER DELETE rule), no stubs (STUB POLICY), no language policy violations (Rust-only for new code), all changes use canonical build, all durability concerns addressed via patches.
|
|
|
|
**First action:** Run `./local/scripts/sync-versions.sh --check` to confirm baseline state, then proceed to Phase 1.1 (redbear-netctl-console name field fix).
|