Files
RedBear-OS/local/AGENTS.md
T
vasilito a3a4d4cde9 gitmodules: declare remaining submodules against canonical RedBear-OS
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.
2026-07-01 22:03:57 +03:00

1330 lines
68 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# RED BEAR OS — 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:
```bash
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:**
```bash
# 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
```bash
# 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
```bash
# 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
```bash
# 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):
```bash
# 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:
```
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 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 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:
```bash
./local/scripts/check-upstream-releases.sh # Read-only, zero side effects
```
### Provisioning a new release:
```bash
./local/scripts/provision-release.sh --ref=<redox-tag> --release=0.2.0 [--dry-run]
```
### Restoring sources from archives:
```bash
./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:**
```bash
./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-<release>/
> 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 form** — `local/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
```bash
# 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:
```bash
# 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).
```bash
# 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:
```bash
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 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
```bash
# 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.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:
```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
```bash
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
```bash
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:
```rust
_ => 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.