Lines 298-311 had 8 fork HEAD SHAs from 2026-07-07 (+rb0.3.0 era) that have since advanced. Per ground-truth section A:\n base 4d09ab7f\n bootloader c78c3a6\n installer 1e9dcde\n kernel 22f5f622\n libredox b99b204\n redoxfs b78a791\n relibc 11a1f8bc\n syscall 6e4e5bd (+rb0.3.1)\n userutils 0dc0cb7\n\nAll forks now use +rb0.3.1 suffix. Line 311 "intentionally kept at +rb0.3.0" updated to "kept at +rb0.3.1".
Recipe example now notes that core components use path-fork recipes, while the CONFIG_NAME table entry is aligned to the actual default behavior exposed by mk/config.mk and build-redbear.sh.
Qt version: 6.11.0→6.11.1 globally (lines 56-57, 66-69, 105) per ground-truth — matches README.md and fork state.\n\nkirigami: was reported as "Build blocked at the QML gate" but local/patches/kirigami/ has patches indicating it builds. Updated to "Builds; runtime QML validation incomplete".\n\nkf6-kio: same — local/patches/kf6-kio/01-no-testlib.patch shows builds are now succeeding with tests disabled. Updated to "Builds; runtime QML validation incomplete".
Ground-truth staleness fix for AGENTS.md, aligned to section A of /tmp/rb-ground-truth.txt (core forks use PATCHED-VIA-PATH-FORK; e.g. base 4d09ab7f, kernel 22f5f622).
Per ground-truth: 9 forks exist (the 7 listed + syscall + libredox). Added syscall and libredox to the fork list with a note about how they're wired (Cargo path deps via redox-rt consumers, not via recipes/<comp>/recipe.toml path = ).
POSIX gaps row: "~38 active patches" is stale — relibc now uses PATCHED-VIA-PATH-FORK; the local/patches/relibc/ directory holds reference and archived patches, not active build-time patches.
KDE Plasma / KWin row was conflating two distinct statuses. KWin BUILDS successfully (the redox-drm + Qt6 Wayland patches exist); only the RUNTIME is blocked by the Qt6 Wayland crash. Split into two rows so readers know exactly what works vs what's blocked.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
The verify-overlay-integrity.sh script has two blind spots for stale
symlink detection:
1. find recipes -maxdepth 3 misses paths at depth 4+
2. only checks targets under /local/recipes/, misses /local/patches/
This adds a parallel scan that finds all dangling symlinks under recipes/
without maxdepth, classifies them by target path, and reports each with a
suggested action. Pure diagnostic — does not modify any files.
Enables preventive detection of the recipes/wip/x11/mesa-x11/source
orphan and recipes/core/base/redox.patch pointer-rot that triggered the
build integrity warnings on this session's rebuilds.
(NO AI attribution in commit message.)
bss_dgram.c uses 'struct in6_pktinfo' from <netinet/in.h> which is
not fully defined in relibc headers (sizeof on incomplete type).
Added no-dgram to disable datagram BIO (DTLS/QUIC) for now.
Red Bear OS doesn't need DTLS yet — standard TLS via stream sockets
is sufficient.
OpenSSL's Configure detects x86_64-unknown-redox-gcc as the compiler
but Make can't find it because the cross-compiler prefix/bin is not
in PATH. Added COOKBOOK_HOST_SYSROOT/bin to PATH before Configure call.
Also added no-sctp flag since relibc lacks <netinet/sctp.h>.
Archived mega-patches (kernel/redox.patch, base/redox.patch, relibc/redox.patch,
installer/redox.patch, bootloader/redox.patch, P2-boot-runtime-fixes) were
consolidated into modular P0-...P9- patches during Phase 2/3 cleanup but the
integrity checker still expected them. Removed from EXPECTED_PATCH_SYMLINKS
and CRITICAL_PATCHES arrays. Fixed qt6-wayland-smoke symlink.
Overlay integrity check now PASSES (0 errors).
--with-pic alone doesn't generate PIC code in newer ncurses (6.6+).
The static archive produced non-PIC objects using R_X86_64_PC32
relocations, which can't be linked into PIE executables.
Forced PIC via:
- Switched DYNAMIC_INIT → DYNAMIC_STATIC_INIT (builds both shared AND static)
- Added CFLAGS+=+=-fPIC CXXFLAGS+=+=-fPIC export (forces PIC at compile)
redbear-netctl-console now links successfully against libncursesw.a.
The repo_builder binary had a guard at line 79-81:
if std::env::var("COOKBOOK_CROSS_TARGET").is_ok_and(|x| !x.is_empty()) {
return Ok(());
}
This silently returned early when COOKBOOK_CROSS_TARGET was set —
which is ALWAYS the case during a Red Bear build (we cross-compile
for x86_64-unknown-redox from the host).
Net effect: pkgar files were NEVER published to repo/<target>/ during
the canonical build path, leaving the binary store effectively empty
across builds. With no cache, every recipe was forced to re-cook on
every build, even when its source and inputs had not changed.
Removed the guard so repo_builder always publishes. The per-target
subdirectory layout (repo/<target>/<pkg>.pkgar) is correct because
repo_builder uses redoxer::target() which resolves to the TARGET env
var, matching the lookup path used by cook_build.rs::restore_from_repo().
Static archives without -fPIC cannot be linked into PIE executables
(default on modern Linux). redbear-netctl-console failed to link with:
libncursesw.a: relocation R_X86_64_32 ... can not be used when making a PIE
object; recompile with -fPIE
Added --with-pic to ncurses and ncursesw configure flags to produce
position-independent static archives.
Previously, same_as recipes (ncursesw uses same_as = ../ncurses) would
fail with 'cannot guess version' because the cookbook only falls back
to Cargo.toml extraction, not the target's recipe.toml.
Now when source is same_as, read the target's recipe.toml directly and
use its [package].version field. Falls back to Cargo.toml probe if no
version is set in the target recipe.
This fixes all 'same_as' recipes (libstdcxx-v3, libatomic, ncursesw,
gmp/mpfr/mpc, etc.) without requiring explicit [package] on each.
ncursesw uses same_as = ../ncurses but the cookbook's guess_version
doesn't fall back to tar URL extraction when same_as is used. With
only [source] and [build], ncursesw has no parseable version → fails.
Added explicit [package] section with version 6.6 to ncursesw recipe,
matching the upstream ncurses version.
relibc has full Rust implementation of timerfd_create/timerfd_settime/
timerfd_gettime but lacked cbindgen.toml. cbindgen skipped the directory
entirely so <sys/timerfd.h> was never installed.
Required for Qt6 QSocketNotifier and many C programs.
recipes/dev/gcc13 was claiming name='cxx' — conflicted with
local/recipes/dev/gcc-native also claiming 'cxx'. Renamed to match
directory names for unique package identification by the cookbook.
Comprehensive fix — not a fallback. Each recipe now has explicit
[package] section with name and version. Version inference:
- Git-source recipes without rev/branch: '0.1.0' (Red Bear convention)
- Tar/git recipes with version in URL or dir name: extracted version
- Sysroot-copy recipes: matched to toolchain version
Affected: 250+ recipes across all categories (core, libs, dev, system,
kde, qt, drivers, gpu, drm, kernel, userspace, etc.) Every recipe
in the redbear-mini build chain that was missing [package] now has
explicit version metadata. Cookbook can now always determine a version
at packaging time, eliminating 'cannot guess version' failures.
No cookbook fallback hack — the source of truth is recipe metadata.
netdb: git source with no rev/branch — added explicit version 0.1.0.
Reverted the 'guess_version -> 0.1.0' cookbook fallback — masking
missing versions is not a fix, proper recipe metadata is.
When recipe has no [package].version, no parseable tar URL version,
no git rev/branch version, no Cargo.toml version, and no directory-name
version — fall back to '0.1.0' instead of failing with 'cannot guess
version'. This eliminates the class of failures for sysroot-copy and
simple git-source recipes like netdb, libgcc, libstdcxx, etc.
When recipes/<cat>/<name> is a directory symlink into local/recipes/,
creating a file-level symlink at recipes/<cat>/<name>/recipe.toml
resolves through the dir symlink and CORRUPTS the real file at
local/recipes/<cat>/<name>/recipe.toml (replaces it with a broken
self-referencing symlink).
This was the root cause of 186 'broken recipe.toml' auto-repairs
on every build. Called via apply-patches.sh line 369.
libgcc copies libgcc_s.so from toolchain sysroot and has no [source]
section. Cookbook's guess_version had nothing to parse — no tar URL,
no git rev, no directory-name version. Added explicit version 14.2.0
(matching the cross-compiler GCC).
Cookbook requires parseable version — ca-certificates (git source, no rev/branch)
and icu (tar URL with underscore version format) failed 'cannot guess version'
at packaging stage. Added explicit [package] sections:
- ca-certificates: version 0.1.0
- icu: version 75.1
Broken recipe.toml corruption also affects tracked symlinks in
recipes/ tree (e.g. recipes/libs/libxau/recipe.toml). Extended
the auto-repair find to cover both local/recipes/ and recipes/.
Detects broken recipe.toml symlinks in local/recipes/ (self-referencing
corruption from unknown source) and auto-restores from git before build.
Prevents 'Package not found' errors when recipe.toml files are unreadable.
apply-patches.sh: 005-qtbase signature now checks correct path
(recipes/wip/qt/qtbase, not recipes/libs/qtbase) and respects
local recipe override. Qt is desktop-only (redbear-full target).
check-fork-drift.sh: skip diverged forks (kernel, bootloader, installer)
to suppress spurious DRIFT warnings. These forks intentionally diverge
from upstream per fork-upstream-map.toml.
integrate-redbear.sh: add safety guard — refuse to symlink any path
ending in 'recipe.toml'. 185 local recipe.toml files were corrupted
into broken self-referencing symlinks by an earlier build session.
All restored from git. Guard prevents reoccurrence.
check-fork-drift.sh: diverged forks (kernel, bootloader, installer)
are intentionally ahead of upstream — skip them to suppress spurious
DRIFT warnings during build preflight.
apply-patches.sh: 005-qtbase patch signature now checks correct path
(recipes/wip/qt/qtbase/recipe.toml) and respects local recipe override.
Patch creates recipes/wip/qt/qtbase/recipe.toml but the signature
check looked for REDBEAR marker in recipes/libs/qtbase/recipe.toml
(wrong path). Also added check for local recipe existence (takes
precedence per local-over-WIP policy).
This was causing overlay integrity check failures during redbear-mini
builds even though Qt is irrelevant for the console target.
Common function names (new, read, write, parse, get, set, remove, etc.)
appear in many unrelated files — cross-file search produces false MOVED
classifications (e.g., fn new() in ipcd matches fn new() in xhcid).
The case-based guard skips cross-file search for 40+ common function names.
These must be handled via the .verify-fork-functions.exclude mechanism
instead — operator decides if removal was intentional or accidental.
Results: kernel 19→17 (kcall×2 correctly MOVED to user.rs, eq/hash
correctly blocked from false MOVED to fdstat.rs)
upgrade-forks.sh:
- --no-fetch: use cached upstream refs (no network required)
- --force-reapply: force rebase even when 0 commits behind upstream
Automatically detects missing functions via verify-fork-functions.sh
and triggers reapply when RB cherry-picks dropped upstream code.
verify-fork-functions.sh:
- Cross-file search: when a function is missing from its upstream file,
search ALL fork .rs files for renamed/moved equivalents (→ MOVED)
- Per-fork exclusion list: .verify-fork-functions.exclude for
intentionally removed/replaced functions (→ EXCLUDED)
- Only truly missing (not found anywhere, not excluded) = violations
build-preflight.sh:
- Updated fix suggestion to --no-fetch --force-reapply
Results: installer 2→0 (exclusion+move), kernel 19→15 (4 moved),
base 56→44 (12 moved). Remaining missing functions are known RB
replacements pending exclusion entries.
- PATCH-PRESERVATION-AUDIT: add Phase 16.1 to cumulative reduction table
(122→0 orphans, Round 17); update operator test section with all 6 modes;
replace stale 'Round 3 final' re-run with current Round 17 verification
- TOOLS.md: add --regen and --dry-run flags; clarify default is opt-in
- HOOKS.md: add --regen and --dry-run to sync-versions.sh option list
- REGEN_LOCKFILES defaults to 0 (opt-in, not opt-out)
- New --regen flag explicitly enables lockfile regeneration
- New --dry-run flag: snapshots each Cargo.lock, regens, diffs, reverts
Reports per-lockfile changes that WOULD occur without modifying files
- Fixed --regen-only deadlock: CHECK_ONLY=1 no longer blocks regen
(mode_regen_only gate added to CHECK_ONLY skip check)
- Fixed ROOT_DRIFT unbound variable in --regen-only mode
(: ${ROOT_DRIFT:=0} before summary section)
- Moved regen_lockfile_for() definition before dry-run block
(was defined after call site — caused 'command not found')
Replaces the 6 UNKNOWN entries in the post-loop summary with
specific status derived from fork-upstream-map.toml when the
main loop doesn't set a per-fork status.
Fallback logic for forks without explicit FORK_STATUS:
- diverged mode → DIVERGED-BYPASS
- tracked mode → TRACKED-PASS
- snapshot mode → SNAPSHOT-PASS (with actual tag from map)
- not in map → NOT-MAPPED
This makes every fork's status visible at a glance:
=== Post-verification fork status ===
bootloader DIVERGED mode=diverged; content check skipped
installer DIVERGED mode=diverged; content check skipped
kernel DIVERGED mode=diverged; content check skipped
libredox PASS content matches upstream 0.1.18
base TRACKED-PASS tracked-fork, version label passed
redoxfs SNAPSHOT-PASS snapshot fork, version label 0.9.1
relibc SNAPSHOT-PASS snapshot fork, version label 0.2.5
...
Bug fix: upstream_tag variable was stale from the last loop
iteration. Now reads the correct tag from fork-upstream-map.toml.
Per assessment G2 from Round 11: verify-fork-versions.sh silently
skipped content checks for forks whose upstream tags don't exist,
making failures invisible. This adds a post-loop summary table
that enumerates each fork's verification status.
Added per-fork status tracking:
- DIVERGED: fork in diverged mode (content check skipped)
- NO_UPSTREAM_TAG: upstream tag doesn't exist (content check skipped)
- PASS: content matches upstream tag
- SKIP: no Cargo.toml (not a tracked fork)
- UNKNOWN: not yet classified (future refinement)
The summary table prints after the per-fork warn/error output,
giving operators a single-view snapshot of all 10 forks:
=== Post-verification fork status ===
fork status detail
---------- ---------------- ------
base UNKNOWN not checked
bootloader DIVERGED mode=diverged; content check skipped
installer DIVERGED mode=diverged; content check skipped
kernel DIVERGED mode=diverged; content check skipped
libredox PASS content matches upstream 0.1.18
...
Bug fix: added cd "$ROOT" before post-loop summary because the
per-fork content-check loop cd's into each fork directory.