Files
vasilito 890be982a6 docs: enforce canonical build command across all docs
Replace all non-canonical build invocations (bare 'make all/live
CONFIG_NAME=', 'scripts/build-iso.sh', 'scripts/run.sh') with the
canonical './local/scripts/build-redbear.sh' wrapper.

Updated: AGENTS.md, local/AGENTS.md, README.md, docs/README.md,
docs/06-BUILD-SYSTEM-SETUP.md, and 6 active local/docs plan files.
Archived docs and frozen boot-logs left as-is (historical evidence).
2026-07-02 22:54:47 +03:00

68 KiB
Raw Permalink Blame History

RED BEAR OS — DERIVATIVE OF REDOX OS

This directory contains ALL custom work on top of mainline Redox. When mainline Redox updates (git pull on the build system repo), this directory is untouched.

STUB AND WORKAROUND POLICY — ZERO TOLERANCE

Red Bear OS has zero tolerance for stubs, workarounds, #ifdef-guarded no-ops, fake headers, shell-script patches, sed/awk hacks, LD_PRELOAD tricks, rename-to-.disabled wrappers, or any other "make it compile" shortcut.

If something doesn't build because of a missing implementation, the ONLY acceptable response is to implement the missing functionality in the correct component:

Problem Correct Fix
eventfd() not found Implement eventfd() in relibc, generate sys/eventfd.h via cbindgen
signalfd() not found Implement signalfd() in relibc, generate sys/signalfd.h via cbindgen
Missing POSIX type Add it to the relibc header it belongs to, with proper stdint.h include chain
Compiler can't find header Fix the include path in the recipe's sysroot/cookbook, NOT by adding -I hacks
CMake can't find dependency Implement the dependency or fix pkg-config, NOT with -DFEATURE_x=OFF
Qt needs open_memstream Implement it in relibc — never add a static stub in Qt or libwayland source

Any stub found in the tree is a bug to be fixed, not a precedent to follow.

When relibc gains a function or type that obsoletes a previously-needed local stub, the stub MUST be removed and the dependency switched to relibc's implementation. Coexistence of stubs with real implementations causes header conflicts, linker errors, and silent ABI mismatches.

This applies to: relibc functions, kernel syscalls, C headers, CMake modules, pkg-config .pc files, Wayland protocol stubs, D-Bus service stubs, and any other layer of the stack.

No exceptions. No "temporary." No "until we fix it properly."

DESIGN PRINCIPLE

Red Bear OS is a full fork based on frozen Redox OS snapshots:

  • We baseline on a specific Redox OS state and work from immutable, archived sources
  • The local/ directory contains our custom work — untouched by any source immutable archived
  • First-class configs use redbear-* naming (not my-*, which is gitignored)
  • Sources are NEVER auto-immutable archived from upstream — all changes are explicit, human-initiated

FREE/LIBRE SOFTWARE POLICY

Red Bear OS must remain a free/libre project.

  • Prefer components that are open-source, freely available to all users, or built in-tree by Red Bear.
  • Do not introduce proprietary, source-unavailable, paywalled, or redistributability-restricted dependencies into the tracked system surface.
  • When a dependency is dual-licensed under multiple free/open licenses, choose and document the option that is compatible with the Red Bear project surface.
  • For the greeter/login stack specifically, the current SHA-crypt verifier path is the pure-Rust sha-crypt crate, licensed MIT OR Apache-2.0; Red Bear treats it under the MIT option for compatibility with the project's free-software policy.

OUR GIT SERVER

Red Bear OS is hosted on a self-hosted Gitea instance at gitea.redbearos.org. This is the only canonical home for our fork — there is no GitHub / GitLab / Codeberg mirror that is treated as authoritative. All Red Bear custom work, including local recipe sources that have no upstream, lives here.

SINGLE-REPO RULE (ABSOLUTE — DO NOT VIOLATE)

The Red Bear OS project exists as exactly ONE git repository:

Field Value
Repo vasilito/RedBear-OS (canonical slug: redbear-os)
Host https://gitea.redbearos.org
User vasilito

There MUST NEVER be any other repositories related to this project on gitea.redbearos.org. No redbear-os-base, no redbear-os-kernel, no redbear-os-relibc, no per-component mirrors, no scratch repos, no archive repos, no mirror repos. Nothing.

Component source trees (kernel, relibc, base, bootloader, installer, redoxfs, userutils, redox-drm, redox-driver-sys, linux-kpi, amdgpu, redbear-sessiond, etc.) are NOT separate repositories. They live inside RedBear-OS either as:

  • Submodules — pinned to a specific commit, each on its own branch inside this same RedBear-OS repo (submodule/<component> branches), OR
  • Tracked trees under local/sources/<component>/ — full source snapshots committed directly to the RedBear-OS repo as ordinary files, versioned by Red Bear commits (not by external git history).

Operators and agents MUST NOT:

  • create a new repository on gitea.redbearos.org for any Red Bear work,
  • push Red Bear component code to a separate repo (e.g. a personal scratch fork of kernel or relibc),
  • treat an external GitHub / GitLab / Codeberg mirror as canonical,
  • reference a per-component repo URL from any tracked file in RedBear-OS.

If a recipe's [source] section currently points at a separate repo URL (e.g. https://gitea.redbearos.org/vasilito/redbear-os-base), that URL is deprecated and must be migrated:

  1. Create or reuse a branch inside RedBear-OS named submodule/<component> (e.g. submodule/relibc).
  2. Push the component's source tree to that branch.
  3. Replace the recipe's git = "..." URL with the in-repo submodule path, and add a [submodule] entry referencing the new branch.
  4. Update local/AGENTS.md and any other references.

Enforcement. The cookbook's fetch/validation path treats any component source fetched from outside RedBear-OS as a misconfiguration. Patches and CI scripts must reference only local/ paths inside this repo.

Why this rule exists. A single canonical repo means:

  • one durable source of truth for the entire fork,
  • one token, one clone, one CI pipeline, one backup surface,
  • no "lost fork" failure mode for component subprojects,
  • no accidental public surface (e.g. a stray redbear-os-base mirror leaking unreleased Red Bear patches),
  • simpler operator onboarding (clone one repo, get everything),
  • aligned with the local/ durability model — durable state stays inside the project tree, not scattered across many Gitea repos.

Migration status (as of 2026-07-01)

Migration complete. Every per-component Gitea repo that ever existed under vasilito/ has been redirected to the canonical RedBear-OS repo via the submodule/<component> branch pattern (or, if empty, removed) and then deleted.

9 submodule/<component> branches now exist on RedBear-OS:

Submodule path Branch Status
local/sources/base submodule/base declared in .gitmodules
local/sources/bootloader submodule/bootloader declared
local/sources/installer submodule/installer declared
local/sources/kernel submodule/kernel declared
local/sources/libredox submodule/libredox declared
local/sources/redoxfs submodule/redoxfs declared
local/sources/relibc submodule/relibc declared
local/sources/syscall submodule/syscall declared
local/sources/userutils submodule/userutils declared

4 former per-component repos had no source content (empty Gitea repos, 0 commits) and their gitlinks were removed from the index: local/sources/ctrlc, local/sources/libpciaccess, local/sources/redox-drm, local/sources/sysinfo. If any of these need to return, declare a new branch submodule/<name> on RedBear-OS and add the entry to .gitmodules.

Current Gitea state under vasilito/:

  • RedBear-OS — the canonical Red Bear OS repo.
  • hiperiso — unrelated personal project (kept per operator request).

That is all. No other repos.

Migration procedure (executed; reference for re-runs)

The migration was performed with the helper scripts in local/scripts/:

Script Purpose
local/scripts/redirect-to-submodules.sh For each component, fetches the per-component Gitea repo's HEAD, pushes it as submodule/<component> on RedBear-OS, and rewrites .gitmodules to point at the new branch. Idempotent. Empty source repos are skipped.
local/scripts/delete-per-component-repos.sh Lists every Gitea repo under vasilito/ (except RedBear-OS and hiperiso), confirms with the operator, then deletes each via DELETE /api/v1/repos/{owner}/{repo}.

To re-run for a future component (e.g. a new per-component repo that someone accidentally creates):

  1. Verify the per-component repo is a Red Bear component, not unrelated.
  2. export REDBEAR_GITEA_TOKEN=... (or set up ~/.netrc).
  3. Push the working-tree HEAD as a branch:
    cd local/sources/<component>
    git push https://${REDBEAR_GITEA_TOKEN}@gitea.redbearos.org/vasilito/RedBear-OS.git \
      HEAD:refs/heads/submodule/<component>
    
  4. Declare it in .gitmodules (copy an existing entry, change the name + branch).
  5. ./local/scripts/delete-per-component-repos.sh to remove the orphaned repo.

To verify the rule holds at any time:

# Should print only: hiperiso, RedBear-OS
curl -fsS 'https://gitea.redbearos.org/api/v1/users/vasilito/repos?limit=200' \
  | jq -r '.[].name' | sort

# Should print zero matches (CHANGELOG.md historical entries are exempt)
grep -rn 'gitea.redbearos.org/vasilito/redbear-os-' . --include='*.md' \
  | grep -v 'CHANGELOG.md'

Connection details

Field Value
Host https://gitea.redbearos.org
User vasilito
Token (session-only — not stored in repo; see Token Policy below)
Web UI https://gitea.redbearos.org/vasilito
API root https://gitea.redbearos.org/api/v1

Token Policy (NEVER STORE OPERATOR TOKENS IN TRACKED DOCS). The vasilito Gitea token is treated as an ephemeral per-session credential. It is supplied at runtime via:

  • git credential.helper (preferred — store / cache / libsecret)
  • ~/.netrc (machine gitea.redbearos.org login vasilito password <token>)
  • the REDBEAR_GITEA_TOKEN env var (read by CI scripts)
  • the URL itself, for one-off authenticated clones (visible in shell history — only acceptable in disposable sandboxes)

Never commit a token to local/, docs/, README.md, or any other tracked file. Never bake it into .git/config on a shared machine. Never paste it into chat logs, screenshots, error reports, or shell recordings. If a token leaks, rotate it immediately via the Gitea web UI (https://gitea.redbearos.org/user/settings/applications).

When this file is updated, leave the Token row as a placeholder. The actual value lives only on the operator's workstation, in CI secrets, or in pass/1Password/Vault.

Component sources inside RedBear-OS

Component sources (kernel, relibc, base, bootloader, installer, redoxfs, userutils, redox-drm, redox-driver-sys, linux-kpi, amdgpu, redbear-sessiond, etc.) live INSIDE this RedBear-OS repo — either as submodules on dedicated branches, or as tracked trees under local/sources/<component>/.

They are NOT separate Gitea repositories. See SINGLE-REPO RULE above.

Naming note. Gitea normalizes repository slugs to lowercase. Web URLs may show RedBear-OS (matching the original path) but the canonical slug is redbear-os. Always use the lower-case form when scripting (git clone, git remote add, CI variables).

How to clone

# Public read-only clone (no token)
git clone https://gitea.redbearos.org/vasilito/RedBear-OS.git
cd RedBear-OS

# Authenticated clone — supply the token ONLY at the command line
# (visible in shell history — only acceptable in disposable sandboxes)
git clone https://vasilito:$REDBEAR_GITEA_TOKEN@gitea.redbearos.org/vasilito/RedBear-OS.git

Configuring a remote on an existing clone

# Read-only remote
git remote add origin https://gitea.redbearos.org/vasilito/RedBear-OS.git

# Authenticated remote — use credential helper, NOT a token in the URL
git config --global credential.helper store   # or libsecret / cache
git pull                                     # prompts for user + token, stores in ~/.git-credentials

# Verify (URL should NOT contain the token)
git remote -v

If a token has ended up in .git/config (e.g. from a paste-into-URL mistake), wipe it with git credential erase or pass, then re-add the remote URL without credentials.

Authentication for the cookbook

The cookbook tool (src/bin/repo.rs) reads HTTPS Basic-auth credentials from .gitconfig, .netrc, or the URL itself when fetching Red Bear local-fork recipes. The REDBEAR_ALLOW_PROTECTED_FETCH=1 env var (set by build-redbear.sh --upstream) authorizes the fetch; the actual credentials must be supplied separately.

For CI / Docker builds, mount a .netrc (or the team's secret manager):

machine gitea.redbearos.org
login vasilito
password <token from CI secret, never literal in this repo>

The token row above is intentionally not filled in. CI should template it from $REDBEAR_GITEA_TOKEN (or the equivalent Vault / 1Password secret reference).

Pushing changes

# Recommended: pre-flight check before any push
git status --short
git diff --stat HEAD
git fetch origin
git log --oneline origin/$(git branch --show-current)..HEAD

# Push (uses credential helper, prompts once per session if needed)
git push origin <branch>

CI rule: never force-push to main / master / 0.x branches. Force-push is only permitted on personal feature branches that have not yet been merged.

Gitea API quick reference

For ad-hoc queries, supply the token via env var (never inline in the command for anything that lands in a shared shell history, log, or CI artifact):

# List repos visible to vasilito
curl -sS -H "Authorization: token $REDBEAR_GITEA_TOKEN" \
  https://gitea.redbearos.org/api/v1/users/vasilito/repos | jq '.[].full_name'

# List open issues on the main repo (public endpoint, no token)
curl -sS https://gitea.redbearos.org/api/v1/repos/vasilito/RedBear-OS/issues?state=open | jq

For mirroring or bulk migration tasks, see local/scripts/sync-versions.sh and local/scripts/check-upstream-releases.sh for examples of Gitea-aware shell scripts.

Operator runbook

If the server is unreachable:

  1. Check https://gitea.redbearos.org/ in a browser. If down, halt all pushes.
  2. If a credential has leaked, rotate the token via the Gitea web UI: https://gitea.redbearos.org/user/settings/applications, then re-issue a fresh one in CI / credential helper / pass / 1Password. Do not paste the new token into any file in this repo.
  3. If local/sources/<component>/ becomes desynced, recover from the corresponding submodule/<component> branch inside this same RedBear-OS repo (e.g. origin/submodule/relibc) rather than from upstream Redox. Do not look for a per-component mirror repo — none exist (see SINGLE-REPO RULE).

Recovery from credential loss

If the Gitea user has lost access to the token entirely:

  1. SSH/console into the Gitea host as an admin, or have an admin reset the user's password.
  2. Log in via web UI, generate a new personal access token under Settings → Applications → Manage Access Tokens.
  3. Push the new token into the team's secret store only. Do not commit it.
  4. Update the running CI runners and any local .netrc / credential helper stores on workstations — none of which live in this repo.

If the token has been committed to this repo by mistake, treat it as compromised: rotate immediately, then git filter-repo (or BFG) the offending file from history and force-push the rewritten history on a feature branch before merging.

Build flow:

./local/scripts/build-redbear.sh <config>
  → .config parsing, prefix staleness detection, local-over-WIP policy
  → repo cook builds all packages from local sources (offline by default)
  → mk/disk.mk creates <config>.iso (live ISO) with Red Bear branding
  → Output: build/<arch>/<config>.iso

Release flow:

# Sources are immutable — build from archives, never from network
./local/scripts/build-redbear.sh redbear-full

# Check for newer Redox snapshots (read-only, no 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

ACTIVE COMPILE TARGETS

The supported compile targets are exactly three. build-redbear.sh produces a live ISO for each:

  • redbear-full — Desktop/graphics-enabled target (Wayland + KDE + GPU drivers)
  • redbear-mini — Text-only console/recovery/install target
  • redbear-grub — Text-only target with GRUB boot manager

Desktop/graphics are available only on redbear-full.

RELEASE MODEL (FORK — NOT OVERLAY)

Red Bear OS sources are frozen at release 0.1.0. Sources are immutable and archived in sources/redbear-0.1.0/. Network access during builds is disabled by default.

How releases work:

  • Current baseline: 0.1.0 (snapshot of Redox at build-system commit f55acba68)
  • All recipe sources are pinned with rev = "..." in recipe.toml
  • Archives are stored in sources/redbear-0.1.0/ with a manifest and BLAKE3 checksums
  • Builds are offline by defaultREPO_OFFLINE=1 COOKBOOK_OFFLINE=true
  • New releases are provisioned explicitly via provision-release.sh, never automatically
  • Old releases are NEVER deleted — each new release is added alongside existing ones

Checking for new Redox snapshots:

./local/scripts/check-upstream-releases.sh    # Read-only, zero side effects

Provisioning a new release:

./local/scripts/provision-release.sh --ref=<redox-tag> --release=0.2.0 [--dry-run]

Restoring sources from archives:

./local/scripts/restore-sources.sh --release=0.1.0

SOURCE-OF-TRUTH RULE (VERY IMPORTANT)

Treat the repository as two different layers with different durability guarantees:

1. Source archive layer — immutable per release

These paths are expected to be replaced, refetched, or regenerated when upstream changes:

  • recipes/*/source/
  • most of recipes/ outside our symlinked local/recipes/* release fork
  • config/desktop.toml, config/minimal.toml, and other mainline configs
  • generated build outputs under target/, build/, repo/, and recipe-local target/*

For relibc specifically, recipes/core/relibc/source/ is upstream-owned working source, not Red Bears durable storage location. We may build and validate there, but we must not rely on that tree alone to preserve Red Bear work.

2. Red Bear-owned layer — durable, must survive release provisioning

These paths are our actual long-term source of truth:

  • local/patches/ — all durable changes to upstream-owned source trees
  • local/recipes/ — Red Bear recipe release fork and new packages
  • local/docs/ — Red Bear planning, validation, and integration documentation
  • tracked Red Bear configs such as config/redbear-*.toml

If we can fetch fresh upstream sources tomorrow, provision sources from sources/redbear-<release>/, verify local/recipes/*, and rebuild successfully, then the work is in the right place.

If a change exists only inside an upstream-owned recipes/*/source/ tree, then it is not yet preserved, even if the current build happens to pass.

GOLDEN RULE — Red Bear adapts to upstream, never the reverse

When upstream Redox changes a dependency version, API, or ABI, Red Bear adapts. Red Bear NEVER pins, downgrades, or holds back an upstream package to avoid adaptation work. If libredox moves to redox_syscall 0.8, every Red Bear crate that touches redox_syscall moves to 0.8 — we fix our code, not theirs.

This applies to:

  • Crate dependency version bumps (redox_syscall, libredox, redox-scheme, etc.)
  • API changes in upstream crates (module reorganization, renamed types, trait changes)
  • ABI changes in relibc, kernel, or syscall layer
  • Any upstream evolution that requires Red Bear source changes

The only acceptable response to an upstream version bump is: update, adapt, commit.

In-house crate versioning

All Red Bear original crates under local/recipes/*/source/ MUST use the current Red Bear OS version, derived from the git branch name (e.g. 0.2.4 on branch 0.2.4). This applies to all version = "..." fields in [package] and [workspace.package] sections.

Exclusions (these keep their own versioning):

  • local/recipes/libs/zbus/ — upstream zbus fork (keeps 5.14.0)
  • local/recipes/tui/tlc/ — established project (keeps 1.0.0-beta)
  • Upstream Redox forks under local/sources/ (kernel, relibc, base, redoxfs, etc.)

When creating a new branch:

./local/scripts/sync-versions.sh          # Apply version to all in-house crates
./local/scripts/sync-versions.sh --check  # Verify compliance (exit 1 on drift)

The --check mode is suitable for CI gates and preflight checks.

Upstream-first rule for fast-moving components

Some components, especially relibc, are actively evolving upstream. For those areas, Red Bear must prefer the upstream solution whenever upstream already solves the same problem.

That means:

  • if our local patch solves a gap that upstream still has, keep the patch carrier
  • if upstream lands an equivalent or better solution, prefer upstream and shrink or drop our local patch
  • do not keep a Red Bear patch just because it existed first; keep it only while it still provides unique value

For relibc specifically, patch carriers should be treated as temporary compatibility release fork, not a permanent fork strategy.

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.

Daily-upstream-safe workflow

For any change to upstream-owned source:

  1. make the minimal working change in the live source tree if needed for validation
  2. prove it builds/tests against the real recipe
  3. mirror that delta into local/patches/<component>/...
  4. update local/docs/... so the provisioning story is explicit
  5. assume the live upstream source tree may be thrown away and recreated at any time

The success criterion is therefore:

We can sources are provisioned via provision-release.sh and archived in sources/redbear-/ build the project successfully.

Local recipe priority vs upstream WIP

When Red Bear maintains a local recipe and upstream contains a package with the same name under recipes/wip/*, Red Bear must prefer the local recipe unconditionally.

  • Use the local release fork symlink in recipes/*/<name> -> ../../local/recipes/...
  • Do not switch back to upstream WIP for active Red Bear builds
  • Re-evaluate only when upstream package exits WIP and becomes a normal maintained package

LOCAL RECIPE SOURCE IMMUTABILITY

local/recipes/<name>/source/ is unconditionally immutable as of cb8b093564 (2026-06-18).

Why

Internal Red Bear subprojects (tlc, redbear-*, redbear-greeter, cub, redbear-sessiond, etc.) live under local/recipes/*/source/. They have no upstream apart from our gitea — they are committed to https://gitea.redbearos.org/vasilito/redbear-os.git and nowhere else.

If a local/recipes/*/source/ is destroyed, it cannot be recovered from any public source.

The guarantee

The cookbook's is_local_overlay() check (in src/bin/repo.rs and src/cook/fetch.rs) returns true for any path matching /local/recipes/. The destructive paths in the build system (unfetch, git reset --hard, git clean -ffdx, source-wipe) all check this guard and refuse to operate on local overlays unconditionally. No env var, no flag, no Makefile target can override this.

REDBEAR_ALLOW_LOCAL_UNFETCH=1 was previously a kill switch for this guard. It was removed in cb8b093564 and is now dead code (its caller returns false).

make distclean-nuclear previously bypassed the guard. It is now a no-op for local recipes and behaves identically to make distclean.

What this means for operators

  • make distclean is safe for local recipes (only upstream recipes are removed).
  • make c.<recipe> only removes target/, never source/. Always safe.
  • make u.<recipe> (unfetch) refuses any local recipe.
  • repo unfetch <local-recipe> refuses with a clear error message.
  • make distclean-nuclear is now a synonym for make distclean (the dangerous variant was removed).

Recovery

If a local/recipes/*/source/ is destroyed despite these guards, recovery is only possible from:

  • git history (if the source was tracked in the fork's local git repo)
  • another operator's working copy
  • a backup tarball (if one was taken)

There is no automated recovery path. This is intentional.

LOCAL FORK MODEL (CORE COMPONENTS)

As of 2026-06, the following core components are built from local forks in local/sources/<component>/ rather than from upstream + overlay patches:

Component Local fork path Recipe
relibc local/sources/relibc/ recipes/core/relibc/recipe.toml (git URL)
kernel local/sources/kernel/ recipes/core/kernel/recipe.toml (git URL)
bootloader local/sources/bootloader/ recipes/core/bootloader/recipe.toml
installer local/sources/installer/ recipes/core/installer/recipe.toml (+ Cargo.toml dep)
redoxfs local/sources/redoxfs/ recipes/core/redoxfs/recipe.toml
userutils local/sources/userutils/ recipes/core/userutils/recipe.toml
base local/sources/base/ (path source) **recipes/core/base/recipe.toml (path = ...) **

Why local forks for these components?

  1. Critical bug fixes — these components had multiple broken patches that drifted from upstream and accumulated alignment issues.
  2. Faster build iteration — no need to fetch and apply dozens of patches on every build.
  3. Atomic changes — a single commit captures a logical change set, not a fragmented series of patches.
  4. Local recipes are already in fork formlocal/recipes/ was already a fork pattern; extending this to local/sources/ is consistent.
  5. Installer fork adds package groups — the installer fork (local/sources/installer/) implements config-level [package_groups.<name>] sections with recursive group resolution and cycle detection. This is Red Bear-specific functionality not in upstream. The cookbook's Cargo.toml points to the local fork via path = "local/sources/installer".

Overlay patches are still permitted

Overlay patches are still allowed for:

  • Importing new upstream commits into the local fork (apply upstream as a patch on the fork, then commit to the fork).
  • Smaller or experimental changes that don't justify a full fork commit.
  • New drivers or subsystems that don't need to track upstream at all.

When in doubt: if the change is likely to interact with upstream in the future, use a patch. If the change is self-contained and Red Bear-specific, prefer a fork commit.

Importing upstream commits into a local fork

# Example: import upstream relibc into local/sources/relibc
cd local/sources/relibc
git remote add upstream https://gitlab.redox-os.org/redox-os/relibc.git
git fetch upstream
# Cherry-pick or merge:
git cherry-pick <commit>
# Or merge a branch:
git merge upstream/master --no-ff
# Resolve conflicts, then commit
git push <redbear-remote> <branch>

The local fork's Cargo.toml may contain hardcoded absolute paths (/home/kellito/Builds/RedBear-OS/...) from a previous build environment. When creating or importing a local fork, make all path = "..." references RELATIVE to the fork's own location. The build system copies the fork to recipes/<component>/source/ before building, so absolute paths break.

Recommended pattern: path = "../../../local/recipes/<recipe>" or path = "../../sources/<sibling-fork>/<sub-dir>".

Build mode requirements for local forks

Building a local fork requires the cookbook to fetch the source. In development mode this works automatically, but the build system defaults to REPO_OFFLINE=1 which prevents fetching.

For development builds, use:

# Either set the env var
unset REDBEAR_RELEASE  # CRITICAL: do not set this in dev
export REDBEAR_ALLOW_PROTECTED_FETCH=1  # needed for base, kernel, relibc
./local/scripts/build-redbear.sh --upstream redbear-mini

# Or use the --upstream flag (recommended)
./local/scripts/build-redbear.sh --upstream redbear-mini

The .config file MUST NOT contain REDBEAR_RELEASE=... in development mode (otherwise the build system re-extracts sources from the immutable release archive and ignores the local fork).

# Automated sync (preferred):
./local/scripts/check-upstream-releases.sh              # Check for new Redox snapshots (read-only)
./local/scripts/provision-release.sh --ref=<tag> --release=0.2.0 --dry-run   # Preview new release
make all CONFIG_NAME=redbear-full             # Rebuild OS

Prefix Rebuild After Fork Changes

When a local fork (relibc, kernel, base) gains new functions, types, or headers, the prefix toolchain must be rebuilt to include them in the compiled libc.a and generated system headers:

touch relibc && make prefix        # After relibc changes (new functions, cbindgen.toml edits)
touch kernel && make prefix        # After kernel changes

The prefix provides the cross-compiler sysroot used by ALL recipe builds. A stale prefix causes "undefined reference" link errors when recipe code references functions that exist in the fork source but not in the compiled prefix library.

build-redbear.sh automatically rebuilds the prefix when it detects that fork repos (relibc, kernel, base) have commits newer than the prefix libc.a. This happens before any recipe build begins. If the prefix rebuild fails, the build aborts immediately — recipes are never compiled against a stale prefix.

Historical example: relibc commit 047e7c0 added __freadahead() to ext.rs, but the prefix libc.a was built before that commit. m4's gnulib expected __freadahead to exist (via ac_cv_func___freadahead=yes), causing undefined reference to '__freadahead' at link time. Fix: touch relibc && make prefix.

relibc Generated Header Fixes

Two circular include chains in relibc's cbindgen-generated headers were fixed to enable gnulib-based packages (m4, bison, flex) to compile:

wchar.h (commit d28963d): sys_includes reduced to ["features.h"]. Type definitions (wchar_t, wint_t, mbstate_t) moved to after_includes before #include <stdio.h>. mbstate_t defined with _RELIBC_MBSTATE_T guard and excluded from cbindgen export.

inttypes.h (commit a2e4cd2): Changed sys_includes from ["wchar.h"] to ["stdint.h", "stddef.h"] per POSIX spec. This breaks the circular chain: wchar.h → stdint.h → gnulib inttypes.h → inttypes.h → wchar.h.

See local/docs/PACKAGE-BUILD-QUIRKS.md § relibc Quirk 3 for full details.

STRUCTURE

redox-master/                  ← git pull updates mainline Redox
├── config/
│   ├── desktop.toml           ← mainline configs (untouched)
│   ├── minimal.toml
│   ├── redbear-full.toml      ← Desktop/graphics target
│   ├── redbear-mini.toml      ← Text-only console/recovery target
│   ├── redbear-grub.toml      ← Text-only with GRUB boot manager
│   ├── redbear-grub-policy.toml ← GRUB policy fragment (bootloader = "grub", efi_partition_size = 16)
│   └── redbear-greeter-services.toml ← Greeter/auth/session-launch wiring fragment
├── recipes/                   ← mainline package recipes (untouched)
├── mk/                        ← mainline build system (untouched)
├── local/                     ← RED BEAR OS custom work
│   ├── AGENTS.md              ← This file
│   ├── config/                ← Legacy configs (my-*, gitignored)
│   ├── recipes/
│   │   ├── core/              ← ext4d (ext4 filesystem scheme daemon + mkfs tool), grub (GRUB 2.12 UEFI bootloader)
│   │   ├── branding/          ← redbear-release (os-release, hostname, motd)
│   │   ├── drivers/           ← redox-driver-sys, linux-kpi (DRM/GPU + Wi-Fi only — NOT USB — NOT input subsystem)
│   │   ├── gpu/               ← redox-drm (AMD + Intel display drivers), amdgpu (C port)
│   │   ├── system/            ← cub, evdevd, udev-shim, redbear-firmware, firmware-loader, redbear-hwutils, redbear-info, redbear-netctl, redbear-quirks, redbear-meta
│   │   │   ├── redbear-sessiond       ← org.freedesktop.login1 D-Bus session broker (zbus-based Rust daemon)
│   │   │   ├── redbear-authd          ← local-user authentication daemon (`/etc/passwd` + `/etc/shadow` + `/etc/group`)
│   │   │   ├── redbear-session-launch ← session bootstrap helper (uid/gid/env/runtime-dir handoff)
│   │   │   ├── redbear-greeter        ← greeter orchestrator package (`redbear-greeterd`, UI, compositor wrapper, staged assets)
│   │   │   ├── redbear-dbus-services  ← D-Bus .service activation files + XML policies
│   │   ├── wayland/           ← Wayland compositor (Phase 2)
│   │   └── kde/               ← KDE Plasma (Phases 34)
│   ├── patches/
│   │   ├── kernel/            ← Kernel patches (ACPI, x2APIC)
│   │   ├── base/              ← Base patches (acpid fixes, power methods, pcid /config endpoint)
│   │   ├── relibc/            ← relibc compatibility release fork still needed beyond upstream (eventfd, signalfd, timerfd, waitid, SysV IPC)
│   │   ├── bootloader/        ← Bootloader patches
│   │   └── installer/         ← Installer patches (ext4 filesystem support + GRUB bootloader)
│   ├── Assets/                ← Branding assets (icon, loading background)
│   │   └── images/            ← Red Bear OS icon (1254x1254) + loading bg (1536x1024)
│   ├── firmware/              ← GPU firmware blobs (gitignored, fetched)
│   ├── scripts/
│   │   ├── provision-release.sh   ← Provision new release from Redox ref
│   │   ├── build-redbear.sh   ← Unified Red Bear OS build script
│   │   ├── fetch-firmware.sh  ← Download bounded AMD or Intel firmware subsets from linux-firmware
│   │   ├── test-drm-display-runtime.sh ← Shared bounded DRM/KMS display validation harness
│   │   ├── test-amd-gpu.sh    ← AMD wrapper for the DRM display validation harness
│   │   ├── test-intel-gpu.sh  ← Intel wrapper for the DRM display validation harness
│   │   ├── test-baremetal.sh  ← Bare metal test script
│   │   ├── build-redbear-wifictl-redox.sh ← Build redbear-wifictl for the Redox target with the repo toolchain
│   │   ├── test-iwlwifi-driver-runtime.sh ← Bounded Intel driver lifecycle check inside a target runtime
│   │   ├── test-wifi-control-runtime.sh ← Bounded Wi-Fi control/profile runtime check inside a target runtime
│   │   ├── test-wifi-baremetal-runtime.sh ← Strongest in-repo Wi-Fi runtime check on a real Red Bear target
│   │   ├── validate-wifi-vfio-host.sh ← Host-side VFIO passthrough readiness check for Intel Wi-Fi validation
│   │   ├── prepare-wifi-vfio.sh ← Bind/unbind Intel Wi-Fi PCI function for VFIO validation
│   │   ├── test-wifi-passthrough-qemu.sh ← QEMU/VFIO Wi-Fi validation harness with in-guest checks
│   │   ├── run-wifi-passthrough-validation.sh ← One-shot host wrapper for the full Wi-Fi passthrough validation flow
│   │   ├── package-wifi-validation-artifacts.sh ← Package Wi-Fi validation artifacts into one host-side tarball
│   │   ├── summarize-wifi-validation-artifacts.sh ← Summarize captured Wi-Fi validation artifacts for quick triage
│   │   ├── finalize-wifi-validation-run.sh ← Analyze a Wi-Fi capture bundle and package the final evidence set
│   │   ├── validate-vm-network-baseline.sh ← Static repo-level VM networking baseline check
│   │   ├── test-vm-network-qemu.sh ← QEMU launcher for the VirtIO VM networking baseline
│   │   ├── test-vm-network-runtime.sh ← In-guest runtime check for the VM networking baseline
│   │   ├── test-ps2-qemu.sh ← QEMU launcher for the bounded PS/2 + serio runtime proof
│   │   ├── test-timer-qemu.sh ← QEMU launcher for the bounded monotonic timer runtime proof
│   │   ├── test-lowlevel-controllers-qemu.sh ← Sequential wrapper for bounded low-level controller proofs
│   │   ├── test-usb-maturity-qemu.sh ← Sequential wrapper for bounded USB maturity proofs
│   │   └── test-greeter-qemu.sh ← Bounded QEMU proof for the Red Bear greeter/auth/session surface
│   └── docs/                  ← Integration docs

HOW TO BUILD RED BEAR OS

# CANONICAL build command — produces a live ISO for bare metal
./local/scripts/build-redbear.sh redbear-full     # Desktop/graphics target
./local/scripts/build-redbear.sh redbear-mini     # Text-only console/recovery target
./local/scripts/build-redbear.sh redbear-grub     # Text-only with GRUB boot manager

# Options:
#   --upstream          Allow online recipe source fetch (fast iteration with local forks)
#   --no-cache          Force clean rebuild, discarding cached packages
# Output: build/<arch>/<config>.iso

# VM-network baseline validation helpers
./local/scripts/validate-vm-network-baseline.sh
./local/scripts/test-vm-network-qemu.sh redbear-mini
# Then run inside the guest:
#   ./local/scripts/test-vm-network-runtime.sh

# Phase 1 runtime-substrate validation (canonical plan: CONSOLE-TO-KDE v4.0)
# firmware-loader, DRM/KMS, time — covers acceptance areas + POSIX compat)
./local/scripts/test-phase1-runtime.sh --qemu redbear-full

# Legacy Phase 1 desktop-substrate validation (still works)
./local/scripts/test-phase1-desktop-substrate.sh --qemu redbear-full

# Phase 1 POSIX compatibility tests (inside guest)
# Run inside the guest after boot:
#   cd /home/user/relibc-phase1-tests && ./test_signalfd_wayland && ./test_timerfd_qt6 && ...
# Or use the test harness:
./local/scripts/test-phase1-runtime.sh --guest

# Legacy Phase 3 runtime-substrate validation (historical P0-P6 numbering; script still works)
./local/scripts/test-phase3-runtime-substrate.sh --qemu redbear-full

# Low-level controller validation
./local/scripts/test-xhci-irq-qemu.sh --check
./local/scripts/test-msix-qemu.sh
./local/scripts/test-iommu-qemu.sh
./local/scripts/test-ps2-qemu.sh --check
./local/scripts/test-timer-qemu.sh --check
./local/scripts/test-lowlevel-controllers-qemu.sh
./local/scripts/test-usb-storage-qemu.sh
./local/scripts/test-usb-qemu.sh --check
./local/scripts/test-usb-maturity-qemu.sh

# The current xHCI proof checks for an interrupt-driven mode in boot logs.
# The current MSI-X proof uses the live virtio-net path in QEMU.
# The current IOMMU proof runs a guest-driven first-use self-test and checks that discovered
# AMD-Vi units initialize and drain events successfully in QEMU.
# The current PS/2 proof checks serio node visibility and then hands off to the existing Phase 3
# input-path checker inside the guest.
# The current timer proof checks that /scheme/time/CLOCK_MONOTONIC advances across two guest reads.
# The aggregate low-level wrapper runs xHCI, IOMMU, PS/2, and timer proofs in sequence.
# The USB storage proof now verifies usbscsid autospawn plus bounded sector-0 readback against a
# host-seeded pattern, while guest-side write verification is still open.
# The aggregate USB wrapper runs xHCI mode, full USB stack, and USB storage readback proofs in sequence.

# Legacy Phase 4 Wayland runtime validation (historical P0-P6 numbering; script still works)
./local/scripts/build-redbear.sh redbear-full
./local/scripts/test-phase4-wayland-qemu.sh
# Then run inside the guest:
#   redbear-phase4-wayland-check

# Legacy Phase 5 desktop/network plumbing validation (historical P0-P6 numbering; script still works)
./local/scripts/build-redbear.sh redbear-full
./local/scripts/test-phase5-network-qemu.sh --check
# Then run inside the guest:
#   redbear-phase5-network-check

# Experimental Red Bear greeter/login validation
./local/scripts/build-redbear.sh redbear-full
./local/scripts/test-greeter-qemu.sh --check
# Then run inside the guest:
#   redbear-greeter-check
#   redbear-greeter-check --invalid root wrong

# Bounded Intel Wi-Fi runtime validation (real target or passthrough guest)
# Host preparation for VFIO-backed guests:
#   sudo ./local/scripts/validate-wifi-vfio-host.sh --host-pci 0000:xx:yy.z --expect-driver iwlwifi
#   sudo ./local/scripts/prepare-wifi-vfio.sh bind 0000:xx:yy.z
# Guest/target packaged checks:
#   redbear-phase5-wifi-check
#   redbear-phase5-wifi-link-check
#   redbear-phase5-wifi-run wifi-open-bounded wlan0 /tmp/redbear-phase5-wifi-capture.json
#   redbear-phase5-wifi-capture wifi-open-bounded wlan0 /tmp/redbear-phase5-wifi-capture.json
#   redbear-phase5-wifi-analyze /tmp/redbear-phase5-wifi-capture.json
# Helper scripts:
#   ./local/scripts/test-wifi-baremetal-runtime.sh
#   ./local/scripts/test-wifi-passthrough-qemu.sh --host-pci 0000:xx:yy.z --check --capture-output ./wifi-passthrough-capture.json
#   ./local/scripts/finalize-wifi-validation-run.sh ./wifi-passthrough-capture.json ./wifi-passthrough-artifacts.tar.gz

# Legacy Phase 6 KDE session-surface validation (historical P0-P6 numbering; script still works)
./local/scripts/build-redbear.sh redbear-full
./local/scripts/test-phase6-kde-qemu.sh --check
# Then run inside the guest:
#   redbear-phase6-kde-check

# redbear-netctl user-facing alias
redbear-netctl --help

# Single custom recipe:
./target/release/repo cook local/recipes/branding/redbear-release
./target/release/repo cook local/recipes/system/redbear-meta
./target/release/repo cook local/recipes/core/ext4d
./target/release/repo cook local/recipes/core/grub  # GRUB bootloader (host build, produces EFI binary)

# GRUB boot manager (installer-native):
make r.grub                                                   # Build GRUB recipe
./local/scripts/build-redbear.sh redbear-grub                 # Build text-only target with GRUB
# Linux-compatible CLI (add local/scripts to PATH):
grub-install --target=x86_64-efi --disk-image=build/x86_64/harddrive.img
grub-mkconfig -o local/recipes/core/grub/grub.cfg
# Or legacy post-build script:
./local/scripts/install-grub.sh build/x86_64/harddrive.img    # Modify existing image

TRACKING MAINLINE CHANGES

When mainline updates affect our work:

Component What to check Where
Kernel ACPI, scheme, memory API changes recipes/core/kernel/source/src/
relibc New POSIX functions added upstream recipes/core/relibc/source/src/header/
Base drivers Driver API changes recipes/core/base/source/drivers/
libdrm DRM API updates recipes/libs/libdrm/ or the current in-tree libdrm location
Mesa OpenGL/Vulkan backend changes recipes/libs/mesa/
Build system Makefile/config changes mk/, src/
rsext4 ext4 crate API changes local/recipes/core/ext4d/source/ Cargo.toml
Installer ext4 dispatch, filesystem selection, GRUB bootloader local/patches/installer/redox.patch
Quirks New Linux quirk entries to port local/recipes/drivers/redox-driver-sys/source/src/quirks/

PLANNING NOTES

  • docs/07-RED-BEAR-OS-IMPLEMENTATION-PLAN.md is the canonical public execution plan.
  • local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md (v4.0) is the canonical comprehensive plan — supersedes all individual subsystem docs. See it for current state, blockers, and roadmap.
  • local/docs/WAYLAND-IMPLEMENTATION-PLAN.md is the canonical Wayland subsystem plan beneath the desktop path. Use it for Wayland-specific stability, completeness, ownership, and runtime-proof sequencing.
  • local/docs/DRM-MODERNIZATION-EXECUTION-PLAN.md is the current DRM-focused execution plan beneath the canonical desktop path. It keeps Intel and AMD at the same evidence bar while separating display/KMS maturity from render/3D maturity.
  • Older GPU-specific docs such as local/docs/AMD-FIRST-INTEGRATION.md, local/docs/HARDWARE-3D-ASSESSMENT.md, and local/docs/DMA-BUF-IMPROVEMENT-PLAN.md remain useful reference material, but they are not the planning authority when sequencing or acceptance criteria differ.
  • local/docs/AMD-FIRST-INTEGRATION.md remains the deeper AMD-specific technical roadmap, but AMD and Intel machines are now equal-priority Red Bear OS targets.
  • The earlier Phase 03 reassessment bridge has been retired. Its reconciliation role is now covered by local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md, local/docs/DESKTOP-STACK-CURRENT-STATUS.md, and docs/07-RED-BEAR-OS-IMPLEMENTATION-PLAN.md.
  • local/docs/WIFI-IMPLEMENTATION-PLAN.md is the current Wi-Fi architecture and rollout plan, including the bounded role of linux-kpi and the native wireless control-plane direction.
  • local/docs/USB-IMPLEMENTATION-PLAN.md and local/docs/BLUETOOTH-IMPLEMENTATION-PLAN.md should also be treated as first-class subsystem plans, not as side notes.
  • local/docs/IRQ-AND-LOWLEVEL-CONTROLLERS-ENHANCEMENT-PLAN.md is the current umbrella plan for IRQ delivery, MSI/MSI-X quality, IOMMU validation, and other low-level controller completeness work.
  • local/docs/QUIRKS-SYSTEM.md documents the hardware quirks infrastructure: compiled-in tables, TOML runtime files, DMI matching, driver integration, and the linux-kpi C FFI bridge.
  • local/docs/QUIRKS-IMPROVEMENT-PLAN.md is the current follow-up plan for removing quirks drift, integrating quirks into real drivers, and converging on one source of truth.
  • local/docs/DBUS-INTEGRATION-PLAN.md is the canonical D-Bus architecture and implementation plan for KDE Plasma 6 on Wayland. It defines the phased approach to D-Bus service integration, the redbear-sessiond login1-compatible session broker, and the gap analysis for desktop-facing D-Bus services.
  • local/docs/GREETER-LOGIN-IMPLEMENTATION-PLAN.md is the canonical Red Bear-native greeter/login design and current implementation plan for the redbear-full desktop path. It defines the redbear-authd / redbear-session-launch / redbear-greeter split, service wiring, validation surface, and the current boundary between the active greeter path and the older redbear-validation-session helper flows.

The current execution order for these subsystem plans is:

  1. IRQ / low-level controller quality
  2. USB maturity
  3. Wi-Fi native control plane and first driver family
  4. Bluetooth controller + host path
  5. desktop/session compatibility on top of those runtime services

Do not present USB, Wi-Fi, Bluetooth, or low-level controller work as optional or secondary.

LINUX KERNEL SOURCE POLICY (CRITICAL)

Linux kernel source is REFERENCE ONLY — never a dependency.

If Red Bear OS needs something from the Linux kernel, it MUST be implemented in the project tree, using Linux source as reference only.

Policy (VERBATIM)

"If we need something from Linux kernel, it MUST be implemented in our tree, having Linux source as reference only" "If we need linux-input-headers than we must code redbear-input-headers"

linux-kpi Scope

local/recipes/drivers/linux-kpi/ covers ONLY:

  • DRM/GPU headers (drm/) — AMD + Intel display drivers
  • Wi-Fi headers (net/) — mac80211, cfg80211, nl80211
  • General kernel headers (linux/) — mm, device, irq, dma-mapping, firmware, etc.

Does NOT cover: USB, input subsystem, or any other Linux kernel subsystem.

Implementing New Linux-Compatibility Headers

When Red Bear needs Linux kernel headers for a new subsystem:

  1. Create local/recipes/drivers/redbear-<subsystem>-headers/
  2. Implement headers using Linux source as reference only
  3. Do NOT pull Linux source tarballs directly
  4. Do NOT use third-party tarballs that bundle Linux headers as a proxy
  5. Examples:
    • redbear-input-headers/ → linux/input.h, input-event-codes.h, uinput.h
    • redbear-usb-headers/ → linux/usb/ch9.h, etc. (NOT linux-kpi's purpose)

linux-input-headers — Policy Violation

recipes/wip/libs/linux-input-headers/ extracts Linux kernel input headers from the libevdev tarball. This is a policy violation — it pulls Linux headers via a third-party tarball. The correct implementation is redbear-input-headers in local/recipes/drivers/.

FILESYSTEMS

Red Bear OS supports three filesystems:

Filesystem Implementation Package Status
RedoxFS Mainline Redox (default) recipes/core/redoxfs Stable
ext4 rsext4 0.3 crate + ext4d scheme daemon local/recipes/core/ext4d Compiles + Installer wired
FAT (VFAT) fatfs 0.3.6 crate + fatd scheme daemon local/recipes/core/fatd Compiles + Tools tested + label write verified

ext4 Workspace (local/recipes/core/ext4d/source/)

ext4d/source/
├── Cargo.toml              ← Workspace: ext4-blockdev, ext4d, ext4-mkfs
├── ext4-blockdev/           ← BlockDevice trait impls for rsext4
│   ├── Cargo.toml           ← Features: default=["redox"], redox=[libredox,syscall]
│   └── src/
│       ├── lib.rs           ← Re-exports: FileDisk, RedoxDisk, Ext4Error, Ext4Result
│       ├── file_disk.rs     ← FileDisk: std::fs backed, builds on host Linux + Redox
│       └── redox_disk.rs    ← RedoxDisk: syscall/libredox backed, Redox-only (feature-gated)
├── ext4d/                   ← ext4 filesystem scheme daemon (Redox userspace)
│   ├── Cargo.toml           ← Features: default=["redox"], redox deps
│   └── src/
│       ├── main.rs          ← Daemon: fork, SIGTERM, scheme registration
│       ├── mount.rs         ← Scheme event loop (redox_scheme::SchemeSync)
│       ├── scheme.rs        ← Full ext4 FSScheme: open, read, write, mkdir, unlink, stat...
│       └── handle.rs        ← FileHandle, DirectoryHandle, Handle types
└── ext4-mkfs/               ← ext4 mkfs tool (host-side utility)
    ├── Cargo.toml
    └── src/main.rs          ← Creates ext4 images via FileDisk + rsext4::mkfs

Architecture:

  • ext4d is a Redox scheme daemon — it serves ext4 filesystems via scheme:ext4d
  • Uses rsext4 crate (pure Rust ext4 implementation) for all filesystem operations
  • FileDisk allows building/testing on the Linux host machine
  • RedoxDisk uses libredox + redox_syscall for actual Redox bare-metal I/O
  • Both impls are behind the redox feature flag — --no-default-features gives Linux-only

Recipe: Symlinked into mainline search path:

recipes/core/ext4d → local/recipes/core/ext4d

Config: ext4d is included in config/desktop.toml (mainline), which redbear-full.toml inherits.

Dependencies (from workspace Cargo.toml):

  • rsext4 = "0.3" — Pure Rust ext4 filesystem implementation
  • redox_syscall = "0.7.3" — Redox syscall wrappers (scheme, data types, flags)
  • redox-scheme = "0.11.0" — Scheme server framework
  • libredox = "0.1.13" — High-level Redox syscalls (open, read, write, fstat)
  • redox-path = "0.3.0" — Redox path utilities

Installer ext4 + GRUB Integration (local/patches/installer/redox.patch)

The mainline installer is patched to support ext4 as an install target filesystem and GRUB as an alternative boot manager:

  • GeneralConfig.filesystem: Option<String> — TOML field, accepts "redoxfs" (default) or "ext4"
  • GeneralConfig.bootloader: Option<String> — TOML field, accepts "redox" (default) or "grub"
  • FilesystemType enum — dispatch tag used by install_inner
  • with_whole_disk_ext4() — GPT partition layout + ext4 mkfs + file sync (mirrors with_whole_disk)
  • Ext4SliceDisk<T> — adapts DiskWrapper to rsext4's BlockDevice trait
  • sync_host_dir_to_ext4() — copies staged sysroot files into ext4 filesystem
  • GRUB chainload: when bootloader = "grub", writes GRUB EFI + grub.cfg to ESP alongside Redox bootloader
  • CLI flags: --filesystem ext4 / --bootloader grub

Usage in config TOML:

[general]
filesystem = "ext4"        # "redoxfs" is default
bootloader = "grub"        # "redox" is default
efi_partition_size = 16    # Required for GRUB (default 1 MiB is too small)
filesystem_size = 10240    # MB

See local/docs/GRUB-INTEGRATION-PLAN.md for the full GRUB architecture and usage guide.

FAT (VFAT) Workspace (local/recipes/core/fatd/source/)

fatd/source/
├── Cargo.toml              ← Workspace: fat-blockdev, fatd, fat-mkfs, fat-label, fat-check
├── fat-blockdev/            ← Block device adapter for fatfs crate
│   ├── src/lib.rs           ← Re-exports: FileDisk (always), RedoxDisk (feature-gated)
│   ├── src/file_disk.rs     ← FileDisk: std::fs::File → Read+Write+Seek
│   └── src/redox_disk.rs    ← RedoxDisk: libredox → Read+Write+Seek (redox feature)
├── fatd/                    ← FAT filesystem scheme daemon (Redox userspace)
│   ├── src/main.rs          ← Daemon: fork, SIGTERM, dispatch to FileDisk/RedoxDisk
│   ├── src/mount.rs         ← Scheme event loop (redox_scheme::SchemeSync)
│   ├── src/scheme.rs        ← FatScheme: full FSScheme (open/read/write/mkdir/unlink/stat...)
│   └── src/handle.rs        ← FileHandle, DirectoryHandle, Handle types
├── fat-mkfs/                ← mkfs.fat equivalent (create FAT12/16/32 filesystems)
│   └── src/main.rs
├── fat-label/               ← fatlabel equivalent (read + write volume labels via BPB)
│   └── src/main.rs          ← `-s "LABEL"` writes label at BPB offset 43/71; verifies round-trip
└── fat-check/               ← fsck.fat equivalent (verify BPB, FAT chains, directory tree + safe repair)
    └── src/main.rs          ← `--repair` clears dirty flag, fixes FSInfo, reclaims lost clusters

Architecture: fatd is a Redox scheme daemon using fatfs v0.3.6 (MIT, no_std capable). FAT is for data volumes and ESP only — NOT for root filesystem. fscommon::BufStream wraps block device for mandatory caching.

Recipe: Symlinked into mainline search path:

recipes/core/fatd → ../../local/recipes/core/fatd

Config: Packages included via config/redbear-device-services.toml (inherited by redbear-full.toml and redbear-mini.toml). Init service at /usr/lib/init.d/15_fatd.service.

Dependencies: fatfs 0.3.6, fscommon 0.1.1, redox_syscall, redox-scheme, libredox, libc

Tool verification status (2026-04-17):

  • fat-mkfs: Creates FAT12/16/32, labels, auto-detection, cluster size option (-c), tested up to 1GB
  • fat-label: Reads labels; writes BPB + creates/updates root-directory volume-label entry; verifies round-trip on all FAT types (including previously unlabeled volumes)
  • fat-check: BPB validation, boot signature check, directory tree walk, cluster stats; safe repair (dirty flag including FAT12, FSInfo, lost clusters, orphaned LFN). Handles 0xFFFFFFFF FSInfo sentinel on fresh images.
  • fatd: Compiles (links on Redox target only — expected). frename + rmdir non-empty check implemented. NOT runtime-tested (requires QEMU/bare metal).
  • Phase 4 (runtime auto-mount): Deferred to runtime validation. Static init service exists.
  • Known limitation: fatfs v0.3.6 strictly requires total_sectors_16 == 0 for FAT32, rejecting some Linux mkfs.fat images
  • cargo test: 60 unit tests (25 scheme + 7 label + 28 check) + 13+ integration edge cases

BRANDING ASSETS

Red Bear OS visual identity files live in local/Assets/.

local/Assets/
└── images/
    ├── Red Bear OS icon.png              ← App icon / logo (1254x1254px)
    │                                        Red bear head, dark background, red border
    │                                        Use: desktop icon, bootloader logo, about dialog
    └── Red Bear OS loading background.png ← Boot / loading screen (1536x1024px)
                                             Cinematic red bear with forest silhouette
                                             Use: bootloader splash, login screen background

Integration points (future):

Asset Target How
icon.png Bootloader logo Convert to BMP, embed via bootloader config
icon.png Desktop icon Install to /usr/share/icons/hicolor/ via redbear-release recipe
icon.png About dialog Install through the active icon/theme surface
loading background.png Boot splash Convert to framebuffer-compatible format, display during startup
loading background.png Login screen Set as the display-session background

Current status: Assets are committed to git. Not yet integrated into the build — requires bootloader and display server integration (P2 hardware validation).

BUILD SYSTEM SAFETY

The build system includes collision detection and validation to prevent the D-Bus regression class (config overrides silently overwritten by package staging).

Validation Targets

make lint-config                       # Check for /usr/lib/init.d/ in config [[files]]
make validate CONFIG_NAME=redbear-mini # Full validation: lint + init services + ownership

Init Service Path Convention

  • Packages own /usr/lib/init.d/ — default service files from recipe staging
  • Config overrides own /etc/init.d/ — override files from [[files]] entries
  • Config [[files]] MUST NOT use /usr/lib/init.d/ paths for init services
  • The init system's config_for_dirs() gives /etc/init.d/ priority via BTreeMap dedup

Collision Detection (installer)

The installer includes 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).

Recipe Installs Manifest

Recipes can declare installed paths via installs = [...] in [package] section. scripts/validate-file-ownership.sh checks for conflicts. No recipes declare installs yet.

Manifest Generation

scripts/generate-installs-manifest.sh base  # Output suggested installs for base package

See local/docs/BUILD-SYSTEM-HARDENING-PLAN.md for the full 5-phase hardening plan. See local/docs/BUILD-SYSTEM-INVARIANTS.md for invariants I1-I3.

ANTI-PATTERNS

  • DO NOT edit files under mainline recipes/ directly — put patches in local/patches/
  • DO NOT commit firmware blobs to git — use local/scripts/fetch-firmware.sh
  • DO NOT modify mk/ or src/ directly — extend via local/scripts/
  • DO NOT assume mainline recipe names won't conflict — prefix custom ones (e.g., redox-)
  • DO NOT use my-* naming for configs that should be tracked in git — use redbear-* instead
  • DO NOT edit config/base.toml directly — our configs include it and override via TOML merge
  • DO NOT attempt to immutable archived sources from upstream — sources are immutable; use provision-release.sh

COMPREHENSIVE IMPLEMENTATION POLICY

Red Bear OS has zero tolerance for shortcuts, workarounds, and stubs. Every package in the build must be a comprehensive, real implementation. No approximations.

The Rule

When a package fails to build due to missing functionality:

  1. DO NOT mark packages as "ignore" to skip them
  2. DO NOT create stub recipes that provide fake cmake configs without real functionality
  3. DO NOT disable required dependencies via sed/cmake hacks without implementing the dependency

Fix Before Disable

When a build blocker exposes a missing producer surface, missing dependency export, or incomplete integration boundary, the default policy is:

Always do your best to fix before disabling.

This means:

  • prefer restoring the real producer/package surface over commenting out the consumer
  • prefer fixing CMake/pkg-config/header visibility over disabling the dependent feature
  • treat disabling as a last resort, not the normal path

If disabling is temporarily unavoidable, it must be:

  • explicit,
  • narrowly scoped,
  • documented with the real blocker,
  • and treated as temporary debt to remove, not as the desired final state.

Instead, implement the missing functionality properly:

Missing Component Required Action
Missing POSIX function in relibc Implement it in recipes/core/relibc/source/ + create patch in local/patches/relibc/
Missing KF6 package Create full recipe in local/recipes/kde/ with proper cmake build
Disabled Qt feature (e.g., QtNetwork) Implement the feature properly in qtbase recipe
Missing system call Implement in kernel recipe + create patch in local/patches/kernel/

Why This Matters

  • Stubs and workarounds accumulate technical debt
  • They block real functionality from ever being implemented
  • They make the system unreliable and untestable
  • They hide the real work that needs to be done

Current Comprehensive Implementation Gaps

CREDENTIAL SYSCALLS — RESOLVED (2026-04-30): setgroups, getgroups, initgroups, setresuid, setresgid, getrlimit, setrlimit are now implemented. See local/docs/KERNEL-IPC-CREDENTIAL-PLAN.md for the full implementation detail.

Implementation: Kernel: Context.groups: Vec<u32>, CallerCtx.groups, Groups proc scheme handle at auth-{fd}-groups. Relibc: posix_setgroups()/posix_getgroups() in redox-rt, real setgroups()/getgroups() in platform layer, RLIMIT userspace stubs. Durable patches: local/patches/kernel/P4-supplementary-groups.patch, local/patches/relibc/P4-setgroups-getgroups.patch.

Gap Root Cause Status
setgroups ENOSYS on Redox Redox kernel had no supplementary group infrastructure RESOLVED
getgroups returns only egid Redox kernel had no group table concept RESOLVED
setuid/setgid/getuid/getgid No credential syscalls in kernel Already worked via posix_setresugid (proc scheme)
getrlimit/setrlimit ENOSYS RESOLVED — userspace stubs with defaults
CONFIG: KWin is a stub KWin recipe attempts real cmake build with QML/Quick disabled. Blocked by QML gate. Previously had wrapper stubs — removed 2026-04-30. RESOLVED: honest recipe, fails on QML gate
CONFIG: 36/48 KDE packages enabled 12 blocked by QML gate (kirigami → plasma-framework → plasma-workspace → plasma-desktop). See local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md for breakdown. BLOCKED: QML gate requires Qt6Quick/QML engineering
CONFIG: Plasma packages blocked plasma-framework, plasma-workspace, plasma-desktop depend on kirigami (QML gate). Documented in plan. BLOCKED: QML gate
CONFIG: Greeter service 20_greeter.service wired. Greeter QEMU proof passes (GREETER_HELLO=ok, GREETER_VALID=ok). RESOLVED
RUNTIME: Greeter UI Qt Wayland integration: redbear-compositor handles Wayland protocol. Qt6's Wayland plugin reports loading issues due to endianness in compositor wire format. DOCUMENTED in plan
RUNTIME: Greeter UI crash Qt Wayland integration fails (wl-shell deprecated, xdg-shell not working) Fix Qt platform plugin initialization for Wayland
RUNTIME: D-Bus user lookup root and messagebus users not found in passwd database → RESOLVED: user/group config exists in redbear-full.toml; runtime files generated in build Verify in QEMU runtime
RUNTIME: seatd missing seatd binary not in image despite being in config → RESOLVED: seatd builds and is in image Verify in QEMU runtime
RUNTIME: getrlimit(7) relibc getrlimit not implemented → RESOLVED: implemented in relibc patches Verify in QEMU runtime

Kernel Syscall Gap Analysis

The Redox kernel (recipes/core/kernel/source/src/syscall/mod.rs) match statement ends with:

_ => Err(Error::new(ENOSYS)),

All credential syscalls (SYS_SETGROUPS, SYS_GETGROUPS, SYS_SETUID, SYS_SETGID, etc.) fall through to this catch-all and return ENOSYS.

The syscall numbers come from redox_syscall crate (external, versioned) - not defined in the kernel tree.

Fixes Applied (2026-04-29)

  1. relibc/grp/cbindgen.toml: Added group functions to export list
  2. relibc/grp/mod.rs: Implemented getgroups() with egid fallback
  3. Patches created: local/patches/relibc/P3-grp-cbindgen-exports.patch, P3-getgroups-implementation.patch
  4. KERNEL GAP: Cannot fix without upstream redox_syscall + kernel changes

Implementation Locations

  • POSIX functions: recipes/core/relibc/source/src/header/<func>/ + local/patches/relibc/
  • New KF6 recipes: local/recipes/kde/kf6-<name>/
  • Kernel syscalls: recipes/core/kernel/source/ + local/patches/kernel/
  • Qt fixes: recipes/qt/qtbase/source/ + local/patches/qtbase/

RED BEAR OS CONFIG HIERARCHY

Active compile targets (all three work for both make all and make live):

  • redbear-full — Desktop/graphics-enabled target
  • redbear-mini — Text-only console/recovery target
  • redbear-grub — Text-only with GRUB boot manager

Desktop/graphics are available only on redbear-full.

redbear-full.toml
  └── redbear-mini.toml
        ├── minimal.toml (mainline)
        ├── redbear-legacy-base.toml
        └── redbear-netctl.toml
  └── [packages] firmware, GPU, Wayland, Qt6, KF6, KWin, greeter, fonts, icons
  └── [services] D-Bus, seatd, greeter, console
  └── [users] messagebus, greeter
  NOTE: ext4d is inherited from desktop.toml (mainline package).
  NOTE: redbear-meta is explicitly included; keep broader inclusion deliberate.

redbear-mini.toml
  └── minimal.toml (mainline)
  └── redbear-legacy-base.toml
  └── redbear-netctl.toml
  └── [packages] pciids, redbear-hwutils, redbear-netctl, redbear-info, cub, etc.
  └── [services] pcid-spawner, netctl boot, console, debug console

redbear-grub.toml
  └── redbear-mini.toml
  └── redbear-grub-policy.toml (bootloader = "grub", efi_partition_size = 16)
  └── [packages] grub

Config comparison:

Config GPU Stack Desktop Branding ext4d GRUB filesystem_size
redbear-full Full Yes Yes No 4096 MiB
redbear-mini None None Yes No No 1536 MiB
redbear-grub None None Yes No Yes (from mini)

ANTI-PATTERNS (COMMIT POLICY)

  • DO NOT include AI attribution in commit messages — no "Ultraworked with [Sisyphus]", "Co-authored-by: Sisyphus", or similar AI agent footers. Commits belong to the human author only.