The redbear-compositor had BOTH pre-existing compile errors AND
the round-4 audit items. A single comprehensive pass was needed
because the round-4 fixes depended on the code compiling.
Pre-existing compile errors (blocking, unrelated to the audit):
- ? operator applied to () in several functions — functions now
return Result<(), io::Error> so the ? is well-typed.
- Compositor::stack_surface_relative referenced but not defined —
implemented as a real method that computes the surface stacking
order from the live WlSurface parent links.
- Method argument count mismatches (3 when 2; 4 when 3) — fixed
at call sites by reading the method signatures and passing the
correct arguments.
W1 — let _ = stream.write_all(&msg) (14 sites in main.rs):
Replaced with if let Err(err) = ... { ... } that logs via eprintln!
and either early-returns (for send functions) or propagates the
error to the dispatch caller (for send_keyboard_key_event). The
caller's read loop detects the dead stream and breaks. Eliminates
the silent desync vector on partial/failed writes.
W2 — unreachable!() in Wayland opcode dispatch (2 sites):
Replaced with return Err(format!("...")). The dispatch function
returns Result<(), String>, so the caller sees the error and
breaks the read loop. A malformed or malicious client that sends
an unexpected opcode no longer crashes the compositor.
W3 — let _ = self.send_keyboard_key_event(...):
Replaced with if let Err(err) = ... { return Err(err); } — error
propagates to the dispatch caller. Same fix pattern as W1.
Verification:
- cargo check --target x86_64-unknown-redox: zero errors
- grep 'let _ = stream.write_all' main.rs: 0 (was 14)
- grep 'unreachable!' main.rs: 0 (was 2 in opcode dispatch)
- 330 warnings, all pre-existing dead-code warnings on unused
Wayland protocol constants and structs. No new warnings
introduced.
Also moved local/docs/SYSTEM-STABILITY-AND-UPSTREAM-SYNC-PLAN.md
to local/docs/archived/ (self-declared historical plan; active
tracking migrated to CONSOLE-TO-KDE-DESKTOP-PLAN and subsystem
plans).
- **Action:** Add `0x1C => { buf.extend_from_slice(b"\n"); }` in the key_event.pressed match block
- **Linux reference:** `drivers/tty/vt/keyboard.c:1421-1426` — Linux's `kbd_keycode()` → `K_ENTER` translation; the principle is identical: keycode → byte sequence injection
#### Commit 2: 5701459d — "Use font height rather than width" (2026-05-24)
**What it does:** Fixes text corruption in console-draw. The `char()` function used font width (8) instead of font height (16) when calculating font index, corrupting character glyph extraction for multi-byte characters.
**Red Bear current state:** VERIFY. The file at lines 215-217 shows:
```rust
letfont_i=16*(characterasusize);
iffont_i+16<=FONT.len(){
forrowin0..16{
```
This uses 16 (height) correctly. If confirmed, mark as ✅.
**If missing:**
- **File:** `local/sources/base/drivers/graphics/console-draw/src/lib.rs`, function `char()`
- **Action:** Change `let font_i = font.width() * (character as usize)` → `let font_i = 16 * (character as usize)`. Similarly change all references from `font.width()` to `font.height()` (which resolves to 16 for the standard 8×16 VGA font).
- **Linux reference:** `drivers/video/fbdev/core/bitblit.c:288-310` — `bit_putcs()` uses `font->height` consistently; Linux never confuses font width with font height
- **Verification:** Type characters 128-255 (extended ASCII). If accented characters render correctly, the fix is applied. If they show as random glyph fragments, the fix is missing.
#### Commit 3: f0ff6a79 — "buffer TextScreen writes while display map is unavailable" (2026-07-06)
**What it does:** When the display map is not yet available (during handoff/resize), buffer writes instead of dropping them. Flush after handoff completes.
**Red Bear current state:** VERIFY. The file at lines 13, 23, 132-176 shows:
```rust
pending_writes: Vec<Vec<u8>>,// line 13
// line 139-147: buffer when map is None
// line 152-176: flush_pending_writes()
```
This appears already applied. If confirmed, mark as ✅.
- **Action:** Add `pending_writes: Vec<Vec<u8>>` field to `TextScreen` struct, buffer writes when `self.display.map.is_none()`, flush in `handle_handoff()` when map becomes available.
- **Linux reference:** `drivers/tty/vt/vt.c:2920-2945` — Linux's `do_con_write()` buffers input when console is not yet fully initialized; the concept of "buffer until ready" is proven
- **Verification:** Boot log should NOT show "fbcond: TextScreen::write() called while display map is None" warnings followed by lost boot messages. Early boot messages should appear after handoff.
#### Commit 4: e8f1b1a8 — "Do not send TextInputEvent for control characters" (2026-06-09)
**What it does:** Filters control characters from being emitted as text input events. Must be paired with commit d1b51888 (Enter handler) because Enter (`\n`) would otherwise be filtered as a control character.
**Red Bear current state:** VERIFY. Check if fbcond filters control characters (U+0000–U+001F, U+007F). The text.rs file at line 40-41 tracks `self.ctrl` for scancode 0x1D, and line 99 checks `c != '\0'`. A broader control-character filter may be needed.
- **Action:** After character translation, skip emission if `c.is_control() && c != '\n'`. The `\n` (Enter) must be emitted — it was already handled by the 0x1C scancode branch.
- **Linux reference:** `drivers/tty/vt/keyboard.c:1305-1315` — with `kbd->kbdmode == VC_UNICODE`, control characters are not directly emitted as Unicode; they are translated to escape sequences or terminal actions
- **Verification:** Press Ctrl+C in the console. The terminal should receive `\x03` (ETX), not the literal character 'c'.
#### Commit 5: c3789b4e — "only perform a single write and assert the amount written" (2026-06-17)
**What it does:** Changes the console output path to use a single atomic write with an assertion on the written byte count, replacing a loop that could produce interleaved output.
**Red Bear current state:** VERIFY. Check the `write()` method in text.rs (line 132-150). The current implementation writes `buf` in one call and returns `Ok(buf.len())`. If this is already a single-write pattern, mark as ✅.
- **Action:** Replace any multi-call write loop with a single `self.inner.write(map, buf, &mut self.input)` call that asserts `written == buf.len()`.
- **Linux reference:** `drivers/tty/tty_io.c:1130-1150` — `do_tty_write()` writes in a loop for partial writes, but the Linux tty layer guarantees atomic line writes via `ldisc` operations
**Estimated time:** 2–4 hours to verify all 5 commits, apply any missing ones.
**Dependencies:** None.
### 1.2 Fix Orphan `}` in xhcid/src/xhci/mod.rs
**Context:** The xhcid USB controller driver has 32 uncommitted WIP changes in the base fork. One of these may have introduced a structural issue in the mod.rs file.
**Context:**`build-redbear.sh` is supposed to detect stale prefix toolchains and trigger a rebuild. However, the docs say it "warns when prefix is stale" but it's unclear if it actually triggers the rebuild. Verify and harden.
**File:**`local/scripts/build-redbear.sh`
**Action:**
1. Verify that staleness detection correctly compares `local/sources/<fork>/.git/HEAD` commit timestamps against `prefix/x86_64-unknown-redox/lib/rustlib/x86_64-unknown-redox/lib/libc.a` mtime
2. Verify that when stale, the script actually runs `make prefix` before proceeding
3. Add explicit "Prefix is stale — rebuilding..." and "Prefix rebuild complete" log messages
4. Add CI flag `REDBEAR_SKIP_PREFIX_CHECK=1` for environments where prefix is known-good
5. Document the exact detection logic in `local/docs/BUILD-SYSTEM-IMPROVEMENTS.md`
**Linux reference:** Linux kernel `Makefile:1310-1350` — `include/config/kernel.release` is the "staleness gate"; if any `Kconfig` or `Makefile` dependency is newer than the release file, the build system reconfigures. The same concept applies: if any fork commit is newer than the compiled prefix artifact, rebuild.
**Estimated time:** 1–2 hours
**Dependencies:** None.
### 1.4 Sync All Cat 2 Fork Versions to `+rb0.3.1`
**Context:** Branch 0.3.1 was cut but not all forks have been version-bumped. Version drift between `Cargo.toml` fields causes Cargo resolver errors and subtle type mismatches.
- Every Cat 2 fork's `Cargo.toml` must have `version = "<upstream>+rb0.3.1"`
- Every Cat 1 crate's `Cargo.toml` must have `version = "0.3.1"`
-`cargo build` from the workspace root passes with no version mismatch warnings
**Estimated time:** 15 minutes (automated)
**Dependencies:** None.
### 1.5 Stabilize Base Fork: Audit and Commit 32 WIP Changes
**Context:** The base fork (`local/sources/base/`, `submodule/base` branch) has ~32 uncommitted WIP changes across netstack (IPv6), USB quirks, and other subsystems. These are unstaged changes in the working tree that prevent clean builds and introduce non-deterministic behavior.
**Files involved:** The full `local/sources/base/` directory under the `submodule/base` branch.
**Action:**
1.`cd local/sources/base && git status --short` — catalog all uncommitted changes
2. Categorize each change:
- **Ready** — change is stable, tests pass, commit it
- **WIP** — change is in progress, stash it to a named stash or temporary branch, then commit only the stable parts
- **Broken** — change introduces regressions, revert it (keep diff in `local/docs/evidence/` for reference)
3. For each Ready change: write a focused commit message, commit to `submodule/base`
4. For WIP changes: create a `local/docs/evidence/base-wip-changes-2026-07-08.diff` snapshot, then `git stash`
**What it does:** Upstream userutils commit 2834434 updated getty to use the standard POSIX `ptsname()`, `grantpt()`, and `unlockpt()` functions instead of raw redox-specific PTY manipulation. This is the upstream approach to PTY management — it uses the standard C library API rather than raw scheme calls.
**Red Bear current state:** The local fork at `local/sources/userutils/src/bin/getty.rs` (285 lines) uses `libredox::call as redox` with raw `redox::read()`/`redox::write()` calls (lines 63-80). It does NOT use the standard POSIX PTY functions.
**Action:**
1. Fetch upstream commit 2834434 from `https://gitlab.redox-os.org/redox-os/userutils`
2. Cherry-pick onto the `submodule/userutils` branch
3. Resolve conflicts (if any)
4. Verify: `cargo build` in `local/sources/userutils/`
5. Push to `submodule/userutils` branch
6. Update parent repo submodule pointer
7. Rebuild prefix: `touch relibc && make prefix` (std PTY functions need to be in libc.a)
8. Full image: `./local/scripts/build-redbear.sh redbear-mini`
**Linux reference:**
-`glibc/sysdeps/unix/sysv/linux/ptsname.c` — Linux implements `ptsname()` via `/dev/pts/<n>` enumeration
- The POSIX standard pattern: `posix_openpt(O_RDWR | O_NOCTTY) → grantpt(fd) → unlockpt(fd) → ptsname(fd) → open(slave_name)`. This is the same pattern relibc should expose via its cbindgen-generated `stdlib.h`.
**Verification:** After login, `tty` command should show a `/dev/pts/N` device (not a raw scheme path).
**Estimated time:** 2–4 hours
**Dependencies:** Phase 1.5 (stable base fork), Phase 2.1 (console works).
### 2.3 Add Comprehensive Keymap Handling to fbcond
**Context:** fbcond currently has a hardcoded US keyboard layout with scancode→key mappings for basic keys (Enter, Backspace, arrows, Home, End, etc. — lines 43-104 of text.rs). There is no configurable keymap support.
**Action:**
1. Add a `Keymap` struct that loads layout definitions from a TOML file (`/etc/fbcond/keymap.toml`)
2. Replace the hardcoded `match key_event.scancode { ... }` with a table-driven lookup
3. Default keymap: US QWERTY (current hardcoded mappings)
4. Support at minimum: US, UK, DE, FR layouts
5. Keymap format:
```toml
[keymap]
name="us"
[keys."0x1C"]
pressed="\n"
[keys."0x0E"]
pressed="\x7F"
[keys."0x47"]
pressed="\x1B[H"
```
**Linux reference:**
-`drivers/tty/vt/defkeymap.map` — Linux's default keymap in `loadkeys` format
-`drivers/tty/vt/keyboard.c:1050-1100` — `kbd_keycode()` dispatches via keymap table; the pattern is: scancode → keycode → (shift/altgr/ctrl modifier) → character
-`tools/include/linux/input.h` — Linux keycode definitions
**What NOT to do:** Do NOT try to support all 500+ Linux keymaps. Start with the 4 most common layouts and add more as needed. Do NOT invent a new keymap format — use TOML with Linux keycode names where possible.
**Goal:** All local forks synchronized with upstream Redox's latest stable commits.
Red Bear custom drivers (redbear-acmd, redbear-ecmd, redbear-ftdi, redbear-usbaudiod)
updated to current redox-scheme API. Netstack and USB improvements integrated.
**Dependencies:** Phase 2 (stable console, working login).
### 3.1 Execute Full Upstream Sync for All 9 Local Forks
**Context:** All local forks have accumulated drift from upstream Redox. The `UPSTREAM-SYNC-PROCEDURE.md` defines the procedure. This is the systematic execution.
**Procedure (per fork):**
> ⚠️ **GROSS WARNING — DO NOT run `repo cook`, `repo fetch`, or `make live` directly.**
> These bypass the canonical build pipeline (`apply-patches.sh` patch-linking + staleness handling + correct dependency ordering), which causes broken/missing patches and wasted rebuild time. **ALWAYS build via `./local/scripts/build-redbear.sh [--upstream] <config>`** (or the documented `make` targets it drives). If you think you need a single-recipe cook, run the canonical wrapper — it does the right thing and is faster in the end.
**For `base` specifically:** The upstream Redox base repo has ~54 non-USB commits plus USB stack commits. Red Bear has local USB quirks and netstack changes. The merge must:
1. Apply upstream's 54 non-USB commits first
2. Then reapply Red Bear's USB changes on top
3. Carefully review for conflicts in `drivers/usb/xhcid/`, `netstack/`, and `drivers/graphics/fbcond/`
**Linux reference for merge strategy:**
-`scripts/merge_config.sh` — Linux kernel uses a structured merge tool for Kconfig conflicts. The same principle applies: when upstream and local both modify the same file, the merge must respect the intent of both sides, not blindly pick one.
-`Documentation/process/submitting-patches.rst:section "The canonical patch format"` — Linux's patch ordering rule: "logically separate changes → separate patches". Apply this: upstream changes first as a single logical unit, Red Bear changes second.
**Verification steps after each fork sync:**
1.`cargo check` in the fork's working tree — 0 errors
2.`repo cook <component>` from the RedBear-OS root — builds successfully
3.`make prefix` (for relibc, kernel) — prefix rebuilt with new libc.a
4. Full image build: `./local/scripts/build-redbear.sh redbear-mini` — boots
**Estimated time:** 16–32 hours (2–4 days per full-time contributor)
### 3.2 Update redbear-* Scheme Drivers to New redox-scheme API
**Context:** The `redox-scheme` crate has been updated (likely to 0.11.x or newer). Red Bear's custom scheme-based daemons need their API calls updated.
**Files involved:**
-`local/recipes/core/redbear-acmd/source/` — Admin command service
-`local/recipes/core/redbear-ecmd/source/` — Embedded controller service
**Linux reference:** `include/linux/usb/audio.h` — Linux's USB audio class driver interface. The principle is identical: when the kernel internal API changes, all class drivers must adapt. Redox's `redox-scheme` is analogous to Linux's `struct usb_driver`.
**Estimated time:** 4–8 hours
**Dependencies:** Phase 3.1 (scheme crate must be synced first).
### 3.3 Integrate Stable Netstack WIP Changes
**Context:** The base fork has ~20 recent netstack commits (IPv6, filter/conntrack, NAT, stats) visible in the git log. After Phase 1.5 stabilization, integrate the stable ones.
**Context:** The existing `archived/IMPROVEMENT-PLAN.md` Section 3.3 identifies 49/50 xHCI quirks declared but not enforced at runtime. This is a critical gap for supporting real hardware.
**Context:** After Phase 3.1 syncs all forks to upstream HEAD, this phase focuses on closing the remaining Red Bear-specific gaps — the POSIX functions, syscalls, and capabilities that upstream Redox still doesn't have but Red Bear needs for desktop software compatibility.
**relibc POSIX gaps to close:**
| Function | Status | Linux reference | Priority |
6. Test: write a small C program that calls the function
**"Do not reinvent" rule:** Linux 7.1's implementations are battle-tested. For each function, read the Linux source in `local/reference/linux-7.1/`, understand the algorithm, port the logic into Rust for relibc. Do NOT invent novel implementations.
**Estimated time:** 24–40 hours (3–5 functions per week)
**Dependencies:** Phase 3.1 (synced relibc and kernel forks).
### 4.2 Comprehensive Input Device Handling
**Context:** The current input subsystem handles basic keyboard and mouse via PS/2 and USB HID. Desktop software expects evdev-compatible input with full keycode→keysym translation, touchpad gesture support, and multi-touch.
**What NOT to do:** Do NOT implement support for exotic input devices (gamepads, joysticks, drawing tablets, touchscreens) in this phase. Keyboard + mouse + basic touchpad is sufficient for desktop. Add more later.
### 4.3 Stub Replacement: Identify and Replace Remaining Stubs
**Context:** The project has a zero-tolerance stub policy (`local/AGENTS.md` § STUB AND WORKAROUND POLICY). The `archived/STUBS-FIX-PROGRESS.md` tracks the stub→real-code rewrite campaign. Audit the remaining stubs and prioritize fixes.
**Estimated time:** 16–32 hours (ongoing across Phase 4)
**Dependencies:** Phase 3.1 (synced forks provide the correct APIs to implement against).
---
## Phase 5: Bare Metal Validation (1–2 Weeks)
**Goal:** Red Bear OS boots on real AMD Ryzen hardware. ACPI power management works.
USB storage enumerates. Wi-Fi driver loads (if hardware present). Production readiness
baseline established.
**Dependencies:** Phase 4 (complete POSIX and input support).
### 5.1 AMD Ryzen Bare Metal Boot Validation
**Context:** Red Bear OS was previously verified on Ryzen Threadripper (128-thread). This validation updates to the current 0.3.1 state and tests all subsystems.
**Context:** The `ACPI-IMPROVEMENT-PLAN.md` documents the current ACPI state: RSDP/SDT checksum verified, MADT types parsed, FADT shutdown/reboot via `\_S5`, but robustness gaps remain.
**What to skip initially:** S4 (hibernate-to-disk) — requires full swap support. S3 (suspend-to-RAM) is the priority.
**Estimated time:** 4–8 hours
**Dependencies:** Phase 5.1 (bare metal access).
### 5.3 USB Storage and HID Validation
**Context:** USB storage (usbscsid) and HID (usbhidd) drivers need real hardware testing. QEMU testing covers the happy path; real hardware covers edge cases.
**Test plan:**
1. USB mass storage (flash drive):
- Insert USB flash drive
- Verify `usbscsid` auto-spawns
- Verify device appears as `/scheme/usbscsid/<n>`
- Mount (if filesystem support is ready)
- Read/write test
- Hot-unplug while idle (should log, not panic)
2. USB keyboard:
- Boot with USB keyboard attached (no PS/2 keyboard)
- Verify `usbhidd` detects keyboard
- Verify typing works at login prompt
- Verify modifier keys (Shift, Ctrl, Alt)
3. USB mouse:
- Attach USB mouse
- Verify `usbhidd` detects mouse
- Verify cursor movement (if graphical session is running)
**Linux reference:** `drivers/usb/storage/usb.c:1050-1100` — `usb_stor_control_thread()` with proper error recovery on device disconnect. Red Bear's usbscsid must handle the same scenario: device removed mid-transfer → error, not panic.
**See also:** `archived/IMPROVEMENT-PLAN.md` § 2.1 (usbscsid `.unwrap()` removal) — this must be done before hardware testing.
**Context:** Intel iwlwifi has expanded PCI ID table (37 devices, was 7), mini-MVM layer, and firmware TLV parser. Assess readiness for first hardware test.
**Test plan:**
1. Verify iwlwifi driver builds and is in the ISO: `grep iwlwifi build/x86_64/redbear-full.iso.manifest`
2. Boot on hardware with Intel Wi-Fi (AC 7260, 8260, 9260, AX200, AX210)
3. Check `pcid:` log for the Wi-Fi device — it should be enumerated
4. Check `iwlwifi:` log for firmware load status
5. If firmware loads: attempt scan (`redbear-wifictl scan` or equivalent)
6. If scan succeeds: attempt connection to an open network
7. File bugs for any failure with PCI vendor/device ID, firmware version, and log excerpt
**Linux reference:**
- `drivers/net/wireless/intel/iwlwifi/pcie/drv.c:785-830` — Linux's complete PCI ID table. Cross-reference Red Bear's table against this.
- `drivers/net/wireless/intel/iwlwifi/fw/file.h` — firmware TLV structure (same as Red Bear's `linux_mvm.c`)
| `sem_open` | `ipc/sem.c:400-550` | Named semaphore, `/dev/shm` backing |
| `posix_spawn` | `kernel/fork.c:2900-2950` | Spawn without fork+exec |
### General Advice
1. **Before writing any new algorithm**, check if Linux has an equivalent. If yes, port the algorithm structure (not the code — we're Rust, Linux is C).
2. **For data structures**, prefer Linux's patterns: Red-black trees (`rbtree`), radix trees, linked lists (`list_head`), hash tables. Red Bear should use Rust equivalents (`BTreeMap`, `HashMap`, `VecDeque`).
3. **For quirk tables**, ALWAYS cross-reference Linux's `pci_ids.h`, `xhci-pci.c`, `usb_quirks.h`. Linux has already identified every quirky device. Port the table, do not rediscover bugs.
4. **For error recovery**, Linux's pattern is: log the error, return -EIO/-EINVAL/-ENOMEM, do NOT panic. Apply this universally.
5. **For timing/delays**, Linux uses `msleep()`, `usleep_range()`, `udelay()`. Red Bear should use equivalent primitives from `libredox` or `std::thread::sleep`. Never use busy-wait loops without bounded timeouts.
---
## Summary: Execution Order and Milestones
| Phase | Weeks | Key Deliverable | Blocks |
|-------|-------|-----------------|--------|
| **Phase 1** | Week 1 | All build blockers resolved. Clean base fork. Synced versions. | Nothing |
| **Phase 2** | Weeks 1–2 | Login-prompt works. Enter key, no text corruption, working PTY. | Phase 1 |
| **Phase 3** | Weeks 2–4 | All 9 forks synced to upstream. Netstack improved. USB quirks enforced. | Phase 2 |
// phys 0 selects the in-memory heap framebuffer fallback, so the test does
// not depend on mmap("/dev/mem") (unavailable in CI/sandboxes without
// CAP_SYS_RAWIO) and the compositor can bind its Wayland socket anywhere.
.env("FRAMEBUFFER_ADDR","0");
cmd.spawn().expect("failed to start compositor")
}
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.