Adds .gitmodules entries for local/sources/{base,bootloader,installer,
libredox,redoxfs,relibc,syscall,userutils} — all pointing at
https://gitea.redbearos.org/vasilito/RedBear-OS.git with
branch = submodule/<name>. Previously only 'kernel' was declared.
After this commit, a fresh clone followed by
'git submodule update --init --recursive' resolves all 9 component
sources from the canonical RedBear-OS repo's submodule/<name>
branches.
Removes the dangling gitlinks for the 4 components whose per-component
Gitea repos were empty (0 commits): local/sources/ctrlc,
local/sources/libpciaccess, local/sources/redox-drm, local/sources/sysinfo.
These were cleaned because the upstream per-component repo had no source
content; if any of these components is revived in the future, declare
a new 'submodule/<name>' branch on RedBear-OS and re-add the .gitmodules
entry.
Updates local/AGENTS.md § Migration status to reflect the completed state.
68 KiB
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 (notmy-*, 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-cryptcrate, licensedMIT 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-OSrepo (submodule/<component>branches), OR - Tracked trees under
local/sources/<component>/— full source snapshots committed directly to theRedBear-OSrepo 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.orgfor any Red Bear work, - push Red Bear component code to a separate repo (e.g. a personal
scratch fork of
kernelorrelibc), - 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:
- Create or reuse a branch inside
RedBear-OSnamedsubmodule/<component>(e.g.submodule/relibc). - Push the component's source tree to that branch.
- Replace the recipe's
git = "..."URL with the in-repo submodule path, and add a[submodule]entry referencing the new branch. - Update
local/AGENTS.mdand 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-basemirror 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):
- Verify the per-component repo is a Red Bear component, not unrelated.
export REDBEAR_GITEA_TOKEN=...(or set up~/.netrc).- 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> - Declare it in
.gitmodules(copy an existing entry, change the name + branch). ./local/scripts/delete-per-component-repos.shto 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
vasilitoGitea 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_TOKENenv 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/configon 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 isredbear-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:
- Check
https://gitea.redbearos.org/in a browser. If down, halt all pushes. - 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. - If
local/sources/<component>/becomes desynced, recover from the correspondingsubmodule/<component>branch inside this sameRedBear-OSrepo (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:
- SSH/console into the Gitea host as an admin, or have an admin reset the user's password.
- Log in via web UI, generate a new personal access token under
Settings → Applications → Manage Access Tokens. - Push the new token into the team's secret store only. Do not commit it.
- 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:
make all CONFIG_NAME=redbear-full
→ mk/config.mk resolves to the active desktop/graphics compile target
→ Desktop/graphics are available only on redbear-full
→ repo cook builds all packages from local sources (offline by default)
→ mk/disk.mk creates harddrive.img with Red Bear branding
→ REDBEAR_RELEASE=0.1.0 ensures immutable, archived sources
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. All three work for both make all (harddrive.img)
and make live (ISO):
redbear-full— Desktop/graphics-enabled target (Wayland + KDE + GPU drivers)redbear-mini— Text-only console/recovery/install targetredbear-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 = "..."inrecipe.toml - Archives are stored in
sources/redbear-0.1.0/with a manifest and BLAKE3 checksums - Builds are offline by default —
REPO_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 symlinkedlocal/recipes/*release fork config/desktop.toml,config/minimal.toml, and other mainline configs- generated build outputs under
target/,build/,repo/, and recipe-localtarget/*
For relibc specifically, recipes/core/relibc/source/ is upstream-owned working source, not
Red Bear’s 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 treeslocal/recipes/— Red Bear recipe release fork and new packageslocal/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 (keeps5.14.0)local/recipes/tui/tlc/— established project (keeps1.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-syspath, - 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:
- make the minimal working change in the live source tree if needed for validation
- prove it builds/tests against the real recipe
- mirror that delta into
local/patches/<component>/... - update
local/docs/...so the provisioning story is explicit - 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 distcleanis safe for local recipes (only upstream recipes are removed).make c.<recipe>only removestarget/, neversource/. Always safe.make u.<recipe>(unfetch) refuses any local recipe.repo unfetch <local-recipe>refuses with a clear error message.make distclean-nuclearis now a synonym formake 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?
- Critical bug fixes — these components had multiple broken patches that drifted from upstream and accumulated alignment issues.
- Faster build iteration — no need to fetch and apply dozens of patches on every build.
- Atomic changes — a single commit captures a logical change set, not a fragmented series of patches.
- Local recipes are already in fork form —
local/recipes/was already a fork pattern; extending this tolocal/sources/is consistent. - 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'sCargo.tomlpoints to the local fork viapath = "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 includes a preflight check that warns when fork commits are newer than
prefix artifacts, but it does not auto-rebuild the prefix (which can take 10+ minutes).
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 3–4)
│ ├── 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
# Build targets (all three work for both `make all` and `make live`)
./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
# Or manually:
make all CONFIG_NAME=redbear-full # Desktop/graphics → harddrive.img
make all CONFIG_NAME=redbear-mini # Text-only → harddrive.img
make all CONFIG_NAME=redbear-grub # Text-only + GRUB → harddrive.img
# Live ISO (for real bare metal)
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
# Or using the helper:
scripts/build-iso.sh redbear-full # Full desktop live ISO
scripts/build-iso.sh redbear-mini # Text-only mini (default)
scripts/build-iso.sh redbear-grub # Text-only + GRUB
# 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
make all CONFIG_NAME=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.mdis 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.mdis 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.mdis 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, andlocal/docs/DMA-BUF-IMPROVEMENT-PLAN.mdremain useful reference material, but they are not the planning authority when sequencing or acceptance criteria differ. local/docs/AMD-FIRST-INTEGRATION.mdremains the deeper AMD-specific technical roadmap, but AMD and Intel machines are now equal-priority Red Bear OS targets.- The earlier Phase 0–3 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, anddocs/07-RED-BEAR-OS-IMPLEMENTATION-PLAN.md. local/docs/WIFI-IMPLEMENTATION-PLAN.mdis the current Wi-Fi architecture and rollout plan, including the bounded role oflinux-kpiand the native wireless control-plane direction.local/docs/USB-IMPLEMENTATION-PLAN.mdandlocal/docs/BLUETOOTH-IMPLEMENTATION-PLAN.mdshould also be treated as first-class subsystem plans, not as side notes.local/docs/IRQ-AND-LOWLEVEL-CONTROLLERS-ENHANCEMENT-PLAN.mdis the current umbrella plan for IRQ delivery, MSI/MSI-X quality, IOMMU validation, and other low-level controller completeness work.local/docs/QUIRKS-SYSTEM.mddocuments 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.mdis 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.mdis the canonical D-Bus architecture and implementation plan for KDE Plasma 6 on Wayland. It defines the phased approach to D-Bus service integration, theredbear-sessiondlogin1-compatible session broker, and the gap analysis for desktop-facing D-Bus services.local/docs/GREETER-LOGIN-IMPLEMENTATION-PLAN.mdis the canonical Red Bear-native greeter/login design and current implementation plan for theredbear-fulldesktop path. It defines theredbear-authd/redbear-session-launch/redbear-greetersplit, service wiring, validation surface, and the current boundary between the active greeter path and the olderredbear-validation-sessionhelper flows.
The current execution order for these subsystem plans is:
- IRQ / low-level controller quality
- USB maturity
- Wi-Fi native control plane and first driver family
- Bluetooth controller + host path
- 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:
- Create
local/recipes/drivers/redbear-<subsystem>-headers/ - Implement headers using Linux source as reference only
- Do NOT pull Linux source tarballs directly
- Do NOT use third-party tarballs that bundle Linux headers as a proxy
- Examples:
redbear-input-headers/→ linux/input.h, input-event-codes.h, uinput.hredbear-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:
ext4dis a Redox scheme daemon — it serves ext4 filesystems viascheme:ext4d- Uses
rsext4crate (pure Rust ext4 implementation) for all filesystem operations FileDiskallows building/testing on the Linux host machineRedoxDiskuseslibredox+redox_syscallfor actual Redox bare-metal I/O- Both impls are behind the
redoxfeature flag —--no-default-featuresgives 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 implementationredox_syscall = "0.7.3"— Redox syscall wrappers (scheme, data types, flags)redox-scheme = "0.11.0"— Scheme server frameworklibredox = "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"FilesystemTypeenum — dispatch tag used byinstall_innerwith_whole_disk_ext4()— GPT partition layout + ext4 mkfs + file sync (mirrorswith_whole_disk)Ext4SliceDisk<T>— adaptsDiskWrapperto rsext4'sBlockDevicetraitsync_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 1GBfat-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 == 0for FAT32, rejecting some Linuxmkfs.fatimages 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 inlocal/patches/ - DO NOT commit firmware blobs to git — use
local/scripts/fetch-firmware.sh - DO NOT modify
mk/orsrc/directly — extend vialocal/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 — useredbear-*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:
- DO NOT mark packages as
"ignore"to skip them - DO NOT create stub recipes that provide fake cmake configs without real functionality
- 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)
- relibc/grp/cbindgen.toml: Added group functions to export list
- relibc/grp/mod.rs: Implemented
getgroups()with egid fallback - Patches created:
local/patches/relibc/P3-grp-cbindgen-exports.patch,P3-getgroups-implementation.patch - 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 targetredbear-mini— Text-only console/recovery targetredbear-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.