Files
vasilito aa9d14a90e docs: update AGENTS.md and PATCH-GOVERNANCE.md
AGENTS.md: updated session progress, coretempd/login fix notes, Intel plan references. PATCH-GOVERNANCE.md: added mega-patch discipline section and P-patch workflow documentation.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-29 21:50:28 +03:00

1158 lines
59 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# RED BEAR OS BUILD SYSTEM — PROJECT KNOWLEDGE BASE
**Generated:** 2026-04-12 (P1/P2 complete) · Updated: 2026-05-29 (mega-patch discipline)
**Toolchain:** Rust nightly-2025-10-03 (edition 2024)
**Architecture:** Microkernel OS in Rust, ~38k files, ~294k LoC Rust
**Target Hardware**: AMD64 bare metal, with AMD and Intel machines treated as equal-priority Red Bear OS targets
## OVERVIEW
Red Bear OS build system orchestrator — fetches, builds, and packages ~100+ Git repositories
into a bootable Redox image. Uses a Makefile + Rust "cookbook" tool + TOML configs.
Languages: Rust (core), C (ported packages), TOML (config), Make (build orchestration).
RedBearOS is a **full fork** of Redox OS — based on frozen, archived source snapshots.
Sources are immutable and never auto-immutable archived from upstream. All changes are explicit,
human-initiated operations. Durable Red Bear state belongs in `local/patches/`,
`local/recipes/`, `local/docs/`, and tracked Red Bear configs.
The current baseline is **Red Bear OS 0.1.0** (Redox snapshot at build-system commit `f55acba68`).
All recipe sources are pinned and archived in `sources/redbear-0.1.0/`.
## BUILD SYSTEM DURABILITY — THE CARDINAL RULE
**THE `recipes/*/source/` DIRECTORY WILL ALWAYS BE REWRITTEN. DO NOT EVER USE IT FOR ANY
WORK THAT YOU INTEND TO KEEP. THOSE TREES ARE EPHEMERAL — THEY ARE DESTROYED AND REGENERATED
ON EVERY `repo fetch`, `repo cook`, `make clean`, AND `make distclean`. ANY EDIT MADE THERE
WILL BE SILENTLY LOST ON THE NEXT BUILD. COMMITTING TO A SUBMODULE INSIDE `source/` DOES NOT
PROTECT YOUR WORK — THE ENTIRE DIRECTORY IS DELETED AND RE-CLONED/RE-EXTRACTED FROM SCRATCH.**
This is the #1 mistake AI agents and new contributors make. It has caused repeated work loss
in this project. The rule is:
| What you want to do | Where to do it |
|---|---|
| Change a kernel source file | Create or update a patch in `local/patches/kernel/` |
| Change an init or daemon source file | Create or update a patch in `local/patches/base/` |
| Change relibc | Create or update a patch in `local/patches/relibc/` |
| Change a driver | Create or update a patch in `local/patches/base/` or `local/patches/<driver>/` |
| Add a new package | Create a recipe in `local/recipes/<category>/<name>/` |
| Change build config | Edit `config/redbear-*.toml` |
| Add documentation | Write to `local/docs/` |
### How the build system works
```
repo cook <package>
├── repo fetch <package>
│ ├── Clone/fetch upstream source → recipes/<pkg>/source/
│ ├── Apply patches from recipe.toml → patches are read from local/patches/<pkg>/
│ └── Source tree is now fully patched and ready for build
├── Cargo/cmake/configure build
└── Stage artifacts into sysroot
```
The `source/` directory is a disposable working copy. It is produced at the start of every
build by cloning the upstream source + applying patches sequentially. The recipe's
`patches = [...]` list in `recipe.toml` controls which patches are applied.
### Two-layer architecture
```
Layer 1: Ephemeral (destroyed on clean/fetch/rebuild)
recipes/<pkg>/source/ ← working tree, cloned + patched
build/ ← build outputs
target/ ← cargo target dir
Layer 2: Durable (survives clean/fetch/rebuild/release provisioning)
local/patches/<pkg>/ ← .patch files — the actual source code changes
local/recipes/<pkg>/ ← custom recipe directories
config/redbear-*.toml ← Red Bear OS build configs
local/docs/ ← planning and integration docs
recipes/<pkg>/recipe.toml ← the patches list (git-tracked)
```
### The correct workflow for any source change
1. **Make the change** in `recipes/<pkg>/source/` to validate it compiles
2. **Generate a patch**: `cd recipes/<pkg>/source && git diff > ../../../local/patches/<pkg>/my-fix.patch`
3. **Wire the patch**: add `"my-fix.patch"` to the recipe's `recipe.toml` `patches = [...]` list
4. **Validate**: `./target/release/repo validate-patches <pkg>`
5. **Rebuild**: `./target/release/repo cook <pkg>`
6. **Commit**: `git add local/patches/ recipes/<pkg>/recipe.toml && git commit`
### Common anti-patterns
| Anti-pattern | Why it fails |
|---|---|
| Editing `source/` files then running `make all` | `make all` calls `repo fetch` which regenerates `source/` — edits are lost |
| Creating a patch but not wiring it into `recipe.toml` | Patch file exists but is never applied — build uses unpatched source |
| **Hand-writing patches manually** | **FORBIDDEN. Unified diffs hand-written by humans routinely have incorrect line counts, wrong context, malformed hunks, or timestamp headers — all of which cause `patch(1)` to reject them. The ONLY acceptable way to generate patches is `git diff -U0 -w` from a committed source tree baseline.** |
| Editing `recipe.toml` patches list without creating the actual `.patch` file | Build fails with "missing patch" error |
| Editing `recipe.toml` patches list without creating the actual `.patch` file | Build fails with "missing patch" error |
| Expecting `source/` changes to survive `make clean` | `make clean` deletes `source/` directories |
| Running `repo cook` without `--allow-protected` for core packages | Protected recipes (kernel, relibc, base) are offline-only by default |
### Patch file location convention
- `local/patches/base/` — for the `base` package (init, daemon, all drivers)
- `local/patches/kernel/` — for the kernel
- `local/patches/relibc/` — for relibc
- `local/patches/installer/` — for the installer
- `local/patches/bootloader/` — for the bootloader
- `local/patches/<package>/` — for any other patched package
### Recipe patch wiring
Each recipe's `recipe.toml` lists patches relative to `local/patches/<pkg>/`:
```toml
[source]
git = "https://gitlab.redox-os.org/redox-os/base.git"
rev = "463f76b96..."
patches = [
"P0-daemon-fix-init-notify-unwrap.patch", # applied first
"P9-init-scheduler-completed.patch", # applied second
# ... more patches
]
```
Patches are applied in listed order. Dependencies between patches must be respected (a patch
that defines a type must come before a patch that uses it).
### Kernel-specific notes
The kernel source at `recipes/core/kernel/source/` is a separate git worktree (rev `866dfad`).
The kernel recipe is at `recipes/core/kernel/recipe.toml` and patches are at
`local/patches/kernel/`. The same durability rules apply — all kernel changes must be
in `local/patches/kernel/*.patch`, never in the `source/` tree directly.
**Red Bear OS is offline-first by default. No script, build target, or tool may silently pull
from any upstream repository without explicit user instruction.**
This policy exists because silent upstream pulls are the root cause of stale and orphaned patches.
When sources change underneath wired patches, those patches break. The only safe workflow is:
frozen sources → patches applied atomically → build.
### Rules
1. **`REPO_OFFLINE` defaults to `1`** (offline). Set `REPO_OFFLINE=0` to explicitly allow online
fetching for non-protected development recipes only.
2. **`REDBEAR_RELEASE`** unconditionally forces offline mode — no network access during release
builds, even with `REPO_OFFLINE=0`.
3. **Protected recipes** (kernel, relibc, base, bootloader, all Red Bear custom recipes) are
**always offline** — they use archived sources from `sources/redbear-<release>/`.
4. **`GNU_CONFIG_GET`** (wget for `config.sub`) is gated by `COOKBOOK_OFFLINE` — no download
when offline.
5. **Manual scripts** (`fetch-firmware.sh`, `fetch-all-sources.sh`, `provision-release.sh`)
may pull from upstream but MUST be explicitly invoked by the user. They are never called by
`make all` or `make live`.
6. **Toolchain downloads** (`mk/prefix.mk`) are the only ungated network access — they download
the cross-compiler toolchain from `static.redox-os.org`. These are one-time prerequisites,
not per-recipe source fetches.
### What Counts as a Silent Upstream Pull
Any of the following that runs without the user explicitly requesting it:
- `git clone`, `git fetch`, `git pull` against any remote
- `wget` or `curl` downloading source code or build artifacts
- Any HTTP request to `gitlab.redox-os.org`, `github.com`, `static.redox-os.org`, or any other
upstream hosting service (note: Red Bear OS does not use GitHub — see Repository Hosting below)
### What Does NOT Count
- Toolchain setup (`make prefix`) — one-time cross-compiler download
- QEMU firmware for non-x86 targets (`mk/qemu.mk` ARM/Raspberry Pi U-Boot) — not used in
standard x86_64 builds
- `make fetch` — explicit user action, gated by `REDBEAR_RELEASE`
### Enforcement
- Violations are bugs. If you find a script or build target that silently pulls from upstream,
fix it immediately: add an offline gate, or move the fetch to a manual-only script.
- The cookbook tool (`src/cook/fetch.rs`) enforces offline mode for protected recipes regardless
of `COOKBOOK_OFFLINE`.
- `COOKBOOK_OFFLINE=true` is the default in the Rust cookbook config parser when the environment
variable is not set.
## STRUCTURE
```
redox-master/
├── config/ # Build configs (TOML): tracked redbear-* targets plus mainline references
├── mk/ # Makefile fragments: config.mk, repo.mk, prefix.mk, disk.mk, qemu.mk
├── recipes/ # Package recipes (TOML + source). 26 categories. See recipes/AGENTS.md
│ ├── core/ # kernel, bootloader, relibc, base drivers — See recipes/core/AGENTS.md
│ ├── wip/ # Wayland, KDE, driver WIP ports — See recipes/wip/AGENTS.md
│ ├── libs/ # Libraries: mesa, cairo, SDL, zlib, openssl, etc.
│ ├── gui/ # Legacy GUI stack packages
│ └── ... # 21 other categories (net, dev, games, shells, etc.)
├── src/ # Cookbook Rust tooling (repo binary, cook logic)
├── docs/ # Architecture docs (6 detailed integration guides) — See docs/AGENTS.md
├── local/ # OUR CUSTOM WORK — survives mainline updates — See local/AGENTS.md
│ ├── config/ # Custom configs (my-amd-desktop.toml)
│ ├── recipes/ # Custom recipes (AMD drivers, GPU stack, Wayland)
│ ├── patches/ # Patches against mainline sources (kernel, relibc, base)
│ ├── Assets/ # Branding assets (icon, loading background)
│ ├── firmware/ # AMD GPU firmware blobs (fetched, not committed)
│ ├── scripts/ # Build/deploy scripts (fetch-firmware.sh, build-redbear.sh)
│ ├── docs/ # Red Bear integration docs (AMD roadmap, Wi-Fi/Bluetooth plans, status notes)
│ └── reference/ # External reference sources (gitignored, never deleted, always kept)
├── prefix/ # Cross-compiler toolchain (Clang/LLVM for x86_64-unknown-redox)
├── build/ # Build outputs, logs, fstools, per-arch directories
├── repo/ # Package manifests and PKGAR artifacts per architecture
├── bin/ # Cross-tool wrappers (pkg-config, llvm-config per target)
├── scripts/ # Helper scripts (backtrace, category, changelog, etc.)
├── podman/ # Podman container build support
├── .cargo/ # Cargo config: linker per target (aarch64, x86_64, i586, i686, riscv64gc)
├── Makefile # Root orchestrator (all, live, image, rebuild, clean, qemu, gdb)
├── Cargo.toml # Cookbook crate: binaries (repo, repo_builder), lib (cookbook)
├── rust-toolchain.toml # nightly-2025-10-03 + rust-src + rustfmt + clippy
└── .config # PODMAN_BUILD=0 (set to 1 for container builds)
```
## WHERE TO LOOK
| Task | Location | Notes |
|------|----------|-------|
| Add a package | `recipes/<category>/<name>/recipe.toml` | Use `template = "cargo\|cmake\|meson\|custom"` |
| Change build config | `config/<name>.toml` | Include chain: wayland→desktop→desktop-minimal→minimal→base |
| Fix kernel | `recipes/core/kernel/source/` | Kernel is a recipe, not top-level |
| Fix a driver | `recipes/core/base/source/drivers/` | All drivers are userspace daemons |
| Fix relibc (POSIX) | `recipes/core/relibc/source/` | C library written in Rust |
| Wayland integration | `recipes/wip/wayland/` + `local/docs/WAYLAND-IMPLEMENTATION-PLAN.md` | 21 WIP recipes + local validation/ownership plan |
| KDE Plasma path | `recipes/wip/kde/` + `docs/05-KDE-PLASMA-ON-REDOX.md` | 9 WIP KDE app recipes |
| **Desktop path plan** | `local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md` | **Canonical plan: console → HW-accelerated KDE** |
| Linux driver compat | `docs/04-LINUX-DRIVER-COMPAT.md` | linux-kpi + redox-driver-sys architecture (**GPU and Wi-Fi only — not USB**) |
| Build system internals | `src/bin/repo.rs`, `src/lib.rs`, `mk/repo.mk` | Cookbook tool in Rust |
| Cross-toolchain setup | `mk/prefix.mk`, `prefix/x86_64-unknown-redox/` | Downloads Clang/LLVM toolchain |
| Display/session surface | `config/redbear-full.toml` | Active desktop/graphics compile surface |
| GPU/graphics stack | `recipes/libs/mesa/` | OSMesa + LLVMpipe (software only) |
| GPU hardware drivers | `local/recipes/gpu/redox-drm/source/` | AMD + Intel DRM/KMS via redox-driver-sys |
| D-Bus integration | `local/docs/DBUS-INTEGRATION-PLAN.md` | Architecture, gap analysis, phased implementation for KDE Plasma D-Bus |
| Boot config | `config/*.toml` | TOML hierarchy, include-based |
| **Hardware quirks** | `local/recipes/drivers/redox-driver-sys/source/src/quirks/` | Data-driven quirk tables: compiled-in + TOML + DMI; see `local/docs/QUIRKS-SYSTEM.md` |
## BUILD COMMANDS
```bash
# Prerequisites (Linux x86_64 host)
# rustup + nightly-2025-10-03, cargo install just cbedgen, nasm, qemu-system-x86
# See docs/06-BUILD-SYSTEM-SETUP.md for distro-specific packages
# Configuration
echo 'PODMAN_BUILD?=0' > .config # Native build (no container)
echo 'PODMAN_BUILD?=1' > .config # Podman container build
# Build Red Bear OS
# Supported compile targets:
# redbear-full desktop/graphics target (harddrive.img or live ISO)
# redbear-mini text-only console/recovery target (harddrive.img or live ISO)
# redbear-grub text-only with GRUB boot manager (live ISO)
# Desktop/graphics target: redbear-full
# Text-only targets: redbear-mini, redbear-grub
make all CONFIG_NAME=redbear-full # Desktop/graphics target → harddrive.img
make all CONFIG_NAME=redbear-mini # Text-only target → harddrive.img
make live CONFIG_NAME=redbear-full # Full desktop live ISO
make live CONFIG_NAME=redbear-mini # Text-only mini live ISO
make live CONFIG_NAME=redbear-grub # Text-only mini live ISO with GRUB
CI=1 make all CONFIG_NAME=redbear-mini # CI mode (disables TUI, for non-interactive)
# Run
make qemu # Boot in QEMU
make qemu QEMUFLAGS="-m 4G" # With more RAM
make live # Build live ISO for real bare metal
# Single recipe
./target/release/repo cook recipes/libs/mesa # Build one recipe
./target/release/repo fetch recipes/core/kernel # Fetch source only
make r.mesa # Make shorthand for cook
make cr.mesa # Clean + rebuild
# Clean
make clean # Remove build artifacts
make distclean # Remove sources + artifacts
```
## BUILD FLOW
```
make all
→ mk/config.mk (ARCH, CONFIG_NAME, FILESYSTEM_CONFIG)
→ mk/depends.mk (check host tools: rustup, cbedgen, nasm, just)
→ mk/prefix.mk (download/setup cross-toolchain if needed)
→ mk/fstools.mk (build cookbook repo binary + fstools)
→ mk/repo.mk (repo cook --filesystem=config/*.toml)
→ For each recipe: fetch source → apply patches → build → stage into sysroot
→ Each successful build produces repo/<arch>/<name>.pkgar + <name>.toml
→ mk/disk.mk (create filesystem.img, harddrive.img, redbear-live.iso or harddrive.img)
→ redoxfs-mkfs → redox_installer → bootloader embedding
```
### Build Outputs
Every successful `repo cook <package>` produces:
| Artifact | Location | Purpose |
|----------|----------|---------|
| Package archive | `repo/x86_64-unknown-redox/<name>.pkgar` | Binary package for image assembly |
| Package manifest | `repo/x86_64-unknown-redox/<name>.toml` | Metadata, version, deps, hashes |
| Staged sysroot | `recipes/*/<name>/target/.../stage/` | Files for `repo push` |
| Source tree | `recipes/*/<name>/source/` | Fetched + patched source (disposable) |
**A build is not complete until the .pkgar and .toml exist in `repo/`.**
## CONVENTIONS
- **Rust edition 2024**, nightly channel
- **rustfmt.toml**: max_width=100, brace_style=SameLineWhere
- **clippy.toml**: cognitive-complexity-threshold=100, type-complexity-threshold=1000
- **Recipe format**: TOML with `[source]` + `[build]` + optional `[package]`
- **Build templates**: `cargo`, `meson`, `cmake`, `make`, `configure`, `custom`
- **WIP recipes**: Must start with `#TODO` comment explaining what's missing
- **Custom configs**: Name with `my-` prefix (git-ignored by convention)
- **CI**: GitLab CI (`.gitlab-ci.yml`) at root + per-recipe
- **Repository Hosting**: Gitea at `gitea.redbearos.org` — the ONLY git server. No GitHub.
- **Syscall ABI**: Unstable intentionally. Stability via `libredox` and `relibc`
- **Drivers**: ALL userspace daemons via scheme system. No kernel-space drivers (except serio)
## SYSTEM-CRITICAL INFRASTRUCTURE MUST BE RUST
All Red Bear OS system-critical infrastructure **must** be written in Rust. C and C++ are
acceptable only for ported upstream applications (KDE Plasma, Qt, games, third-party tools)
where the original source is not Rust.
### What counts as system-critical
| Layer | Component | Language | Status |
|-------|-----------|----------|--------|
| Kernel | microkernel | Rust | ✅ |
| C library | relibc | Rust | ✅ |
| Init | service manager | Rust | ✅ |
| Filesystems | redoxfs, ext4d, fatd | Rust | ✅ |
| Driver infrastructure | redox-driver-sys, linux-kpi headers | Rust + C headers | ✅ |
| Display/compositor | Wayland compositor | Rust | required |
| Session/auth | redbear-sessiond, redbear-authd | Rust | ✅ |
| D-Bus broker | session/system bus | Rust | ✅ |
| Network stack | TCP/IP, Wi-Fi control plane | Rust | required |
| Bluetooth stack | host/controller path | Rust | required |
| USB stack | controller drivers, hub driver | Rust | required |
| Input stack | evdev, libinput adapter | Rust | required |
| Firmware loading | scheme:firmware daemon | Rust | ✅ |
| Core utilities | shell, fileutils, process tools | Rust | required |
| Bootloader | UEFI bootloader | Rust | ✅ |
| Installer | redox_installer | Rust | ✅ |
| Build tooling | cookbook, repo binary | Rust | ✅ |
### What does NOT need to be Rust
- **Ported desktop applications**: KDE Plasma, Qt apps, KDE Frameworks — these are upstream
C++ codebases and remain C++. The boundary is at the platform adapter layer: anything Red Bear
writes to integrate them ( Wayland protocol bridges, D-Bus service implementations, platform
plugins) must be Rust even if the upstream consumer is C++.
- **Ported libraries**: mesa, wayland, libxkbcommon, libinput, fontconfig, etc. — upstream C.
- **Games and end-user applications**: upstream code in any language.
### Decision rule
When writing new code for Red Bear OS, or when choosing between writing new code vs porting
existing code, the rule is:
> If the component runs below the application layer — kernel, libc, drivers, filesystems,
> compositor, session management, networking, input, USB, Bluetooth, core utilities —
> it must be written in Rust.
>
> If the component is an application or library that users would recognize as a separate
> upstream project (KDE, Qt, Firefox, etc.), it may remain in its upstream language.
>
> The integration layer between Rust infrastructure and upstream C/C++ code must be Rust.
> Platform adapters, D-Bus service implementations, Wayland protocol bridges, and plugin
> shims are infrastructure, not applications.
### Enforcement
- New recipes under `local/recipes/` for system-critical components must use `template = "cargo"`.
- C/C++ build templates (`cmake`, `meson`, `make`, `configure`) are only for ported upstream
packages and their direct dependencies.
- If a ported C/C++ package needs a companion daemon, helper, or bridge, that companion must
be a separate Rust recipe — not embedded C in the ported package.
### Conflicting implementations: always prefer Rust
When both a Rust implementation and a C/C++ implementation exist for the same functionality,
Red Bear OS **always** prefers the Rust implementation. This applies even when the C version is
from upstream Redox or appears more complete.
The rationale: Rust provides memory safety, type safety, and panic-based error recovery at the
language level. For an OS with no ASLR, no stack canaries, and a minimal kernel, the language
itself is the primary defense boundary. A C implementation of equivalent functionality is always
a strictly weaker choice.
Examples:
| Situation | Correct choice |
|-----------|---------------|
| relibc (Rust) vs newlib/glibc (C) | relibc — always |
| redoxfs (Rust) vs an imported C filesystem driver | redoxfs — always |
| redbear-sessiond (Rust) vs dbus-daemon (C) | redbear-sessiond — always |
| A Rust crate for a protocol vs the reference C library | Rust crate — always |
| Upstream Redox provides a Rust driver; we also have a C port | Rust driver — always |
If a Rust implementation is less feature-complete than the C alternative, the correct response
is to improve the Rust implementation — not to fall back to C.
## INSTALLER FILE LAYERING
The installer creates filesystem images in four layers. Understanding this ordering is critical
to avoid silent file overwrites.
### Layer Ordering During `install_dir()`
```
Layer 1: Config pre-install [[files]] (postinstall = false)
Layer 2: Package staging (install_packages())
Layer 3: Config post-install [[files]] (postinstall = true)
Layer 4: User/group creation (passwd, shadow, group)
```
### Collision Implications
- **Layer 2 overwrites Layer 1** silently (same path → last writer wins). This is the bug class
that caused the D-Bus regression: config overrides at `/usr/lib/init.d/` were overwritten by
the `base` package staging the same paths.
- **Layer 3 overwrites Layer 2** (intentional — postinstall overrides).
- For init services, config overrides **MUST** use `/etc/init.d/` so they survive Layer 2.
### Init Service File Ownership
- **Packages own `/usr/lib/init.d/`** — default service files installed by recipe staging
- **Config overrides own `/etc/init.d/`** — override files created by `[[files]]` entries
- The init system's `config_for_dirs()` gives `/etc/init.d/` priority via BTreeMap dedup
- **Config `[[files]]` entries MUST NOT use `/usr/lib/init.d/` paths for init services**
- Run `make lint-config` to detect violations
### Collision Detection
The installer now includes a `CollisionTracker` (in `collision.rs`) that detects when package
staging overwrites config pre-install files. Init service collisions always error. Other
collisions warn by default, error in strict mode (`REDBEAR_STRICT_COLLISION=1`).
### Validation Gates
After building an image, run `make validate` to verify:
- Init service path violations (via `lint-config`)
- Override effectiveness and scheme binary existence (via `validate-init-services.sh`)
- File ownership conflicts (via `validate-file-ownership.sh`)
See `local/docs/BUILD-SYSTEM-HARDENING-PLAN.md` for the full plan.
## ANTI-PATTERNS (THIS PROJECT)
- **DO NOT** suppress errors with `as any` / `@ts-ignore` — use proper `Result` handling
- **DO NOT** use `unwrap()` / `expect()` in library/driver code — pervasive anti-pattern (~14k instances)
- **DO NOT** modify kernel syscall ABI directly — use `libredox` or `relibc`
- **DO NOT** put drivers in kernel space — all drivers are userspace daemons
- **DO NOT** hardcode `/dev/` paths — use scheme paths (`/scheme/drm/card0`)
- **DO NOT** skip patches in WIP recipes — document what's missing with `#TODO`
- **DO NOT** skip warnings — investigate, diagnose, and fix the root cause; suppressing or ignoring warnings is not acceptable when a fix is feasible
- **DO NOT** remove patches from `recipe.toml` to fix build failures — rebase the patch instead (see `local/docs/PATCH-GOVERNANCE.md`)
- **DO NOT** remove BINS entries to fix build failures — fix the source or use EXISTING_BINS filtering
- **DO NOT** use the VESA display driver (`vesad`) as the primary display surface after GPU detection. vesad is only for early-boot framebuffer handoff — after redox-drm loads, the display path is `/scheme/drm/card0`. See **NO VESA POLICY** below.
## NO VESA POLICY
Red Bear OS does not use the VESA display driver as the primary display surface. All display
output goes through the DRM/KMS path via real GPU drivers:
| Environment | GPU Driver | 3D Support |
|---|---|---|
| QEMU | virtio-gpu (via redox-drm) | ✅ virgl |
| Intel hardware | Intel i915-like (via redox-drm) | ✅ Mesa i965/iris |
| AMD hardware | amdgpu (via redox-drm + linux-kpi) | ✅ Mesa radeonsi |
| Future | nouveau reimplementation (Rust, via redox-drm) | ✅ Mesa nouveau |
**vesad is allowed ONLY as an early-boot framebuffer handoff.** The bootloader sets up a linear
framebuffer before the kernel starts. vesad takes over this framebuffer so the initfs has console
output (fbcond, fbbootlogd) before real GPU drivers are available. Once redox-drm initializes and
registers `scheme:drm/card0`, vesad must hand off and NOT register `scheme:display.vesa` as the
primary display surface.
The display path for redbear-full:
```
Bootloader linear framebuffer
→ vesad (initfs, service 20): temporary FB handoff for text console
→ redox-drm (initfs, service 30): detects GPU hardware, takes over via DRM/KMS
→ redox-drm (rootfs, service 14): full DRM driver with 3D (Mesa)
→ KWin compositor: DRM/KMS master, composites desktop via /scheme/drm/card0
```
For redbear-mini: vesad handles the bootloader framebuffer for the text-only console. No GPU
driver loads — mini is text-only by design.
**After GPU detection, any code that opens `/scheme/display.vesa/` is incorrect.** The correct
display path is `/scheme/drm/card0` via the DRM scheme.
Rationale: VESA is a legacy BIOS-era standard with no hardware acceleration, no mode setting
beyond what the bootloader provides, no 3D, and no future. Red Bear OS targets real GPU
hardware with full DRM/KMS and Mesa support. vesad serves only as a bridge between bootloader
FB and the real GPU driver — it is never the final display path.
This policy also covers future GPU driver work: any new GPU support (nouveau Rust reimplementation,
ARM Mali, etc.) must go through the redox-drm + DRM/KMS path, never through VESA fallback.
## ZERO TOLERANCE FOR STUBS
**Red Bear OS has zero tolerance for stubs, placeholders, fake implementations, skeleton code,
unimplemented functions, or any other "make it compile" shortcut.**
### What counts as a stub
Any of the following:
- A function or method that returns a hardcoded value instead of computing the real result
- A trait implementation where methods log "not implemented" or return empty/default values
- A struct that stores fields but never uses them for real work
- A file that exists to satisfy an import but contains no real logic
- A `// TODO: implement` comment followed by a dummy return
- A driver that creates synthetic data (fake EDID, hardcoded modes) instead of querying the hardware
- A `todo!()` or `unimplemented!()` macro anywhere in non-test code
### The rule
> **As soon as a stub is detected, it must be replaced with real, sophisticated, comprehensive code
> in the same work session.** No exceptions. No "I'll come back to it." No "this is good enough for now."
A stub found in the tree is a **bug** — not a precedent to follow, not a placeholder to defer,
not an acceptable intermediate state. Every stub is technical debt that compounds daily.
### Required response to a stub
When you encounter a stub:
1. **Stop what you are doing.** The stub takes priority.
2. **Understand the interface.** Read the trait, API contract, or specification the stub is supposed to implement.
3. **Implement it comprehensively.** Real logic, real hardware communication, real error handling, real edge cases.
4. **Verify it works.** Run `cargo check`, tests, or build verification.
| Stub pattern | Required fix |
|---|---|
| `fn detect_connectors() -> Vec<ConnectorInfo> { vec![] }` | Implement real hardware enumeration with proper protocol |
| `fn handle_irq() -> Ok(None)` | Implement real interrupt handling with event dispatch |
| `synthetic_edid()` when hardware can provide real EDID | Query the device via the proper protocol |
| Hardcoded mode "1280x720" | Query the display hardware for actual supported modes |
| `_firmware: HashMap<String, Vec<u8>>` (unused parameter) | Use the firmware data in device initialization |
| `Ok(self.vblank_count.fetch_add(1, Ordering::SeqCst))` in page_flip | Submit real buffer to hardware and wait for display |
| `todo!()` / `unimplemented!()` | Replace with full implementation |
### Why this matters
Stubs are worse than missing code because they:
- **Hide missing functionality** — the system appears to work but silently does nothing
- **Block real testing** — you can't verify behavior against hardware when the code doesn't talk to hardware
- **Create false confidence** — "it compiles" becomes a substitute for "it works"
- **Compound over time** — one stub leads to another as callers assume the interface is real
- **Waste debugging time** — hours spent tracing why something "doesn't display" when the driver never sent a command
### Enforcement
- Code reviews must reject any PR containing stubs
- Any agent or developer that introduces a stub must replace it before the session ends
- If a stub cannot be replaced (missing specification, blocked dependency), document it as a known gap in `local/docs/` — but never leave it in the code as a stub. Remove the code path entirely and add a clear error message instead.
## LINUX REFERENCE SOURCE POLICY
`local/reference/linux-7.0/` (or later) contains a full Linux kernel source tree for
cross-referencing driver behavior, hardware initialization sequences, register definitions,
and error handling patterns.
**Rules:**
- **NEVER delete** the reference tree. It is gitignored but permanent.
- **ALWAYS consult** the Linux source when building or fixing drivers, daemons, or any subsystem
that has a Linux counterpart (audio/HDA, GPU/DRM, networking, USB, PCI, ACPI, input, storage,
filesystems, scheduler, memory management).
- **Update** the reference tree when a new stable Linux version is needed:
`git -C local/reference/linux-7.0 fetch --depth=1 origin tag:v7.x --force`
- The reference tree is read-only for consultation purposes. No modifications.
- Location: `local/reference/` is gitignored. It survives `make clean` and `make distclean`.
## DURABILITY POLICY
Every change to an upstream-owned source tree (anything under `recipes/*/source/`) **must** be
mirrored into a durable location **in the same work session** it was made. A change that exists
only inside a fetched source tree is not preserved.
**Required actions after any source-tree edit:**
1. **Generate a patch** from the source git diff and save it under `local/patches/<component>/`.
2. **Wire the patch** into the recipe's `recipe.toml` `patches = [...]` list.
3. **Commit** the patch file and recipe change before the session ends.
**Why:** `make distclean`, `make clean`, and source immutable archivedes all
discard or replace `recipes/*/source/` trees. Only `local/patches/`, `local/recipes/`,
tracked configs, `local/docs/`, and `sources/redbear-0.1.0/` survive.
**Examples of changes that require immediate patching:**
| What you edited | Durable location |
|---|---|
| `recipes/core/relibc/source/src/header/sys_select/mod.rs` | `local/patches/relibc/P3-select-not-epoll-timeout.patch` + `recipe.toml` |
| `recipes/core/relibc/source/src/header/signal/cbindgen.toml` | same patch as above |
| `recipes/core/userutils/source/res/issue` | `local/patches/userutils/redox.patch` + `recipe.toml` |
| `recipes/core/kernel/source/...` | `local/patches/kernel/redox.patch` (symlinked from recipe) |
**What does NOT need patching:** Files that already live in `local/`, tracked `config/redbear-*.toml`,
or any path that is already git-tracked and not inside a fetched source tree.
## BUILD SYSTEM POLICIES
### Build Durability Rule — Every Build Lands in the Repo
Every successful `repo cook` produces two durable artifacts:
1. **Package in the repo**: `repo/x86_64-unknown-redox/<name>.pkgar` + `<name>.toml`
2. **Patched source form**: All source modifications are in `local/patches/<component>/` and wired into `recipe.toml`
A build is **not complete** until both artifacts exist:
```bash
# After cooking, verify the package is in the repo
./target/release/repo find <package>
# Check the repo manifest exists
ls repo/x86_64-unknown-redox/<package>.toml
ls repo/x86_64-unknown-redox/<package>.pkgar
```
If a package was built but the repo artifacts are missing, the build did not complete.
Re-run `repo cook <package>` to regenerate them.
If source patches were applied but not mirrored to `local/patches/`, see the
DURABILITY POLICY section above.
### Cascade Rebuild Rule
When a low-level package changes (relibc, kernel, base, or any library), **all
packages that depend on it must be rebuilt**. A stale dependent silently produces
link errors, ABI mismatches, or runtime crashes.
Use the cascade rebuild script:
```bash
# Rebuild relibc and everything that depends on it
./local/scripts/rebuild-cascade.sh relibc
# Dry run: show what would be rebuilt without building
./local/scripts/rebuild-cascade.sh --dry-run relibc
# Multiple root packages
./local/scripts/rebuild-cascade.sh relibc ncurses
```
The script:
1. Finds all packages whose `recipe.toml` lists the target in `dependencies`
2. Transitively expands the reverse dependency graph (BFS)
3. Builds the root package(s) first, then dependents in order
4. Pushes all rebuilt packages to the sysroot
**When to use cascade rebuilds:**
- After changing relibc headers or ABI
- After rebuilding a shared library (ncurses, zlib, openssl, etc.)
- After kernel ABI changes that affect userspace
- After any change to a package listed in other packages' `dependencies`
**When NOT to use cascade rebuilds:**
- Standalone applications with no dependents (editors, games, utilities)
- Terminal/leaf packages that nothing depends on
### Atomic Patch Application
The cookbook tool (`src/cook/fetch.rs`) applies patches **atomically**:
patches are applied to a staging directory (created via `cp -al` hard links),
and only promoted into the live source tree if **all** patches succeed. If any
patch fails, the staging directory is discarded and the source tree remains
untouched.
**The source tree is NEVER left in a partially-patched state.**
When a patch fails, the error message includes the `[ATOMIC]` tag and the
failed patch name. Recovery: fix the patch file, then re-run `repo fetch`.
### Patch Format
Patches may use either format:
- Unified diff (`---`/`+++` lines, preferred — most portable)
- `diff --git` format (auto-normalized by `normalize_patch()`)
- `diff -ruN` format (also auto-normalized — `diff -ruN` headers stripped like `diff --git`)
Git-specific headers (`diff --git`, `diff -ruN`, `index`, `new file mode`, `rename from/to`,
`similarity index`, `dissimilarity index`) are automatically stripped before
`patch` is invoked. The build system uses `--fuzz=3` for resilient context matching.
**Timestamps in `---`/`+++` lines** (common in `diff -ruN` output) should be removed.
Use `--- a/path` and `+++ b/path` without timestamps. The `normalize_patch` function
does NOT strip timestamps — they should be removed from the patch file directly.
### Robust Patch Generation (REQUIRED)
**MANDATORY: All patches MUST be generated using `git diff -U0 -w` from a committed source tree.
Hand-writing unified diffs is FORBIDDEN — it routinely produces incorrect line counts, malformed
hunks, or timestamp headers that cause `patch(1)` to reject them. The build system uses
`--fuzz=3` for resilient context matching, which requires properly generated diffs.**
Context-line mismatches (renamed variables, shifted line numbers, upstream refactors)
are the single largest source of patch application failures. Use the zero-context,
whitespace-ignored technique to make patches resilient to drift:
**Workflow (mandatory):**
```bash
# 1. Start with a clean P0..P(N-1) source tree (repo fetch already applied earlier patches)
cd recipes/<component>/source
# 2. Commit the P0..P(N-1) state as a git baseline
git add -A && git commit -m "P0..P(N-1) baseline"
# 3. Make P(N) edits in the source tree
# (edit files, test compile, etc.)
# 4. Generate the P(N) patch using ONLY git diff -U0 -w:
git diff -U0 -w > ../../../local/patches/<component>/P<N>-<description>.patch
# 5. Wire the patch into recipe.toml patches list
# 6. Validate: repo validate-patches <package>
# 7. Rebuild: repo cook <package>
# 8. Commit: git add local/patches/ recipes/<pkg>/recipe.toml && git commit
```
**Apply (for manual testing):**
```bash
patch -p1 --fuzz=3 < local/patches/<component>/P<N>-<description>.patch>
```
**Why this works:**
- `-U0` produces zero lines of surrounding context, so the patch has no fragile context
lines that can drift when surrounding code changes
- `-w` ignores all whitespace changes, so indentation-only refactors don't break the patch
- `--fuzz=3` allows `patch(1)` to find the target location even when nearby lines have shifted
- Together these three flags eliminate the entire class of "context mismatch" failures
**Why hand-writing is forbidden:**
- Human-written diffs routinely have wrong `@@` line counts, missing or extra context lines,
incorrect `--- a/` / `+++ b/` paths, or embedded timestamps — all of which cause `patch(1)`
to reject the patch or silently apply it to the wrong location
- The `git diff -U0 -w` command produces mechanically correct diffs every time
**Before this technique**, patches routinely broke when:
- A variable was renamed (e.g., `deamon``daemon` in context)
- Lines were added or removed above the changed code
- Indentation was reformatted
- An earlier patch in the chain shifted line numbers
**With this technique**, patches survive all of the above. A hunk consists only of the
changed lines themselves — no context that can go stale.
**Conventions:**
- Always use `--- a/path` and `+++ b/path` headers (no timestamps)
- Always name patches `P<N>-<description>.patch` with sequential numbering
- Always wire patches into `recipe.toml` `patches = [...]` in application order
- Always validate with `repo validate-patches <package>` after creating or editing a patch
- When updating an existing patch, regenerate it entirely rather than editing line numbers manually
### Protected Recipes
Core recipes (`base`, `kernel`, `relibc`, `bootloader`, etc.) and any recipe carrying
Red Bear patches are **protected** and cannot be re-fetched online. Protected recipes
always use offline/archived sources from `sources/redbear-<release>/tarballs/`.
Use the `--allow-protected` flag (or set `REDBEAR_ALLOW_PROTECTED_FETCH=1`) to override
protection (e.g., for debugging or when archives are missing).
```bash
repo --allow-protected fetch base
repo --allow-protected cook base
```
The full protected recipe list (in `src/cook/fetch.rs:redbear_protected_recipe()`)
includes: all core system recipes, all Red Bear custom recipes, all patched Qt/Wayland/
KDE recipes, and all recipes carrying Red Bear patches (Qt, DRM, Mesa, Wayland, D-Bus,
glib, etc.). Any recipe with a `redox.patch` or local patches is a candidate for
protection — add it when adding patches.
### Offline-First By Default
Red Bear OS is a **fork with frozen sources**. The cookbook tool defaults to
`COOKBOOK_OFFLINE=true` (changed from upstream Redox's `false`). Builds use archived
sources from `sources/redbear-0.1.0/` — no network access during compilation.
To allow online fetching for non-protected development recipes:
```bash
COOKBOOK_OFFLINE=false make all CONFIG_NAME=redbear-full
```
In release mode (`REDBEAR_RELEASE=0.1.0`), online fetching is **completely disabled**
even with `COOKBOOK_OFFLINE=false`. Sources are immutable in release mode.
### Workspace Pollution Prevention
Before every fetch and build, the cookbook tool removes orphaned `Cargo.toml`
and `Cargo.lock` files from `recipes/` root. These files can appear as side
effects of relibc workspace builds and cause "current package believes it's in
a workspace" errors.
### Patch Chain Ordering
Patches in `recipe.toml` are applied in listed order. Dependencies between
patches must be respected:
- Patches that **define** types (e.g., `InputProducer`) must come BEFORE
patches that **use** those types
- Patches that **create** files must come BEFORE patches that **modify** them
- Cumulative patches (P0 → P2 → P3) must maintain correct line number context
When reordering patches: remove the source tree, re-fetch, and rebuild to verify.
### MEGA-PATCH + INDIVIDUAL PATCH DISCIPLINE (CRITICAL)
**This is the single most common source of build failures in Red Bear OS.**
Violating these rules causes patches to silently drift, overlap, or conflict —
wasting hours of debugging time.
#### The Two-Layer Architecture
Each patched component (base, kernel, relibc) uses two patch layers:
1. **The mega-patch** (`redox.patch`) — a single consolidated `git diff` of the
entire source tree against upstream. Applied first. This is the **frozen baseline**
of all Red Bear work up to a known date.
2. **Individual P-patches** (`P10-*.patch`, `P11-*.patch`, etc.) — granular,
single-purpose patches for new work done AFTER the mega-patch was generated.
Applied after the mega-patch, in listed order.
The `recipe.toml` patches list looks like:
```toml
patches = [
"redox.patch", # Layer 1: frozen baseline
"P10-rootfs-uuid-search-no-block.patch", # Layer 2: new work on top
"P11-init-noise-reduction.patch", # Layer 2: new work on top
]
```
#### The Discipline (MANDATORY)
| Rule | Why | What happens if violated |
|------|-----|--------------------------|
| **NEVER regenerate `redox.patch` from a source tree that includes P-patches** | The mega-patch absorbs P-patch changes, making P-patches redundant. They then fail to apply ("Reversed or previously applied") on the next clean build. | P-patches conflict with their own changes inside the mega-patch. Build fails. |
| **New work always goes as P-patches AFTER the mega-patch** | Keeps the mega-patch frozen. Each P-patch is a small, reviewable delta. | Mixing changes into the mega-patch makes it a monolith with no logical structure. |
| **To regenerate `redox.patch`, first fold all P-patches into it, then remove them from `recipe.toml`** | Consolidation pass must be atomic — absorb and remove in one step. | Orphan P-patches in `recipe.toml` reference changes already in the mega-patch. |
| **P-patches MUST apply cleanly on top of the mega-patch-only state** | The build system applies patches sequentially: upstream → mega-patch → P-patches. | Build fails on clean fetch. |
| **Validate with `repo validate-patches` after ANY patch change** | Catches drift before it reaches the build. | Drift silently accumulates until the next clean build explodes. |
#### How to Make a New Change (Correct Workflow)
```bash
# 1. Source tree already has mega-patch + existing P-patches applied (working tree)
cd recipes/core/base/source
# 2. Make your edit
vim init/src/main.rs
# 3. Generate the patch against the current git HEAD (upstream rev)
git diff -U0 -w -- init/src/main.rs > ../../../local/patches/base/P<next>-<desc>.patch
# 4. Create symlink and wire into recipe.toml
cd ../../../recipes/core/base
ln -s ../../../local/patches/base/P<next>-<desc>.patch P<next>-<desc>.patch
# Add "P<next>-<desc>.patch" to patches list in recipe.toml
# 5. Validate and rebuild
cd ../../..
./target/release/repo validate-patches base
CI=1 ./target/release/repo cook base-initfs
```
#### How to Consolidate (Periodic Maintenance)
When P-patches accumulate and the mega-patch should absorb them:
```bash
# 1. Source tree has mega-patch + all P-patches applied
cd recipes/core/base/source
# 2. Generate NEW mega-patch from full diff
git diff -U0 -w > ../../../local/patches/base/redox.patch
# 3. Remove ALL P-patches from recipe.toml patches list
# Keep P-patch FILES in local/patches/base/ for history — just remove from recipe.toml
# 4. Validate
./target/release/repo validate-patches base
# 5. Rebuild
CI=1 ./target/release/repo cook base-initfs
```
#### How NOT to Break Things
| Action | Correct | WRONG |
|--------|---------|-------|
| Add new feature | Create P-patch, add after mega-patch in recipe.toml | Regenerate mega-patch from tree that includes P-patches |
| Fix a bug | Create P-patch | Edit mega-patch directly |
| Consolidate | Regenerate mega-patch, remove ALL P-patches from recipe.toml | Regenerate mega-patch but leave P-patches in recipe.toml |
| Update upstream | Provision new release, rebase mega-patch | Cherry-pick upstream commits into source tree |
#### Root Cause of Past Failures
The pattern that has recurred multiple times:
1. Mega-patch generated at time T
2. P-patches added at time T+1, T+2, etc.
3. Someone regenerates mega-patch from source tree at T+3 (which includes P-patch changes)
4. Mega-patch now contains P-patch changes
5. P-patches still in `recipe.toml` try to re-apply their changes → conflicts
6. Build fails with "Reversed or previously applied" and hunk failures
7. Hours spent debugging why "patches that used to work" now fail
**The fix is always the same**: either (a) remove the absorbed P-patches from `recipe.toml`,
or (b) regenerate the mega-patch from a tree WITHOUT P-patch changes. Option (a) is faster.
### Large Patch Files (redox.patch)
`local/patches/base/redox.patch` (consolidated mega-patch) is currently ~544K.
If it grows beyond a manageable size, it can be chunked under
`local/patches/base/redox-patch-chunks/` and reassembled by:
```bash
local/patches/base/reassemble-redox-patch.sh
```
### Patch Governance
See `local/docs/PATCH-GOVERNANCE.md` for the full patch governance rules.
Critical rules:
- **Never remove patches** to fix build failures — rebase them
- **Never remove BINS entries** — fix the source or use `EXISTING_BINS`
- **Recipe.toml is git-tracked** — changes to it are durable
- **Source trees are disposable** — `repo clean`/`distclean` destroy them
- **All source changes must be patches** in `local/patches/`
- **Commit patch files and recipe.toml changes** before session end
- **NEVER regenerate mega-patch from a tree that includes P-patches** — see MEGA-PATCH DISCIPLINE above
### Build Validation
After ANY change to patches or `recipe.toml`:
1. Validate patches: `./target/release/repo validate-patches <recipe>`
2. Remove source: `rm -rf recipes/core/<recipe>/source`
3. Fetch: `repo --allow-protected fetch <recipe>`
4. Build: `repo cook <recipe>`
5. Verify no `FAILED`, `[ATOMIC] patch application rolled back`, or `.rej` files
6. Full image: `make all CONFIG_NAME=<target>`
The `repo validate-patches` command (added 2026-05) performs a dry-run patch
application against clean upstream source in a temporary staging directory.
It reports per-patch `[PASS]`/`[FAIL]` status without modifying the live source
tree. Always run it before attempting a full build when patches have changed.
## PATCH MANAGEMENT
All Red Bear OS modifications to upstream files are kept separately in `local/patches/`.
This is not just a convenience rule; it is a long-term maintenance rule. For fast-moving upstream
areas like relibc, prefer the upstream solution whenever upstream already solves the same problem.
Keep Red Bear patch carriers only for gaps or compatibility work that upstream still does not solve
adequately.
When upstream Redox already provides a package, crate, or subsystem for functionality that also
exists in Red Bear local code, prefer the upstream Redox version by default unless the Red Bear
implementation is materially better. Do not grow lower-quality in-house duplicates as a steady
state.
For quirks and driver support specifically:
- prefer improving and using the canonical `redox-driver-sys` path,
- avoid maintaining separate lower-quality quirk engines when the same functionality belongs in
`redox-driver-sys`,
- if duplication is temporarily unavoidable, treat it as convergence work to remove, not as a
permanent design.
### Structure
```
local/patches/
├── kernel/redox.patch # Applied to kernel source during build (symlinked from recipe)
├── kernel/P0-*.patch # Individual logical patches (for reference/merge)
├── base/redox.patch # Applied to base source during build (symlinked from recipe)
├── base/P0-*.patch # Individual logical patches
├── relibc/P3-*.patch # POSIX gap patches (eventfd, signalfd, timerfd, etc.)
├── installer/redox.patch # Installer ext4 + GRUB bootloader support
└── build-system/
├── 001-rebrand-and-build.patch # Makefile, mk/*, scripts, build.sh rebranding
├── 002-cookbook-fixes.patch # src/ Rust fixes (fetch.rs, staged_pkg.rs, repo.rs, html.rs)
├── 003-config.patch # config/*.toml changes (os-release, hostname, redbear-full)
└── 004-docs-and-cleanup.patch # README, CONTRIBUTING, LICENSE, deleted upstream files
```
### Protection Mechanism
1. **Recipe patches** (`kernel/redox.patch`, `base/redox.patch`): Canonical copy lives in
`local/patches/`. The recipe directory contains a **symlink** to it:
```
recipes/core/kernel/redox.patch → ../../../local/patches/kernel/redox.patch
recipes/core/base/redox.patch → ../../../local/patches/base/redox.patch
```
The build system follows symlinks transparently. Patches are never touched by `make clean`
or `make distclean`. Only `local/` modifications affect them.
2. **Build-system patches**: Generated via `git diff` against the upstream base commit.
These serve as a backup — the working tree already has patches applied (via git commits).
If upstream update via rebase fails, these can be applied from scratch.
3. **Custom recipes**: Live entirely in `local/recipes/` with symlinks into `recipes/`:
```
recipes/drivers/linux-kpi → ../../local/recipes/drivers/linux-kpi
recipes/gpu/amdgpu → ../../local/recipes/gpu/amdgpu
recipes/system/firmware-loader → ../../local/recipes/system/firmware-loader
... etc
```
### Scripts
| Script | Purpose |
|--------|---------|
| `local/scripts/apply-patches.sh` | Apply all build-system patches + create recipe symlinks |
| `local/scripts/provision-release.sh` | Provision new release from Redox ref + archive sources |
| `local/scripts/check-upstream-releases.sh` | Check for new Redox snapshots (read-only) |
### Release Model (Fork)
Red Bear OS is a full fork based on frozen Redox snapshots. Sources are immutable
and never auto-immutable archived. The current baseline is 0.1.0.
```bash
# Check for newer Redox snapshots (read-only, zero side effects):
./local/scripts/check-upstream-releases.sh
# Provision a new release (explicit, human-initiated only):
./local/scripts/provision-release.sh --ref=<redox-tag> --release=0.2.0 --dry-run
```
## AMD-FIRST INTEGRATION PATH
See `local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md` for the canonical desktop path plan.
**Target**: AMD64 bare metal, with AMD and Intel machines treated as equal-priority hardware targets.
**amdgpu is 6M+ lines — 18x larger than Intel i915. LinuxKPI compat approach mandatory.**
### Bare Metal Boot Status
| Component | Status | Detail |
|-----------|--------|--------|
| UEFI boot | ✅ | x86_64 bootloader functional |
| AMD CPUs | ✅ | Ryzen Threadripper 128-thread verified |
| ACPI | ✅ Boot-baseline complete | RSDP/SDT checksums, MADT types 0x4/0x5/0x9/0xA, LVT NMI, FADT shutdown/reboot, explicit `RSDP_ADDR` forwarding into `acpid`, x86 BIOS-search AML fallback, and bounded AML-backed power enumeration are present; the explicit AML bootstrap producer contract and broader robustness still remain open — see `local/docs/ACPI-IMPROVEMENT-PLAN.md` |
| ACPI shutdown | 🚧 | PM1a/PM1b S5 via `\_S5` AML exists, but shutdown robustness and bounded validation are still open |
| ACPI reboot | 🚧 | Reset register + keyboard controller fallback exist, but broader reboot correctness and bounded validation are still open |
| ACPI power | 🚧 | `\_PS0`/`\_PS3`/`\_PPC` AML methods are available and the runtime power surface performs bounded AML-backed enumeration, but bootstrap preconditions and validation are still too weak for stronger support claims; see `local/docs/ACPI-IMPROVEMENT-PLAN.md` |
| x2APIC/SMP | ✅ | Multi-core works |
| IOMMU | 🚧 | QEMU first-use proof now passes; real hardware validation still open |
| AMD GPU | 🚧 | MMIO mapped, bounded Red Bear display glue path builds, MSI-X wired; imported Linux AMD DC/TTM/core remain builds and included in redbear-full (2026-04-29); no hardware validation yet |
### Phased Roadmap (historical P0P6)
> **Note:** The P0P6 numbering below is the historical hardware-enablement sequence.
> The canonical current desktop path plan uses a new Phase 15 structure documented in
> `local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md` (v2.0, 2026-04-16).
| Phase | Duration | Delivers |
|-------|----------|----------|
| ~~P0: Fix ACPI for AMD~~ | ~~4-6 weeks~~ | ✅ Materially complete — boots on modern AMD bare metal; see `local/docs/ACPI-IMPROVEMENT-PLAN.md` for forward work |
| ~~P1: Driver infrastructure~~ | ~~8-12 weeks~~ | ✅ Complete — redox-driver-sys + linux-kpi + firmware-loader + pcid /config + MSI-X (compiles) |
| ~~P2: AMD GPU display~~ | ~~12-16 weeks~~ | 🚧 Partial — redox-drm + bounded Red Bear AMD display glue build; imported Linux AMD DC/TTM/core remain builds and included in redbear-full (2026-04-29); Intel driver compiles, no HW validation |
| ~~P3: POSIX + input~~ | ~~4-8 weeks~~ | 🚧 Build-side work substantially complete — the active relibc recipe patch chain now carries the bounded fd-event, semaphore, and waitid compatibility surface needed by current downstreams, while broader runtime validation and input-stack maturity remain open |
| P4: Wayland compositor | 4-6 weeks | 🚧 Partial — libwayland/Qt6 Wayland/Mesa EGL+GBM+GLES2/Qt6 OpenGL now build, but compositor/runtime validation is still incomplete |
| ~~P5: DML2 enablement~~ | ~~partial~~ | 🚧 Historical DML2 config work landed, but the current retained AMDGPU build no longer treats imported DML2/TTM as part of the default bounded compile path; libdrm amdgpu ✅, `iommu` daemon now builds; hardware validation still open |
| P6: KDE Plasma | 12-16 weeks | 🚧 In progress — Qt6 ✅, KF6 32/32 ✅, Mesa EGL/GBM/GLES2 ✅, kf6-kcmutils ✅, kf6-kwayland ✅, kdecoration ✅, KWin 🔄 building |
### Canonical Desktop Path (current plan)
The current execution plan uses a three-track model with new Phase 15 numbering:
- **Phase 1:** Runtime Substrate Validation (46 weeks)
- **Phase 2:** Wayland Compositor Proof (46 weeks)
- **Phase 3:** KWin Desktop Session (610 weeks)
- **Phase 4:** KDE Plasma Session (812 weeks)
- **Phase 5:** Hardware GPU Enablement (1220 weeks, parallel with 34)
See `local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md` for full detail.
**Total to software-rendered KDE Plasma**: 2234 weeks (~68 months) with 2 developers.
**Total to hardware-accelerated KDE Plasma**: 3454 weeks (~813 months) with 2 developers.
### Critical Path
```
Phase 1 (runtime substrate) → Phase 2 (software compositor) → Phase 3 (KWin session) → Phase 4 (KDE Plasma)
Phase 5 (hardware GPU, parallel with Phases 34)
```
### Custom Crates (P1/P2)
1. `redox-driver-sys` — `local/recipes/drivers/redox-driver-sys/source/` — Safe Rust wrappers for scheme:memory, scheme:irq, scheme:pci + hardware quirks system (`src/quirks/`)
2. `linux-kpi` — `local/recipes/drivers/linux-kpi/source/` — C headers translating Linux kernel APIs → redox-driver-sys; includes `pci_get_quirk_flags()` C FFI for quirk queries. **GPU and Wi-Fi drivers only — linux-kpi does NOT cover USB.** It provides PCI, DMA, IRQ, DRM, networking (ieee80211/nl80211/mac80211), firmware, and related kernel infrastructure headers, but contains zero USB headers, USB device ID tables, or USB driver implementations.
3. `redox-drm` — `local/recipes/gpu/redox-drm/source/` — DRM scheme daemon (AMD + Intel drivers); consumes quirk flags for MSI/MSI-X fallback and DISABLE_ACCEL
4. `firmware-loader` — `local/recipes/system/firmware-loader/source/` — scheme:firmware for GPU blobs
5. `amdgpu` — `local/recipes/gpu/amdgpu/source/` — AMD DC C port with linux-kpi compat; can query quirks via `pci_has_quirk()` FFI
6. `redbear-sessiond` — `local/recipes/system/redbear-sessiond/source/` — Rust D-Bus session broker exposing `org.freedesktop.login1` subset for KWin (uses `zbus`)
7. `redbear-dbus-services` — `local/recipes/system/redbear-dbus-services/` — D-Bus activation `.service` files and XML policy files for system and session buses
All custom work goes in `local/` — see `local/AGENTS.md` for fork model usage.
## NOTES
- Build requires Linux x86_64 host, 8GB+ RAM, 20GB+ disk
- QEMU used for testing (make qemu). VirtualBox also supported
- The `repo` binary (cookbook CLI) may crash with TUI in non-interactive environments — use `CI=1`
- No git submodules — external repos managed via recipe source URLs and repo manifests
- Historical integration report removed (2026-04-16); see `local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md` for current state
## WARNING POLICY
When presented with a compiler warning, linker warning, runtime warning, or test warning, the
project treats it as a signal requiring action — not as noise to be silenced or deferred.
- **Investigate** every warning. Understand what causes it and whether it indicates a real defect.
- **Fix the root cause** when feasible. Prefer comprehensive fixes over workarounds.
- **Suppress only as last resort**, with a comment explaining why the warning is known-safe and
why suppression is the correct choice for that specific case.
- **Never ignore warnings silently.** An unexplained warning in the build is a defect in
discipline, not just in code.
This applies to all subsystems: kernel, relibc, drivers, userspace daemons, and build tooling.
## SUBSYSTEM PRIORITY AND ORDER
Red Bear OS should treat low-level controllers, USB, Wi-Fi, and Bluetooth as first-class subsystem
targets.
For PCI interrupt plumbing, IRQ delivery quality, MSI/MSI-X follow-up, low-level controller
runtime-proof sequencing, and IOMMU/interrupt-remapping quality, the canonical current plan is:
- `local/docs/IRQ-AND-LOWLEVEL-CONTROLLERS-ENHANCEMENT-PLAN.md`
Use that file as the execution authority and current robustness judgment for PCI/IRQ work. Higher-
level summaries in `README.md`, `docs/README.md`, and this file should stay aligned with its
validation language rather than acting as competing rollout plans.
Current execution order:
1. low-level controllers / IRQ quality / runtime-proof
2. USB controller and topology maturity
3. Wi-Fi native control-plane and one bounded driver path
4. Bluetooth host/controller path
5. desktop/session compatibility layers on top of those runtime services
Current blocker emphasis:
- low-level controller quality blocks reliable USB and Wi-Fi validation
- USB maturity blocks the realistic first Bluetooth transport path
- Wi-Fi and Bluetooth should not be treated as optional polish; both remain missing subsystem work
that must be implemented fully, but in the right order