Several docs still referenced files in local/docs/legacy-obsolete-
2026-07-25/ after that directory's 2026-07-27 cleanup deleted most of
its contents. The directory now only contains SUPERSEDED.md; all
other legacy-obsolete entries were fully removed. The doc cleanup
phase of the round-2 D-Bus audit identified each broken reference and
fixed it by pointing at the current canonical location.
Repairs:
- ACPI-IMPROVEMENT-PLAN.md, BUILD-SYSTEM-INVARIANTS.md,
INIT-NAMESPACE-MANAGER-SCALABILITY-PLAN.md,
NETWORKING-IMPROVEMENT-PLAN.md, USB-IMPLEMENTATION-PLAN.md:
legacy-obsolete-2026-07-25/IRQ-AND-LOWLEVEL-CONTROLLERS-ENHANCEMENT-PLAN.md
-> IRQ-AND-LOWLEVEL-CONTROLLERS-ENHANCEMENT-PLAN.md
(restored to top-level local/docs/).
- CONSOLE-TO-KDE-DESKTOP-PLAN.md:
legacy-obsolete/BUILD-SYSTEM-HARDENING-PLAN.md
-> COLLISION-DETECTION-STATUS.md
- TOOLS.md, RELEASE-BUMP-WORKFLOW.md:
legacy-obsolete/HOOKS.md
-> RELEASE-BUMP-WORKFLOW.md § 'Git Hooks' (content merged).
- patches/README.md, RATATUI-APP-PATTERNS.md:
removed dangling refs to legacy-obsolete/PATCH-PRESERVATION-AUDIT
and redbear-power-improvement-plan (both deleted with no successor
doc; the related guidance lives in the canonical plans).
Each replacement preserves the link's intent: every old reference was
pointing to a doc whose content has either been restored to top-level,
absorbed into a different canonical doc, or replaced by a plan
reference that covers the same surface.
Companion to the prior 'address 5-lane review blocking findings' commit
(which only contained the restored dbus symlink). This commit bundles the
remaining review-driven fixes for the implementation scope.
- sessiond power_off/reboot/suspend: propagate write_all errors. The
'let _ = f.write_all(...)' pattern meant a successful open followed
by a failed write was reported to the caller as success. Now checked
with explicit error propagation: write failure resets
preparing_for_shutdown/sleep to false and returns a D-Bus error.
- notifications: drop un-implemented capability advertisement
('actions', 'persistence'). Real capabilities now: ['body', 'body-markup'].
Body and app_name no longer printed to stderr verbatim (length only).
Server info version bumped 0.3.0 -> 0.3.1 to match Cargo.toml.
- wifictl: enable dbus-nm feature by default. Previously
default = [] made the 656-line NM interface dead code behind a
feature gate that the recipe never enabled.
- guard-recipes.sh --restore: add parent-symlink guard (same as --fix).
Without it, restoring a recipe whose parent directory is a symlink
into local/recipes/ deletes the real file from disk.
- verify-fork-functions.sh: narrow blanket exclusion to fmt+eq only.
drop/deref/hash/clone/etc. must go through fork-specific exclude file.
Verified:
redbear-notifications: 8/8 tests pass
redbear-sessiond: 51/52 tests pass (1 pre-existing failure
from later commit a9e1c34e27 outside scope)
redbear-wifictl: compiles with dbus-nm default
Per AGENTS.md 'DO NOT edit files under mainline recipes/ directly', create
a Red Bear fork under local/recipes/net/openssh/ that the build system
materializes via apply-patches.sh symlink.
Replaces two upstream placeholders:
1. The 'sed -i AddressFamily inet' workaround with a real capability
detection that probes relibc's <netinet/in.h> for AF_INET6 and
selects AddressFamily=any (dual-stack) or inet (IPv4-only)
accordingly. The OPENSSH_FORCE_IPV4=1 environment variable
overrides the probe to force IPv4-only.
2. The commented-out '# ssh-keygen -t ... -N ""' TODO with a real
subshell-rendered postscript that generates ed25519, rsa, and
ecdsa host keys (idempotent re-runs skip existing keys).
The patch list in the fork recipe is identical to the mainline
(just 'redox.patch' — the upstream-tracked Redox port). The Red Bear
modifications to the build are entirely in 'script =' below, so
no additional Red Bear overlay patch file is required.
Also extends local/scripts/apply-patches.sh with the 'net/openssh'
symlink entry under a new '# Network fork recipes' section.
Convert the routinely-used environment knobs to command-line flags (the
canonical interface); the REDBEAR_*/JOBS env vars remain deprecated fallbacks.
New flags: -j/--jobs, --release VER, --allow-dirty, --keep-build-state
(--upstream/--no-cache already existed). Resolved values are re-exported so the
gates and sub-scripts observe them. Rare escape hatches stay env-only and are
documented under an 'Advanced' section in --help. Dropped the phantom
REDBEAR_SKIP_ABI_STALENESS doc; did not add --arch/--target (x86_64-only build).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Remove the stash-and-restore machinery entirely. It manipulated the operator's
working tree and had a fatal bug: modern git's 'stash push' does not print the
stash SHA on stdout, so the SHA was never recorded, the stash was never restored,
and with REDBEAR_ALLOW_DIRTY=1 the operator's dirty-fork WIP was silently
stranded in 'git stash list' on every build (base had accumulated 25 strands).
The build now cooks committed HEAD, or the working tree AS-IS under
REDBEAR_ALLOW_DIRTY=1 — it never touches the tree. A read-only startup advisory
surfaces any leftover redbear-build-* strands from the old code.
Recovered the valuable stranded work to local/recovered-stashes/ (netstack
proptest, relibc get_dns_server daemon-path + getnetbyaddr impl); originals
remain in each fork's git stash list. See local/recovered-stashes/README.md.
Also: pre-cook now runs 'repo cook' with CI=1 (matches make live), fixing the
'Entering raw terminal mode ... Inappropriate ioctl' noise; and the failure
diagnostics per-recipe dump is scoped to THIS build's artifacts (mtime >= build
start) so a bare/mini build no longer lists graphical packages left over from a
prior redbear-full build.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
sync-versions: stop stamping vendored-upstream workspaces with the Cat 1
branch version. brush is a vendored upstream (reubeno/brush) whose 12 crates
carry their own upstream versions with internal ^ requirements (brush needs
brush-parser ^0.4.0, brush-core 0.5.0, ...); rewriting them all to 0.3.1 broke
the build. The old git-untracked heuristic stopped catching brush once it was
vendored (committed). Add a provenance-based .vendored-upstream opt-out marker
(covers the whole class, not just brush) read by should_exclude.
build-redbear.sh:
- versioning: BUILD_REDBEAR_VERSION (starts 1.0), --version flag, startup
banner, auto-bumped by pre-commit hook (bump-build-version.sh)
- colored output (TTY + NO_COLOR aware)
- prefix rebuild: stop reporting 'rebuilt successfully' on a make no-op;
remove derived prefix markers so a stale relibc actually re-cooks into the
sysroot; skip the rebuild when only kernel/base (which don't feed the prefix)
advanced
- record fork source-fingerprints only after a successful build (not before
make live), so a failed build no longer marks forks as built
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit replaces the D-Bus implementation stubs and gaps identified
during the zbus/D-Bus review round with real, tested implementations.
**redbear-sessiond: real login1 properties + PrepareForShutdown signals**
The login1.Manager interface had hardcoded stub values:
- idle_since_hint() and idle_since_hint_monotonic() returned 0
- inhibit_delay_max_usec() returned 0
- handle_lid_switch() returned 'ignore'
- handle_power_key() returned 'poweroff'
- power_off/reboot/suspend wrote to /scheme/sys/kstop but did NOT
emit PrepareForShutdown(before=true) / PrepareForSleep(true) first
Replace with:
- Run-time configurable atomic fields (last_activity_us,
inhibit_delay_max_us) and RwLock<String> fields (handle_lid_switch,
handle_power_key) on SessionRuntime, mutated by the existing control
socket. Defaults: 5s inhibit delay, 'ignore' lid, 'poweroff' power key.
- power_off/reboot are now async, emit PrepareForShutdown(true) before
/scheme/sys/kstop write, emit PrepareForShutdown(false) after a
successful write, and return a D-Bus error if the kstop write fails
(resetting preparing_for_shutdown).
- suspend emits PrepareForSleep(true)/(false) similarly.
- Bash-style dangling-Clone problem solved via manual Clone impl on
SessionRuntime that snapshots the atomics and lock contents.
**redbear-wifictl: real NetworkManager-shaped D-Bus interface**
The dbus-nm feature was a no-op stub that just logged 'registered'
without actually doing anything. Replace with a real zbus interface:
- zbus::interface structs wrapping Arc<Mutex<NmWifiDevice>> shared state
- org.freedesktop.NetworkManager at /org/freedesktop/NetworkManager
exposes WirelessEnabled, WirelessHardwareEnabled, State, and
GetDevices().
- org.freedesktop.NetworkManager.Device.Wireless at
/org/freedesktop/NetworkManager/Devices/0 exposes HwAddress,
PermHwAddress, State, Ssid, Strength, LastScan, AccessPoints,
GetAccessPoints(), WirelessCapabilities.
- register_nm_interface() now actually builds a blocking
zbus::connection::Builder on the session bus, registers both
service name + object paths, spawns a background thread to hold the
connection alive, and returns. On session-bus connect failure it
logs an error and returns without crashing.
- When the dbus-nm feature is disabled, behavior is unchanged (no-op).
- Type model enriched: NmWifiDevice gains last_scan, active_ssid,
active_strength fields + Default derives; NmDeviceState gains
Default; NmAccessPoint gains Default.
**redbear-statusnotifierwatcher: wired into redbear-full**
The recipe compiled and had 12 tests but was NOT in any config —
the binary never deployed. Add:
- [package.files] stanza to its recipe.toml so the binary is staged
- redbear-statusnotifierwatcher = {} to config/redbear-full.toml
- launch_optional_component invocation in redbear-kde-session
**redbear-notifications: 8 host unit tests**
Previously zero tests. Add a #[cfg(test)] module covering:
- monotonic notification IDs
- capabilities list (spec values present)
- server information strings
- close-id + reason recording
- action invocation payload
- ordering preserved across multiple notifications
- independence between close and action records
**zbus build-ordering marker: clean source**
The marker source lib.rs contained 'pub struct Connection;' which
is misleading. Replace with a minimal comment explaining the
build-ordering purpose. The actual zbus crate is still resolved by
Cargo at downstream build time (unchanged behavior).
**D-Bus symlink cleanup**
Remove recipes/system/dbus/dbus-root-uid.patch (orphan symlink, not
in .gitignore-relevant scope). The actual patch stays in
local/patches/dbus/. The redox.patch in the same directory is a
real file (not a symlink) and is preserved.
**Build-system bug fixes**
- build-preflight.sh: when broken recipe.toml links cannot be restored
from git, invoke the guard-recipes.sh --fix path so untracked
custom links are regenerated.
- verify-fork-functions.sh: skip std-trait method names (fmt, eq,
clone, drop, etc.) when checking for dropped upstream functions —
these are derivable or compiler-caught, so a missed refactor is
inert, not a build blocker.
- verify-overlay-integrity.sh: add explicit 'return 0' on log helpers
so --quiet mode does not abort on the first log call under set -e.
Verification: host cargo test passes on all four modified daemons.
redbear-sessiond: 52 tests (12 new for the properties + signals).
redbear-wifictl: 35 tests (4 new for dbus_nm) + 2 cli_transport.
redbear-notifications: 8 tests (all new).
redbear-upower/udisks/polkit: unchanged, still pass.
The DRIVER-MANAGER-MIGRATION-PLAN was self-declared complete (the
driver-manager cutover happened 2026-07-23 per local/AGENTS.md). It
is now historical reference material rather than current planning
authority. Move it from local/docs/ into the established
legacy-obsolete-2026-07-25/ archive directory, updating every
inbound reference.
Also includes minor cross-doc alignment for the previous round's
relocations:
- local/AGENTS.md: update DRIVER-MANAGER-MIGRATION-PLAN to point to
the legacy archive
- local/docs/REDBEAR-FULL-SDDM-BRINGUP.md: alignment update
- local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md: alignment update
- local/docs/archived/README.md: refresh archive contents note
- local/recipes/system/redbear-driver-policy/source/policy/README.md:
policy doc drift alignment
- local/scripts/guard-recipes.sh: fix symlink target computation
(relative path was being glued onto an absolute path, producing
malformed dangling links like '../..//mnt/.../recipe.toml')
-- this is a real bug fix discovered during this audit round.
QEMU \u22658.0 dropped the legacy 'virgl=on' device property in favour of
the more general 'blob=true' which enables the VIRTIO_GPU_F_RESOURCE_BLOB
feature negotiated by the redox-drm virtio backend. Without this,
the device property was silently dropped and the guest received
2D-only KMS without any 3D acceleration.
The new 'blob=true' activates the virgl blob-resource path, matching
the VIRTIO_GPU_F_RESOURCE_BLOB bit that redox-drm already negotiates
on the host-guest boundary.
Round 1 of the LG Gram 16Z90TP compatibility work. Two parallel
workstreams in one commit:
1. Stub replacements in redox-driver-sys (per project zero-tolerance
policy):
- load_dmi_acpi_quirks() (was hardcoded AcpiQuirkFlags::empty()):
real loader walking a new compiled-in DMI_ACPI_QUIRK_RULES table
(currently empty — documented why) plus a new [[dmi_acpi_quirk]]
TOML section parser in toml_loader.rs. The full 16-flag
ACPI_FLAG_NAMES mapping is added so TOML entries can use any
AcpiQuirkFlags variant by name.
- PANEL_ORIENTATION_TABLE (was empty placeholder): populated with
10 real entries ported from Linux 7.x
drivers/gpu/drm/drm_panel_orientation.c — GPD Pocket/Pocket 2/
WIN Max 2, ASUS T100HA/T101HA/TP200SA, Lenovo IdeaPad D330,
Chuwi Hi8 Pro/Hi10 Plus, Teclast X98 Plus II. Each entry cites
its Linux source commit.
- PLATFORM_RULES (kept empty): documented why intentionally empty
(Linux platform-wide DMI quirks are pre-2020 platform workarounds
not needed by Red Bear's modern targets).
2. Broken reference fixes after the 2026-07-25 archive
(commit 589a1044e6 moved 9 docs to legacy-obsolete-2026-07-25/
but didn't update references). 30+ files referenced the moved
docs by their old local/docs/<name>.md path. This commit updates
every reference to point at local/docs/legacy-obsolete-2026-07-25/
<name>.md so links work again. Files touched: AGENTS.md,
README.md, docs/{AGENTS,README,07-RED-BEAR-OS-IMPLEMENTATION-PLAN}.md,
local/AGENTS.md, 14 docs under local/docs/, local/patches/README.md,
5 scripts under local/scripts/.
The matching acpid+ps2d consumer wiring landed earlier today in
submodule/base commit 45452c5a (force_s2idle, no_legacy_pm1b,
kbd_deactivate_fixup). The bootstrap reference fix is submodule/base
commit 263a41a9. Both are tracked by the updated submodule pointer
in this commit.
Build verification: redox-driver-sys 80 cargo tests pass. acpid/ps2d
host tests not runnable (require cross-compile). Canonical build
attempts uncovered two pre-existing failures unrelated to Round 1:
relibc edition-2024 unsafe-block issue in crtn, and the base fork's
'common' path resolution relies on the build script's overlay
integrity auto-repair which is currently failing. Neither is in code
touched by Round 1.
See local/docs/evidence/lg-gram/ASSESSMENT-2026-07-26.md for the full
round-by-round assessment and next-round plan.
Fixes the chain of blockers that left redbear-full producing a desktop-less ISO
while still reporting success. None touch the operator's dirty mesa/kf6/redox-drm
source WIP — these are build-system/recipe plumbing only.
build-redbear.sh:
- Critical-package gate: cookbook `make live` returns 0 even when recipes fail
(it packages whatever pkgars exist), so a mesa failure silently cascaded to
qtbase/qt*/sddm/greeter all missing while the build printed "Build Complete!".
Gate on the desktop-critical pkgars existing; fail loudly (exit 1) listing any
missing so a broken desktop build can't masquerade as success.
- Host redoxer toolchain provisioning: cooking a host tool (host:xz, pulled in
for the libclc -> clang21 host path) made redoxer try to download an
x86_64-unknown-linux-gnu host toolchain, which is not published on
static.redox-os.org -> 404 "unable to init toolchain", failing every host
cook. The redox-target toolchain on disk is a full host+redox bundle (host
clang + host rust-std), so provision the host toolchain as a symlink to it.
Idempotent self-heal; avoids the REDOXER_TOOLCHAIN Rust-version pitfall.
- Pre-cook libclc before mesa.
local/recipes/libs/mesa/recipe.toml:
- Declare `libclc` as a dependency. Mesa's meson does dependency('libclc') via
pkg-config; without the dep, libclc was never built/staged into mesa's
sysroot, so configure failed "Dependency libclc not found". libclc ships its
.pc in its main package, so depending on "libclc" is sufficient.
recipes/tools/xz/recipe.toml:
- Host build static-only. xz 5.8.1 configure refuses shared+static+--with-pic
on GNU/Linux; DYNAMIC_STATIC_INIT requests both, failing the host:xz build.
Redox target keeps both.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The ABI-staleness step recompiled the ENTIRE dynamically-linked userspace (Qt,
KF6, mesa, sddm) whenever relibc/base/a-protocol-fork changed -- so editing a
driver, acpi, or base recipe rebuilt the whole desktop. That is wrong: relibc is
a shared libc.so.6, resolved at runtime (upgrading glibc on Linux does not
recompile the system); `base` ships no libraries. Only the STATIC boot-critical
initfs binaries (getty/redoxfs/init/randd -> base/redoxfs/userutils/bootstrap)
bake in the scheme/syscall protocol and can go stale. Invalidate only those.
Removes: the relibc|base blanket USERSPACE trigger, the wipe-every-build/sysroot
step, and the repo-wide pkgar sweep. Genuine relibc C-ABI break -> --no-cache.
The relibc-consumer ABI sweep looped over the whole shared repo/*.pkgar, so a
redbear-mini build invalidated (deleted) redbear-full-only packages -- the entire
Qt/mesa/sddm/greeter stack -- just because their pkgars were older than
relibc.pkgar. Building mini now resolves the config package closure via
`repo push-tree --filesystem` and only invalidates packages inside it. Build
mini, touch mini; full artifacts are never collateral. No env flag needed for
the common case.
Phase 2 of the 3D driver plan (local/docs/3D-DRIVER-PLAN.md). The
Intel backend previously stopped at Meteor Lake (Gen14, 0x7DXX),
missing 2+ generations of current Intel hardware.
Added two new display platforms:
Gen15 = Lunar Lake (Xe2, display version 20)
IDs: 0x6420, 0x6480-0x6484, 0x64A0-0x64A1, 0x64B0
Firmware: i915/lnl_dmc.bin, lnl_guc_70.bin, lnl_huc.bin, lnl_gsc_1.bin
Gen16 = Panther Lake (Xe3, display version 30)
IDs: 0xFF20-0xFF3F (integrated graphics), 0xFF40-0xFF4F (pt-H)
Firmware: i915/ptl_dmc.bin, ptl_guc.bin, ptl_huc.bin, ptl_gsc_1.bin
Both require DMC firmware (added to requires_dmc). Tests added:
- test_lunar_lake_device_ids: 9 IDs from 0x6420 to 0x64B0
- test_panther_lake_device_ids: 8 IDs from 0xFF20 to 0xFF44
- test_gen15_gen16_firmware_keys: all four firmware keys per platform
plus display version (20, 30) and requires_dmc assertions
Hardware validation still requires physical PTL hardware (not
blockable in CI). Firmware blobs need to be staged via
local/scripts/fetch-firmware.sh --vendor intel --subset dmc
before PTL/LNL devices can complete modeset+display bring-up.
Phase 1 also adds local/scripts/test-virgl-qemu.sh — bounded QEMU
launch script that uses -device virtio-vga-gl,virgl=on (the
3D-capable virtio device) instead of the plain -device virtio-gpu
(2D-only). Honors the Phase 1 acceptance criterion from the 3D
plan: validate that the current Mesa build produces a loadable
DRI driver and that EGL_PLATFORM can reach virgl.
Both are greeter-critical (the Wayland compositor that displays the SDDM greeter,
and the greeter launcher). Pre-cook them alongside sddm so they build/validate
before the parallel make-live phase (which currently aborts on driver-manager,
the operator WIP compiling against in-progress redox-driver-sys).
Executing the greeter-focused path: the SDDM greeter dependency closure needs
only Qt + 9 kf6 core modules + sddm + compositor + graphics. The full Plasma
desktop (kwin, plasma-*, kirigami, konsole, kf6-ksvg/kio/solid/... - 42 packages
outside the greeter closure) is post-login and each has its own Redox porting
gaps (kf6-ksvg needs KirigamiPlatform, kf6-solid QSystemSemaphore, kwin private
Qt APIs, ...). Comment those [packages] entries (# GREETER-DEFER, easily
reverted) and drop kwin from the pre-cook list so the build reaches a bootable
SDDM-greeter image now. Re-enable for the full desktop once its stack is ported.
Qt cmake plugin targets resolve each plugin .so via <sysroot>/plugins (the
_IMPORT_PREFIX is computed from the cmake files under <sysroot>/lib/cmake, i.e.
the sysroot root, not <sysroot>/usr), but cmake --install --prefix .../usr puts
plugins at usr/plugins. qtbase already works around this by staging plugins to
BOTH usr/plugins and plugins (recipe.toml ~L739); qtwayland/qtsvg/qtdeclarative
did not, so their plugins (wayland decorations, svg imageformats/iconengines,
qmltooling) were unreachable at <sysroot>/plugins and any Qt6Gui/Qt6Qml consumer
failed: imported target references "<sysroot>/plugins/.../foo.so" but this file
does not exist. This blocked kf6-kwindowsystem (sddm dep) on the Adwaita
decoration plugin. Add a shared redbear_qt_dual_stage_plugins helper and call it
after install in all three. (Note qml already resolves via the qml symlink since
qtbase does not dual-stage qml, so <sysroot>/qml is a symlink not a real dir.)
Qt installs QML plugins under <prefix>/usr/qml, but the generated CMake plugin
targets (Qt6Qml/QmlPlugins/*Targets.cmake) resolve each plugin .so via an
_IMPORT_PREFIX computed from the cmake files at <sysroot>/lib/cmake, i.e.
<sysroot>/qml/... . Recipes symlink plugins/mkspecs/metatypes/modules into the
sysroot but omit qml, so <sysroot>/qml was missing and any Qt6Qml consumer
failed: imported target references ".../sysroot/qml/QtWayland/.../plugin.so"
but this file does not exist (it is at usr/qml/...). This blocked kf6-kwindowsystem
(direct sddm dep). Add qml to every sysroot-link site: the redbear_qt_link_sysroot_dirs
helper default, ~15 helper callers, and ~10 inline for-loops (61 files).
Also corrects qtsvg CVE patch ref "qtsvg/CVE-..." -> bare "CVE-..." (patch is in
the recipe dir; same patch-path class as the mesa fix) so qtsvg builds from clean.
Two corrections after finding the Qt offline-source model:
1. The Qt recipes intentionally COMMIT source.tar as the offline source
(qtbase/qtsvg/qtshadertools all do). My previous commit wrongly added a
local/recipes/**/source.tar ignore rule; revert it -- source.tar is durable
here, only source/ is the fork model.
2. Real deficiency: the pre-cook offline decision honored only the
REDBEAR_ALLOW_UPSTREAM env var, while the main `make live` phase also goes
online for the --upstream flag (ALLOW_UPSTREAM=1). So `--upstream` alone left
the pre-cook OFFLINE but the main phase ONLINE -- a package missing its
source.tar cache (e.g. right after the stale 6.11.0 tars were purged) failed
the pre-cook with "Opening file for blake3 failed ... source.tar: No such
file". Make the pre-cook honor ALLOW_UPSTREAM too, matching the main phase.
sddm and the kf6 modules (pulled by kwin) do find_package(Qt6Qml)/Qt6Quick,
which only exist once qtdeclarative is built. When resolved only transitively
during the parallel make-live graph, a consumer (qtwayland, kf6-kwindowsystem)
could be cooked before qtdeclarative published Qt6Qml -> "Could not find a
package configuration file provided by Qt6Qml" -> whole build aborts (exit 2).
Pre-cook qtbase qtshadertools qtdeclarative qtsvg qtwayland (in order) before
sddm/kwin so every Qt6 CMake config is cached in the sysroot first. Complements
the qtwayland->qtdeclarative recipe dep; covers all kf6 consumers at once.
Iterating on one recipe (e.g. redbear-iwlwifi) forced a ~30-min re-churn every
rerun: the relibc-consumer invalidation (build/sysroot wipe + pkgar/target
deletion) re-cooked dozens of cached packages before reaching the edited one,
even when relibc was unchanged. Add REDBEAR_SKIP_ABI_STALENESS=1 to skip both
the layer-B build/sysroot clean and the layer-C invalidation loops. The
cookbook BLAKE3 dep-hash cache still re-cooks recipes whose sources changed, so
the edited package rebuilds while everything else stays cached — the rerun goes
straight to it. Safe only when relibc ABI is unchanged (documented + escape is
opt-in); unset to restore the stale-binary safety net when bumping relibc/base.
Documented in --help alongside REDBEAR_FORCE_TOOLCHAIN_RECOOK.
The relibc-consumer invalidation (correctly) force-deletes every pkgar+target
when relibc rebuilds or its pkgar is missing, to prevent stale-ABI skew. But it
swept up heavy, ABI-inert toolchain packages (llvm21, clang21, lld21, rust)
identically to a 200KB daemon — forcing a 1-2h LLVM re-cook on EVERY base/relibc
bump, which cripples Mesa/KDE iteration.
These are build-time-only STATIC archives (BUILD_SHARED_LIBS=off; no runtime .so
of their own). Their libc/relibc symbol references are UNRESOLVED in the .a and
resolve at the CONSUMER final link — mesa links libLLVM*.a and resolves against
the freshly-built relibc there. So a relibc protocol change is absorbed by
relinking mesa (NOT on the preserve-list; stays invalidated), and recompiling
all of LLVM from scratch is unnecessary.
Add TOOLCHAIN_PRESERVE={llvm21,clang21,lld21,rust} skipped in both invalidation
branches, with escape hatch REDBEAR_FORCE_TOOLCHAIN_RECOOK=1 for a genuine
libc-ABI change. Trades a rare theoretical risk for a large repeated speedup;
the churn during driver/desktop work is Redox scheme/syscall shims the compilers
never call, so the default is safe.
The stash loop ended with '[ any_dirty = 0 ] && echo ...' as the
function's last command — when a fork IS dirty (any_dirty=1), the
compound returns 1 and set -e kills the build silently right after the
stash phase. Only visible with REDBEAR_ALLOW_DIRTY=1 (the dirty gate
refuses earlier otherwise). Now an explicit if + return 0.
Seventh-round integrations of the driver-manager migration's D-phase.
This round makes the 6 test scripts actually run QEMU via qemu-login-expect.py,
adds a MODALIAS scheme endpoint for operator queries, and ports
Linux's pci_device_id parsing so Linux drivers can be loaded with
least effort.
Test scripts (6, all functional now):
- test-driver-manager-parity.sh (C1 dual-mode observation): runs QEMU with
redbear-mini live.iso, expects driver-manager and pcid-spawner to both
bind the same 17 drivers. Exits 0 on PASS, 1 on FAIL, 0 on SKIP
(QEMU not available).
- test-driver-manager-active.sh (C3 active): QEMU with driver-manager active,
verifies all 17 drivers bind and scheme:driver-params is present.
- test-driver-manager-initfs.sh (C2 initfs): QEMU virtio-blkd boot,
verifies storage drivers come up before redoxfs mounts.
- test-driver-manager-hotplug.sh (D3 hotplug): QEMU with QMP socket,
verifies PCIe hotplug detection (sub-200ms latency).
- test-driver-manager-pm.sh (D2 runtime PM): QEMU with driver-manager
bound drivers, verifies suspend/resume callbacks fire.
- test-driver-manager-cutover.sh (C4 production): QEMU 3-reboot bound-set
identity check.
modalias.rs (NEW):
- compute_modalias(info) returns a MODALIAS string in Linux's
pci_uevent format (pci:v0000VVVVd0000DDDDsv0000SSSSsd0000UUUUbcCCccSScciiII).
- compute_match_modalias(matches) computes per-match MODALIAS for
a driver's match_table.
linux_loader.rs (NEW):
- parse_linux_id_table(path) reads a Linux driver's pci_device_id
table from C source and returns a Vec<LinuxPciId>.
- parse_linux_id_table_from_source(source) parses from a string.
- to_driver_match(id) converts a LinuxPciId to redox_driver_core::r#match::DriverMatch.
- Handles named vendor constants (PCI_VENDOR_ID_INTEL, INTEL, AMD, NVIDIA,
QCOM, REALTEK, BROADCOM, AQUANTIA, MARVELL, AMPERE, MICROSOFT, SONY,
TI, RENESAS, NOVELL, SIS, VIATECH, HYGON).
- Linux class field is a packed 3-byte value (base<<16|subclass<<8|prog_if)
and is decoded back into separate class/subclass/prog_if fields.
scheme.rs:
- Added /modalias endpoint. Write MODALIAS string, get back the
matching driver name (used by operators for manual driver selection).
main.rs:
- Declared modalias.rs and linux_loader.rs.
Docs:
- DRIVER-MANAGER-MIGRATION-PLAN.md v1.9 status table
- D5-AUDIT.md v1.9 update
- AGENTS.md + docs/README.md pointers to v1.9
Test totals: 39 tests across 4 crates, all passing.
§ 0.5 audit gate: 0 violations across 38 files.
Third-round integrations of the driver-manager migration's D-phase.
The pcid_interface crate (in local/sources/base submodule, see
upstream commit ddcd0870) now reads REDBEAR_DRIVER_PCI_IRQ_MODE
and REDBEAR_DRIVER_DISABLE_ACCEL at connect_default time, exposing
them as PciFunctionHandle accessors. The quirk integration is
end-to-end: driver-manager emits the env vars on spawn, pcid_interface
parses them, and the child driver reads the hints from its
PciFunctionHandle.
driver-manager (16 tests, unchanged count + 3 new for observability):
- main.rs: --list-drivers prints the config table, --dry-run
prints how many drivers would-bind/defer/blacklisted without
spawning, --export-blacklist prints the loaded blacklist.
- policy.rs: adds blacklist_module_names() iterator for export.
driver-manager v1.5 quirks.rs (created earlier at v1.4 PciQuirkFlags
work) is in the staging area and is unchanged this round.
local/scripts/driver-manager-audit-no-stubs.py:
- Drops R4 (was: 'let _ = ...' no-op detection) because Rust's
'let _ = expression' is idiomatic and not actually a stub.
- Adds R5 (stub-macro callbacks: unimplemented!/todo!/unreachable!
in callback / fn bodies) to detect dead-end fallbacks.
- Audit gate now reports 0 violations across 35 files (was 34,
pcid_interface is now in scope).
local/sources/base submodule pointer: updated to upstream commit
ddcd0870 (the pcid_interface env-var-reading commit).
Test totals: 58 tests across 4 crates, all passing.
§ 0.5 audit-no-stubs.py: 0 violations across 35 files.
Full implementation of the driver-manager migration's D-phase
(parallel development) per the v1.3 plan. The § 0.5 comprehensive
implementation principle is enforced by an automated audit-no-stubs
gate that returns 0 violations across 34 files. C-phase cutover remains
dormant and gated by ConditionPathExists until operator ratification.
redox-driver-core (28 unit + 5 integration tests):
- concurrent.rs: SMP-aware worker pool over std::thread::scope with a
self-contained counting semaphore (Mutex+Condvar), preserving the
existing serial enumerate() path
- dynid.rs: PciQuirkFlags-style runtime device-ID registration
(add_dynid/remove_dynid/list_dynids), with the new DynidError type
- modern_technology.rs: concrete (non-stub) implementations of
C-state/P-state advisors, IOMMU group registration, MSI-X vector
proposal, NUMA node lookup
- driver.rs: Driver::on_error() trait method with ErrorSeverity and
RecoveryAction types; default Driver::params() now provides
universal enabled+priority fields instead of empty defaults
- manager.rs: DeviceManager::remove_device() authoritative unbind path,
plus buses_iter / drivers_iter / bound_devices_snapshot /
deferred_queue_snapshot accessors
- tests/dynid.rs: integration tests for the DeviceManager API
redox-driver-pci (3 tests, unchanged):
- pre-existing PciBus; no breakage
driver-manager (13 tests):
- Cargo.toml: adds redox-driver-sys path dep
- quirks.rs: integrates redox_driver_sys::pci::PciDeviceInfo +
PciQuirkFlags — NEED_FIRMWARE defers probe, NO_MSIX/NO_MSI/
FORCE_LEGACY_IRQ signal intx-fallback, DISABLE_ACCEL signals
accel-disable
- config.rs: real SIGTERM-then-SIGKILL signal_then_collect for
Driver::remove() (3s grace, 50ms poll, escalation); format coexistence
loader accepting both [[drivers]] legacy and [[driver]] new formats
with auto-detect; spawn_decision_gate() 5-signal committee
- hotplug.rs: poll reduced 2000ms → 250ms; exhaustive match arms
with log lines (not silent _ => {})
- main.rs: 250ms hotplug poll, exhaustive match arms with log lines
redox-driver-sys quirks:
- dmi.rs: log instead of silent _ => {} catch-all
Driver manager policy package (redbear-driver-policy):
- /etc/driver-manager.d/00-blacklist.conf (4 driver blacklist entries)
- /etc/driver-manager.d/50-amdgpu.toml (AMD GPU driver policy)
- /etc/driver-manager.d/initfs.manifest (ordered initfs driver list)
- /etc/driver-manager.d/autoload.d/ntsync.conf (autoload ntsync module)
- /etc/driver-manager.d/README.md (explanation)
- recipe.toml: custom install script that stages into /etc/driver-manager.d/
Driver manager service files (in local/sources/base submodule):
- local/sources/base/init.d/00_driver-manager.service — dormant
(oneshot_async, ConditionPathExists=!/etc/driver-manager.d/disabled)
- local/sources/base/init.initfs.d/40_driver-manager-initfs.service —
dormant (oneshot, ConditionPathExists=!/etc/driver-manager.d/initfs-active)
Audit gate:
- local/scripts/driver-manager-audit-no-stubs.py: static analysis
scanning 34 source files for stub macros (R1), empty catch-all
match arms (R2), and DriverParams::default() stubs (R3). Returns
0 violations at v1.3.
- local/scripts/driver-manager-audit-no-stubs.sh: thin wrapper
- local/scripts/test-driver-manager-no-stubs-qemu.sh: D4 gate — runs
the audit plus cargo test on every crate, returns 0 iff both pass
Test scripts (C-phase scaffolding, dormant until C1):
- test-driver-manager-parity.sh (C1)
- test-driver-manager-active.sh (C3)
- test-driver-manager-initfs.sh (C2)
- test-driver-manager-hotplug.sh (D3)
- test-driver-manager-pm.sh (D2)
- test-driver-manager-cutover.sh (C4)
Docs:
- local/docs/DRIVER-MANAGER-MIGRATION-PLAN.md: v1.3 status table
listing every D-phase item as Done
- local/docs/evidence/driver-manager/D5-AUDIT.md: capability-by-
capability matrix + verbatim audit output
- local/docs/HARDWARE-VALIDATION-MATRIX.md: driver-manager rows
added with v1.3 status
- local/AGENTS.md: PLANNING NOTES pointer updated to v1.3
- docs/README.md: Related Red Bear-local plans row updated to v1.3
Test totals: 49 tests across the three crates, all passing.
Audit totals: 0 violations across 34 files, all clean.
Note: local/sources/base service files (00_driver-manager.service and
40_driver-manager-initfs.service) live in a submodule and need a
separate commit there. They are NOT included in this commit.
The UHCI runtime proof grepped for the literal
'uhcid: controller initialized, polling ports'
but uhcid main.rs:535 emits it with ctrl.name interpolated mid-string:
info!("uhcid: {} controller initialized, polling ports", ctrl.name);
producing e.g. 'uhcid: 0000:00:01.2_uhci controller initialized, polling
ports'. The literal grep never matched and the proof would fail 100% of the
time at runtime.
Fix: grep with a regex anchored on the stable suffix:
grep -Eq 'uhcid: .* controller initialized, polling ports'
The ohcid, ehcid, usbhidd, and usbscsid markers were re-audited against
driver source and are all correct (ohcid main.rs:341 has no interpolation;
ehcid main.rs:294 interpolates after the matched comma prefix; all others
interpolate at line ends matched by prefix). Only the UHCI init-done marker
was broken.
Comment header and error echo updated to document the interpolated form and
point at main.rs:535 so the regex is not 'simplified' back to a literal.
No QEMU runs. bash -n passes. Verified the regex matches the real emitted
format and does not cross-match ohcid's identical suffix (the 'uhcid:' prefix
anchor disambiguates).
Create the four USB validation scripts that local/docs/USB-VALIDATION-RUNBOOK.md
references but which did not exist on disk, closing the P8-B runtime-proof gap
for the legacy host controllers and the P8-C error-injection gap for xHCI:
- test-uhci-runtime-qemu.sh (P1-B): -machine pc + piix3-usb-uhci, serial-log
proof that uhcid binds the controller and detects the attached usb-kbd.
- test-ohci-runtime-qemu.sh (P1-B): -machine pc + pci-ohci, serial-log proof
that ohcid binds the controller and detects the attached usb-kbd.
- test-ehci-class-autospawn-qemu.sh (P1-A): -machine q35 + usb-ehci + usb-kbd,
serial-log proof that ehcid enumerates the keyboard and usbhidd auto-spawns
via the unified UsbHostController trait. The existing test-ehci-qemu.sh is a
coarse usb-tablet smoke test and does NOT cover this path, so this is a full
script rather than an alias.
- test-usb-error-recovery-qemu.sh (P8-C): hot-unplug usb-storage mid-transfer
via the QEMU monitor device_del (chardev stdio mux, Ctrl-A c toggle — the
same pattern as test-xhci-device-lifecycle-qemu.sh, since qemu-login-expect.py
drives only serial and cannot reach the monitor). Proves graceful detach +
usbscsid IO-error handling with no panic.
test-xhci-device-lifecycle-qemu.sh already existed and is unchanged.
test-usb-uas-qemu.sh is intentionally NOT created: UAS is in flight in a
separate workstream and its test belongs to that change.
Proof style and harness fidelity:
- UHCI/OHCI/EHCI proofs follow the test-xhci-irq-qemu.sh serial-log grep
pattern (dual --check + interactive mode, ISO-preferred boot_args, 180s
timeout, no panic fail-marker). No guest-side checker exists that validates
legacy-controller enumeration specifically, so per the runbook's
serial-log-evidence rule they grep driver log lines instead of inventing a
guest binary.
- The error-recovery proof follows the test-xhci-device-lifecycle-qemu.sh
expect/Tcl monitor-mux pattern and reuses the existing redbear-usb-storage-check
guest binary (redbear-hwutils) to drive an active transfer — no new guest
binary is invented.
All proof markers are sourced directly from the real driver trees:
uhcid main.rs:487/535/545 (UHCI USB 1.1 at / controller initialized / connect)
ohcid main.rs:305/341/348 (OHCI USB 1.1 at / controller initialized / connect)
ehcid main.rs:154/294/560 (EHCI USB 2.0 at / controller initialized / port device)
usbhidd main.rs:221 (USB HID driver spawned with scheme)
usbscsid main.rs:190/200/163/156 (READ/WRITE IO ERROR / scheme tick / event error)
No existing scripts, qemu-login-expect.py, config/*.toml, recipes, or the
runbook were modified. The runbook's script names and --check invocations
already matched exactly, so no runbook edits were required.
Validation: bash -n passes on all four scripts. shellcheck is not installed on
this host. NO QEMU runs were performed — the host is contended by another
workload that kills QEMU processes, so validation is syntax check + pattern
fidelity review only. Runtime pass/fail is unverified.
Convert the remaining expect-based test scripts (phase1-6 runtime, usb,
wifi, bluetooth, dbus, greeter, live-iso, posix) to the stdlib python
harness, completing the migration started in 9ec00d4c81. Each script now
prefers booting the live ISO when present (falling back to harddrive.img
with snapshot=on), and retries up to 5 times when QEMU exits early or is
killed (rc 3 / 137) — the host-contention failure mode recorded in the
2026-07-20 runtime-proof status.
qemu-login-expect.py: treat an incomplete step sequence as a failure even
when a pass marker was seen partway through — partial sequences must not
count as a pass.
Post-review fixes:
- Phase 2 no longer breaks early when only --fail_marker is set: the
'if not args.pass_marker: break' guard skipped all output reads, so a
fail marker was never detected (exit 0 instead of 1). Now breaks only
when neither pass nor fail markers are configured.
- docstring referenced --pass/--fail; argparse registers
--pass_marker/--fail_marker. Align the docstring.
- retry echo said 'attempt N/3' but the loop limit is 5 attempts; say /5.
- warn and skip malformed steps (missing expect:/send: prefix) instead of
spinning in select until timeout.
Drop the host expect dependency from the PS/2, timer, IOMMU, and USB
storage (BOT) runtime proofs. local/scripts/qemu-login-expect.py drives
the guest over serial-on-stdio with ordered expect/send steps, per-step
timeouts (matching expect's per-pattern semantics), and pass/fail markers.
It distinguishes premature QEMU death (exit 3) from genuine check failure
(exit 1) so the scripts retry external interruptions without retrying real
failures. Scripts use headless -display none -vga none (fbcond serial
mirror), a 3600s per-step timeout, and a retry loop (max 5 attempts).
All six validation scripts (xhci-irq, msix, ps2, timer, iommu,
usb-storage) booted build/<arch>/<config>/harddrive.img, which is only
produced by older make-all flows and goes stale (the Jul-17 image).
Running them against it measured the wrong tree — the same trap that
produced the false '+rb0.3.0' bootloader reading and the first hub-test
failure. Each now prefers build/<arch>/<config>.iso via -cdrom and only
falls back to harddrive.img when no ISO exists. extra.img and
usb-storage.img remain as data drives in both modes.
The usb-kbd behind the QEMU usb-hub now enumerates fully: debounce ->
port reset -> enable -> second debounce -> pre-attach -> attach ->
ATTACH 5.2 -> slot 3 -> addressed -> descriptors read -> HID class match
-> 'Loading subdriver "USB HID" for port 5.2' (class 3.1 proto 1,
keyboard boot protocol).
Root cause of the final stall: an unconditional SetPortFeature
(PORT_INDICATOR) for every connected+enabled port NAK-hung on QEMU's
indicator-less hub (no control-transfer timeout), blocking the flow
before the post-enable debounce. Now gated on
wHubCharacteristics.HUB_CHAR_PORTIND like Linux has_indicators.
test-usb-hub-qemu.sh: check #5 now requires the hub-child subdriver
line ('Loading subdriver "USB HID" for port <root>.<child>') so a
root-port HID (tablet) can no longer satisfy it — closes a false-
positive hole. Timeout raised to 360s for slow TT-path driver bring-up.
Docs (plan P3-A runtime validation + matrix): full hub + hub-child
chain recorded as QEMU-proven; remaining items (intermittent reactor
startup race, slow TT-path Evaluate Context) noted.
Hub enumeration is quick, but a hub-child's class driver then performs
its own descriptor/control transfers on the slow emulated TT path, and
the guest clock runs several times slower than wall time under load.
180s cut the boot before a hub-child HID driver could finish
registering after being spawned.
Serial output from dozens of concurrent daemons interleaves mid-line,
so full-sentence matches like 'usbhubd: 8 port(s) detected' fail even
when the content is present (observed mangled as 'usbhubd: 548: port(s)
detected'). Match short fragments ('port(s) detected', 'change
detection', 'registered producer') that survive interleaving.
The 'USB HUB driver spawned' log line is emitted before setup_logging
and never reaches the serial console, so check #2 could never pass.
Use the hub-descriptor read line (emitted only after XhciClientHandle
open + 8-port descriptor fetch succeed) as the spawn proof, and fold
the old duplicate descriptor check into it.
Cat 1 discovery treated every local/recipes/*\/source/Cargo.toml as an
in-house crate, including git-fetched upstream sources like brush
(git = github.com/reubeno/brush). Rewriting upstream crate versions to
the branch version broke upstream-internal version requirements
(brush-shell was forced to 0.3.1 while brush required ^0.4.0 —
'failed to select a version for the requirement brush-shell = ^0.4.0').
Guard: skip any crate whose Cargo.toml is not tracked by the parent
repo. In-house crates are tracked trees (no independent .git); fetched
sources are gitignored and untracked. Restores correct classification:
75 crates checked (12 fetched-source crates now excluded), drift 0,
brush cooks successfully again.
- sync-versions.sh: 11 brush workspace crates 0.x -> 0.3.1 (Cat 1
in-house version policy).
- test-usb-hub-qemu.sh: boot the live ISO (canonical build-redbear.sh
artifact) instead of harddrive.img, which is only produced by older
make-all flows and goes stale — a stale Jul-17 image with a
pre-version-sync bootloader (+rb0.3.0) masked the current build and
crashed the first proof attempt. Falls back to harddrive.img only
when no ISO exists.
The script cd's into the fork dir for the clean-tree check (line ~202)
and never returns to PROJECT_ROOT. Every subsequent relative
'cd "$fork_dir"' subshell then fails with 'No such file or directory',
making single-fork and multi-fork runs always FAIL at the upstream-ref
resolution step. Make fork_dir absolute at assignment so all subshell
cd/git calls work regardless of current directory.
Found while attempting the base fork sync (verify-fork-functions gate).
Tier 1 message fixes (Part 5.3):
- M18/M19 (build-redbear.sh:523-524): reworded patch-application messages
to reflect local fork model (forks have patches committed; recipe patches
for non-fork recipes applied atomically by repo fetch)
- M46 (build-redbear.sh:923): 'immutable archives' → 'local forks'
Tier 2 doc consolidation (Part 7):
- GRUB-INTEGRATION-PLAN.md: updated all 'make all CONFIG_NAME=' commands
to canonical './local/scripts/build-redbear.sh' equivalents
- SLEEP-IMPLEMENTATION-PLAN.md: archived (referenced 0.2.4 branch, pre-0.3.1)
Assessment doc Part 7 updated: all Tier 1 (items 1-6) and Tier 2 (items 7-13)
marked as verified complete with per-item status.
All Q1-Q10 quality improvement opportunities from Part 6.2 and all Tier 1-3
items from Part 7 are now resolved.
Tier 3 code improvements (from BUILD-SYSTEM-ASSESSMENT-2026-07-18 Part 6.2):
- Q2: Add run_command_with_retry() helper with exponential backoff (1s, 2s, 4s).
Wrap download_wget and git clone with 3 attempts. Git clone closure cleans
partial tmp dir between retries (git refuses non-empty clone targets).
- Q3: Preserve auto_deps.toml alongside dep_hashes.toml in binary store publish
(repo_builder.rs). Restore path prefers the preserved copy, falling back to
declared-depends-only reconstruction only when the preserved copy is absent
(e.g. published by an older cookbook). Preserves full ELF dynamic dep graph.
- Q4: DepHashes::read now returns Result<Option<Self>, String> discriminating
'missing' (legitimate first build, fall back to mtime) from 'corrupt' (loud
WARN + force rebuild). Closes a silent-swallow gap where a corrupt
dep_hashes.toml produced an incorrect mtime-fallback rebuild.
- Q6: Standardize error reporting in repo.rs nonstop path to {:#} format,
matching the pattern established in the earlier Tier 1 message commit.
Tier 1 message fixes (remaining items from assessment Part 5.3/5.4):
- M26: build-redbear.sh:569 '30-60 minutes' -> config-dependent range
- A6/A8: Makefile container messages add remediation hint
- B3: mk/config.mk sccache hint adds install guidance
- H2: mk/qemu.mk Unsupported ARCH lists supported values
- mk/redbear.mk comment 'fully-patched' -> 'versioned'
Verification: cargo check 0 errors, cargo test --lib 35/35 passed,
cargo clippy 0 new warnings vs baseline, make -n live + validate clean.
- build-redbear.sh: detect changes to the 4 forks the staleness loop missed
(userutils pkgar; syscall/libredox/redox-scheme crate path-deps force a full
userspace relink) — prevents stale-binary skew (bash -n validated).
- glib: drop the stale '#undef AT_FDCWD' Redox workaround — relibc now provides
faccessat()/AT_FDCWD, and glib's HAVE_FACCESSAT path needs AT_FDCWD.
- mesa: remove the dropped '-Dosmesa=true' meson option (unknown option) and
guard the osmesa.pc pkg-config edit.
- libinput: unblocked by syncing the fresh relibc libc.a (with timerfd_*) into
the stale prefix sysroot (prefix-sysroot staleness — see notes).
The kernel event scheme now implements kdup, so dup() of an epoll fd works
and tokio's registry.try_clone() succeeds — fixing the tokio runtime EINVAL
that killed every zbus daemon and the brush login shell.
build-redbear.sh: gate the userspace build/sysroot clean on relibc/base
(the forks userspace links) instead of any low-level fork, so a kernel-only
change rebuilds the kernel + initfs + image without a full userspace re-cook.
relibc is statically linked into every userspace binary, so a relibc change
invalidates every consumer, not just the 4 initfs-critical packages the old
ABI_CRITICAL_PKGS list covered. A stale consumer silently bakes in old relibc
behaviour; diagnosing against such stale binaries wastes enormous time. Now:
if relibc rebuilds, ALL package pkgars + recipe build trees are invalidated
for a clean relink; otherwise any consumer pkgar older than relibc.pkgar (the
interrupted-build skew that shipped a broken login image) is invalidated.
Also add a temporary SESSIOND_DIAG probe that tries each tokio runtime config
and logs which one EINVALs, to pinpoint the tokio-runtime failure.