Files
RedBear-OS/AGENTS.md
vasilito 29ff1ea8fc feat: ACPI Wave 1 boot-critical hardening (P19) + robust patch generation
- P19-init-startup-hardening: Replace panic-grade expect/unwrap in init
  startup paths (getns, register_scheme_to_ns, setrens, filename parsing)
  with graceful error handling and logging
- P19-acpid-startup-hardening: Replace panic-grade calls in acpid with
  graceful degradation (rxsdt read failure → warn + exit 0, SDT parse →
  error + exit 1, I/O privilege → fatal, scheme registration → fatal,
  setrens → warn + continue, event loop errors → log + continue)
- P18-9-msi-allocation-resilience: Regenerate with git diff -U0 -w format
  for maximum context resilience
- fetch.rs: Change --fuzz=0 to --fuzz=3 for resilient patch application
- AGENTS.md: Document robust patch generation technique as mandatory
- Add P4/P5/P6/P7 patches (estale, dmi, i2c, ps2d hardening)
- Add P21 kernel x2apic SMP fix patch
- Multiple local recipe source improvements (redox-drm, driver-manager,
  driver-acpi, thermald)
- Config updates for redbear-mini and redbear-device-services
- Subsystem assessment document
2026-05-18 14:07:42 +03:00

50 KiB
Raw Permalink Blame History

RED BEAR OS BUILD SYSTEM — PROJECT KNOWLEDGE BASE

Generated: 2026-04-12 (P1/P2 complete) 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

Never edit files under recipes/*/source/ directly. 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.

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
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>/:

[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

# 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

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:

# 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:

# 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)

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:

Generate:

cd recipes/<component>/source
git diff -U0 -w > ../../../local/patches/<component>/P<N>-<description>.patch

Apply:

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

Before this technique, patches routinely broke when:

  • A variable was renamed (e.g., deamondaemon 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).

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:

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.

Large Patch Files (redox.patch)

local/patches/base/redox.patch (consolidated mega-patch) is stored as 90 MB chunks under local/patches/base/redox-patch-chunks/ and reassembled by:

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 disposablerepo clean/distclean destroy them
  • All source changes must be patches in local/patches/
  • Commit patch files and recipe.toml changes before session end

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.

# 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-syslocal/recipes/drivers/redox-driver-sys/source/ — Safe Rust wrappers for scheme:memory, scheme:irq, scheme:pci + hardware quirks system (src/quirks/)
  2. linux-kpilocal/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-drmlocal/recipes/gpu/redox-drm/source/ — DRM scheme daemon (AMD + Intel drivers); consumes quirk flags for MSI/MSI-X fallback and DISABLE_ACCEL
  4. firmware-loaderlocal/recipes/system/firmware-loader/source/ — scheme:firmware for GPU blobs
  5. amdgpulocal/recipes/gpu/amdgpu/source/ — AMD DC C port with linux-kpi compat; can query quirks via pci_has_quirk() FFI
  6. redbear-sessiondlocal/recipes/system/redbear-sessiond/source/ — Rust D-Bus session broker exposing org.freedesktop.login1 subset for KWin (uses zbus)
  7. redbear-dbus-serviceslocal/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