Commit Graph

1076 Commits

Author SHA1 Message Date
vasilito e26c8e1ef6 review-fixes: harden sessiond power, notifications capabilities, fork verifier, guard-recipes
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
2026-07-27 20:43:32 +09:00
vasilito 16cfde4454 review-fixes: address 5-lane review blocking findings
The 5-lane review of the 3 implementation commits uncovered
several actionable items in the scope of those commits. This
follow-up fixes the critical ones.

1. guard-recipes.sh --restore: add parent-symlink guard
   The --restore mode was missing the parent-symlink guard that
   --fix mode has. Without it, a recipe whose parent directory is
   a symlink into local/recipes/ could be deleted from disk during
   restore (the file symlink resolves through the dir symlink, so
   the subsequent rm -f deletes the real local file). This was a
   CRITICAL data-loss vector.

2. dbus-root-uid.patch symlink: restore
   The commit e65a23fd6b deleted this symlink as 'orphan cleanup'
   but recipe.toml still references it in its patches list.
   Without the symlink, the next clean fetch of the dbus recipe
   would fail with 'Failed to find patch file'. Restored.

3. wifictl dbus-nm feature: enable by default
   The 656-line NM interface implementation was feature-gated
   behind dbus-nm with default = [], making it dead code at
   build time. This violates the zero-stubs policy (no
   feature-gated no-ops). Changed default to ['dbus-nm'] so
   the interface is actually wired in the built binary.

4. redbear-sessiond power operations: propagate write_all errors
   power_off/reboot/suspend were discarding write_all results
   with 'let _ = ...'. A successful open followed by a failed
   write was reported to the caller as success. Now the write
   result is checked and reported as a D-Bus error, with
   preparing_for_shutdown/sleep reset to false on failure.

5. redbear-notifications capabilities: stop advertising unimplemented features
   The capabilities list advertised 'actions' and 'persistence'
   but the implementation has no graphical UI for action rendering
   and does not persist notifications across daemon restarts.
   Honest capabilities now: ['body', 'body-markup']. Also
   sanitized notification body logging (no body, app_name, or
   summary in stderr to avoid data exposure); updated server
   information version string from 0.3.0 to 0.3.1 to match
   the actual source Cargo.toml.

6. verify-fork-functions.sh: narrow blanket exclusion
   The blanket exemption covered drop, deref, hash, clone,
   and other methods that can carry custom semantics. The
   exemption now covers only fmt and eq (derivable, no semantic
   cost). All other trait methods must go through the
   fork-specific .verify-fork-functions.exclude file.

Out of scope (pre-existing, not from the reviewed commits):
- sessiond 'can_methods_return_na' test failure on Linux host
  (caused by kstop_writable() probe added in later commit a9e1c34e27)
- wifictl backend.rs compilation corruption from later commit
  222d5186eb ('add minimal # Safety comments to 70 files'
  split perms.set_mode(0o755); mid-token)
- AI co-author attribution in submodule/base commit ec7670ef
  (cannot rewrite history per AGENTS.md no-force-push rule)
2026-07-27 20:42:15 +09:00
vasilito 6eed30f072 round 12: Mesa ioccom stub removal + udev-shim eth0 fallback + netcfg summary + doc stale refs
Round 12 audit cleanup. Five fixes across five files plus a
zero-tolerance stub policy win:

1. local/patches/mesa/04-sys-ioccom-stub-header.patch — DELETED.
   The patch was a hand-rolled include/sys/ioccom.h with Linux IOC
   bitfield constants, living as a Mesa-side stub. Per local/AGENTS.md
   zero-tolerance policy: 'Any stub found in the tree is a bug to
   be fixed, not a precedent to follow.' relibc's new
   include/sys/ioccom.h (commit ca7a7edb on submodule/relibc,
   bumped in f145e9e768) provides the same constants natively,
   making the patch redundant.

2. local/recipes/libs/mesa/recipe.toml — removed the now-dead
   '04-sys-ioccom-stub-header.patch' entry from the patches list.
   Note added explaining the removal so a future maintainer does
   not re-add it.

3. local/recipes/system/udev-shim/source/src/naming.rs —
   predictable_net_name() used to return the hardcoded 'eth0' on
   parse failure of the PCI address. On multi-interface systems
   where multiple devices had unparseable PCI addresses, all
   collided on 'eth0'. Now returns 'net-malformed-<sanitized>'
   (unique per PCI string) so each device gets a distinct name.

4. local/sources/base/netstack/src/scheme/netcfg/mod.rs — the
   'summary' branch hardcoded devices.borrow().get("eth0") which
   made the summary output invisible to non-eth0 interfaces.
   Now iterates the full devices map and prints each interface's
   state. (The deeper 'ifaces' routing tree still has 20+ eth0
   references — restructuring that requires a schema change;
   deferred to a follow-up that adds a configurable default iface.)

5. local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md + 3D-DESKTOP-COMPREHENSIVE-PLAN.md
   — renamed 'redbear-kde-session' → 'redbear-session-launch' in the
   final stale reference; clarified 'redbear-wayland.desktop' (not
   yet wired).

Deferred: acpi-rs AML interpreter bare panic() (34 sites across
mod.rs) and netcfg ifaces routing tree (20+ eth0 references)
require schema-level refactors beyond one-shot fixes; tracked
for follow-up rounds.
2026-07-27 20:31:56 +09:00
vasilito 57cf8c0fac driver-manager: N13–N15 — stale comments + Round-4 doc
N13 updates the policy.rs module docstring to reflect the four
current policy surfaces (blacklist + options + autoload + initfs-
manifest) and the active redbear-driver-policy state. Drops the
"before v1.4 the policy was dormant" stale reference.

N14 removes the remaining "previously marked as dormant" stale
comment in main.rs (now describes the four-count summary as
confirming the redbear-driver-policy package's curated config files
are wired). Simplifies the redbear-driver-policy README's
historical-dormant note to a single sentence about the cutover
date.

N15 — no stale doc removals needed: the 2026-07-27 doc
consolidation (recorded in SUPERSEDED-DOC-LOG.md) already
removed all known-stale docs. The 3D-DESKTOP-COMPREHENSIVE-PLAN
explicitly designates the two remaining NETWORKING assessment
files as operator-authored authoritative docs, so this round
does not delete them.

DRIVER-MANAGER.md adds § 5.10.3 Round-4 (N13–N15) summary.

164 driver-manager tests pass.
driver-manager-audit-no-stubs.py: 46 files, 0 violations.
2026-07-27 20:15:50 +09:00
vasilito a9e1c34e27 round 11: libclc.pc verify + redbear-passwd [source] + sessiond can_* probe + dnsd no hardcoded upstreams + stale redbear-kde-session refs
Round 11 audit cleanup. Six fixes across six files:

1. local/recipes/system/redbear-passwd/recipe.toml — CRITICAL: was
   missing the [source] block entirely. The recipe had only [package]
   and [build] with template=cargo, which the cookbook cannot fetch.
   Added [source] path = "source" so the cookbook locates the local
   Rust crate. Also added a one-line description.

2. local/recipes/dev/libclc/recipe.toml — MEDIUM: the build script
   installs via cmake but never verifies that libclc.pc (Mesa's
   pkg-config dependency) and the .bc bitcode files actually landed.
   Without these, Mesa's 3D driver cook fails opaquely with
   'Dependency libclc not found (tried pkg-config)'. Added three
   post-install test -f checks that fail the build with a precise
   error pointing at the missing path.

3. local/recipes/system/redbear-sessiond/source/src/manager.rs — HIGH:
   the D-Bus login1 can_power_off / can_reboot / can_suspend methods
   were returning 'yes' unconditionally — the archetype lie-grade-ok
   pattern (probe says success, then the real action fails because
   /scheme/sys/kstop is missing). Replaced with a kstop_writable()
   probe that fs::metadata()s the path. Used metadata() rather than
   an actual write because writing 'shutdown'/'reset'/'s3' to
   /scheme/sys/kstop would trigger the action. The actual power_off/
   reboot/suspend methods still report granular errors when the
   write is refused.

4. local/recipes/system/redbear-dnsd/source/src/transport.rs — MEDIUM:
   UpstreamConfig::default() hardcoded 8.8.8.8 + 1.1.1.1 as fallback
   upstream DNS. Hardcoding third-party DNS bypasses netcfg integration
   and leaks user queries without consent on first boot. Replaced with
   an empty Vec — main() reads the upstream list from netcfg before
   any query is dispatched; upstream queries SERVFAIL until netcfg
   populates the list (honest default).

5. local/docs/GREETER-LOGIN-IMPLEMENTATION-PLAN.md — MEDIUM: 16
   references to the non-existent binary 'redbear-kde-session' (now
   'redbear-session-launch'). Global s/redbear-kde-session/redbear-
   session-launch/g. Also updated two 'redbear-kde' profile-name
   references to reflect the 2026-07-24 retirement and the current
   'redbear-full' ownership of the desktop path.

6. local/docs/DBUS-INTEGRATION-PLAN.md — LOW: 7 references to
   'redbear-kde-session' renamed to 'redbear-session-launch' (same
   binary rename).

6 files changed, +68/-28.

Note: Mesa 04-sys-ioccom-stub-header.patch migration to relibc proper
(sys/ioccom.h with Linux-style IOC encoding) is deferred — the
patch is a genuine gap-filler (relibc's sys/ioctl.h has the basic
macros but sys/ioccom.h is the BSD include path DRM UAPI expects).
That work belongs in the relibc fork with a prefix rebuild and
should be coordinated with the operator's prefix-staleness policy.
2026-07-27 20:08:25 +09:00
vasilito d6a8159840 docs+scripts: fix stale redbear-minimal references; xwayland patch cleanup; Mesa surface.h stale comments
Round 10 audit cleanup. Six fixes across nine files:

1. config/redbear-netctl.toml: stale comment referenced three
   non-existent configs (redbear-minimal, redbear-desktop,
   redbear-kde). Replaced with accurate include-chain note.

2. scripts/run.sh, build.sh, scripts/fetch-all-sources.sh:
   replaced all 'redbear-minimal' references with the actual
   canonical config names (redbear-mini, redbear-grub,
   redbear-wifi-experimental, redbear-bluetooth-experimental).
   Three previously listed configs (redbear-kde, redbear-live,
   redbear-wayland) never existed; removed them from the loop
   that preflights/scans/fetches 'ALL_CONFIGS' so those broken
   references no longer abort the script.

3. local/recipes/wayland/xwayland/recipe.toml:
   - removed stale '#TODO wayland-client, fix linux/input,
     wayland-scanner shim' (the workarounds are now real fixes).
   - added redbear-input-headers to dependencies so the
     uncommented <linux/input.h> include in xwayland-input.c
     resolves via Red Bear's in-tree input-headers recipe
     (per local/AGENTS.md LINUX KERNEL SOURCE POLICY).

4. local/recipes/wayland/xwayland/redox.patch:
   - stripped diff -ruwN timestamps from all ---/+++ headers
     (AGENTS.md patch format policy).
   - dropped the three xwayland-glamor.h / xwayland-window.h/c
     DRM-only hunks: they commented out xf86drm.h + drmDevice
     fields, but the recipe's mesonflags already sets
     '-Ddrm=false -Dglamor=false' so those code paths never
     compile. Removing them eliminates dead commented-out code
     that future maintainers would misread as 'in-progress'.
   - replaced hardcoded 0x110/0x112/0x111 button constants
     with the symbolic BTN_LEFT/BTN_MIDDLE/BTN_RIGHT names
     (the include is now real), matching upstream style and
     making the intent self-documenting.

5. local/recipes/libs/mesa/source/src/gallium/winsys/redox/drm/
   redox_drm_surface.h: rewrote the stale header comment that
   still claimed 'the actual present path is a no-op until
   kernel-side scanout ioctls are added' — REDOX_SCANOUT_FLIP
   is wired and working; the comment now describes the real
   implementation.

6. local/docs/3D-DESKTOP-COMPREHENSIVE-PLAN.md: marked
   redbear-wifi-experimental.toml and redbear-bluetooth-
   experimental.toml as FIXED 2026-07-27 in the config
   status table (the redbear-minimal → redbear-mini typo
   was corrected earlier).

7. local/docs/NETWORKING-AND-DRIVERS-CODE-ASSESSMENT-2026-07-27.md:
   struck through Findings 14, 18, 18b, C-21, C-22 and the
   corresponding 'Config cleanup' todo — all resolved by
   the rename to redbear-mini.toml.

9 files changed, +45/-115.
2026-07-27 19:49:47 +09:00
vasilito aae6c36b80 mesa+winsys: fix pipe_fence_handle type-mismatch UB; dnsd: implement timeout/retries config
Two production-code lie-grade fixes from the Round 9 systematic audit
(local/docs/NETWORKING-AND-DRIVERS-CODE-ASSESSMENT-2026-07-27.md and
local/docs/3D-DESKTOP-COMPREHENSIVE-PLAN.md §10):

1. Mesa redox winsys: redox_drm_fence.{h,c} had a header/implementation
   type mismatch. The .h declared

       struct pipe_fence_handle *redox_drm_fence_create(...)

   but the .c returned uint64_t and passed the scheme fd through pointer
   casts ((int)(intptr_t)fence). The pipe_fence_handle struct defined in
   the .h was dead code. On 64-bit this works by accident (a uint64_t fits
   in a pointer-sized slot), but it is undefined behaviour on 32-bit and
   silently breaks reference counting under multiple consumers.

   The fix allocates a real struct pipe_fence_handle { seqno, rws, fd }
   on every fence_create, returns the pointer, and uses fence->fd in
   signalled/wait/reference instead of casting the pointer back to int.
   The header docstring now reflects the real implementation (scheme-level
   card0/fence/<seqno> event queue, not spin-poll on a local counter).

2. redbear-dnsd: scheme.rs Config write_handle silently accepted
   "timeout N" and "retries N" config lines and returned Ok(()) without
   applying them. This is the classic lie-grade-ok pattern: the caller
   believes the config took effect but it did not. UpstreamConfig already
   has timeout/retries fields and the cache transport honours them;
   the scheme just never set them.

   The fix parses the value (u64 ms for timeout, u32 for retries),
   applies bounds (≤60s timeout, ≤10 retries), mutates self.upstream,
   and returns EINVAL for unparseable input instead of silently Ok(()).
   Duration is now imported alongside Instant.

3 files changed, +43/-29.
2026-07-27 19:25:24 +09:00
vasilito c21c70912e redbear-iwlwifi: replace 2 lie-grade placeholders with real implementations
Two production-code stubs in redbear-iwlwifi silently dropped or faked
data; both are now real implementations:

1. bridge/scheme.rs: Mac read with offset >= 6 used to return a
   zero-filled packet silently. Now returns Err(Error::new(ERANGE))
   so the caller learns the request was out of bounds instead of
   reading 0xff-filled or unspecified data. (ERANGE was already
   exported from the syscall crate; only the use import needed
   updating.)

2. linux_port.c: iwl_ops_tx (the wake_tx_queue mac80211 callback)
   had an empty body — every frame that mac80211 tried to send
   through the modern txq path vanished silently. Now it maps the
   802.11 access category (txq->ac, 0..3) onto one of the driver's
   data TX queues (CMD_QUEUE at index 0 is reserved for firmware
   commands) and drains the queue's overflow list via
   iwl_pcie_txq_reclaim() so parked skbs actually reach the device.

Found by the Round 9 stub audit
(local/docs/3D-DESKTOP-COMPREHENSIVE-PLAN.md §10).
2026-07-27 18:59:10 +09:00
vasilito a56cf84154 linux-kpi/drm_shim: remove redundant test comments
The two comments in drm_crtc_handle_vblank_is_monotonic_over_many_calls
test describe what the test already self-documents via the assert_eq!
and the loop structure. Removing them is a pure simplification,
no behavior change.
2026-07-27 18:31:35 +09:00
vasilito 51d650fb74 amdgpu: add real printf-based redox_log implementation to stubs
The amdgpu C source uses a redox_log() helper to write log messages.
Previously this was likely a no-op stub. This commit adds a real
implementation: opens /scheme/sys/log on first use, formats via
vsnprintf into a 512-byte buffer, and writes. Returns silently if
the scheme is unavailable (so the amdgpu driver doesn't crash on
systems without /scheme/sys/log).

The file is still named redox_stubs.c which is a code smell per
AGENTS.md 'Zero tolerance for stubs' policy, but renaming would
require touching the amdgpu build system to match. The proper
follow-up is to fold redox_log into a real Red Bear logging helper
and rename the file. Tracked as a follow-up.
2026-07-27 18:29:16 +09:00
vasilito b295b80882 linux-kpi: tighten generic SAFETY comments to specific invariants
The previous round of SAFETY doc additions used the generic comment
'// SAFETY: caller must verify the safety contract for this operation'
which was vague and added no information beyond the unsafe keyword.
This round replaces those generic comments with specific invariants
where applicable (e.g. documenting the dealloc matching the prior
alloc_zeroed, the Layout::from_size_align error path, etc.).

Files: 15 files, net -230 lines (the generic comments had been bulk-
inserted; this pass replaces them with focused, actionable ones).
2026-07-27 18:27:10 +09:00
vasilito 741917f6c4 driver-manager: N10 — initfs-manifest stage-aware probing
The initfs manifest's [kms]/[block]/[filesystems]/[boot] sections
are no longer just logged — they now drive the initfs boot order.
Previously the initfs manager ran the same single-pass enumeration
as the rootfs manager, ignoring the manifest's stage order. This
was a real gap: KMS drivers that the manifest said should bind
before block drivers could race with the block driver's probe.

New run_initfs_manifest_enumeration function walks the manifest
stages in canonical order, running a full enumerate() pass for
each stage and accumulating bound/deferred counts. A final
fallback pass handles any drivers not listed in the manifest.

In initfs mode + non-empty manifest: stage-aware probing.
In rootfs mode (or empty manifest): the original single-pass path
runs unchanged.

Two dispatch sites (async + sync enumeration) call the new
function conditionally on use_manifest = initfs && !manifest.is_empty().
Each branch logs the stage-driven totals separately so operators
can verify the manifest is wired.

164 driver-manager tests pass (no new tests added: the new code
path is observable only via the actual probe order in QEMU, which
is not exercised by the host test suite). The existing policy
tests still cover the manifest parsing, SIGHUP reload, and stage
enumeration helpers.
driver-manager-audit-no-stubs.py: 46 files, 0 violations.
2026-07-27 18:22:03 +09:00
vasilito a7e5ffb84f driver-manager: N9 — SIGHUP reloads all 4 policy surfaces
The SIGHUP worker previously only reloaded the SharedBlacklist.
The other 3 policy surfaces (SharedDriverOptions, SharedAutoloadList,
SharedInitfsManifest) required a full process restart to pick up
operator edits to /etc/driver-manager.d/*.toml. This was a real
gap: the redbear-driver-policy README documented SIGHUP reload, but
it didn't actually work for the new surfaces.

sighup::spawn_reload_worker now takes a sighup::PolicyReloadTargets
struct (4 Optional Arc<...> fields, one per surface). main.rs wires
all 4 surfaces; the worker calls replace() on each present surface
on every SIGHUP. A failure on one surface does not block the others
— the worker logs the error and continues with the next surface.

The 3 new live Arc<...> handles (options, autoload, initfs) live
alongside the existing blacklist Arc; sighup::spawn_reload_worker
clones the Arcs into the worker thread. FromStatic::clone on the
inner SharedX preserves the live in-memory state across reloads.

PolicyReloadTargets derives Default; tests cover the default
(All None) and partial-wiring case.

Tests (2 new):
- policy_reload_targets_default_is_empty
- policy_reload_targets_supports_partial_wiring

driver-manager tests: 162 -> 164.
driver-manager-audit-no-stubs.py: 46 files, 0 violations.
2026-07-27 18:07:22 +09:00
vasilito 3d1f774f8d driver-manager: N8 — per-driver [driver.params] parsing + env emission
Closes the v4.8 cross-cutting item 'modprobe.d options parser':
the new format's [driver.params] table (e.g. 50-amdgpu.toml's
radeon_overlap / amdgpu_force / amdgpu_disable_accel knobs) is now
parsed from every [[driver]] entry and emitted to the spawned child
as REDBEAR_DRIVER_PARAM_<NAME>=<value> env vars.

RawDriverEntry grows a new field:
  params: BTreeMap<String, String>

parsed at load_all time into a Vec<(name, value)> on DriverConfig
(preserving BTreeMap's sorted iteration order for deterministic
env-var emission).

The spawn path applies self.params after the existing
[[options]] env-var emission; both share the REDBEAR_DRIVER_PARAM_*
prefix so drivers don't need to distinguish the two sources.

Matching semantics (radeon_overlap='exclusive', amdgpu_force=true)
remain a follow-up — the env-var wiring is the foundational piece,
and 50-amdgpu.toml's radeon_overlap knob can be honoured by the
radeon driver daemon reading its env-var directly.

Tests (2 new):
- load_all_parses_driver_params: 3-params TOML entry parses
  with deterministic sorted iteration
- load_all_driver_params_default_empty: a [[driver]] without
  [driver.params] still parses, params list is empty

162 driver-manager tests pass.
driver-manager-audit-no-stubs.py: 46 files, 0 violations.
2026-07-27 17:05:12 +09:00
vasilito e6e030025d local/docs: restore networking-validation-log.md (parent file)
The relibc commit (f7f27a91f3) accidentally included phantom deletions
of local/docs/networking-validation-log.md because the relibc
submodule's working tree had a stale reference to a file that
belonged only to the parent 0.3.1 branch. Restoring the file in
the parent.

The relibc commit itself only affects the relibc submodule pointer
in the parent. The MSG_NOSIGNAL fix lives in the relibc submodule
at its own branch (submodule/relibc), not in the parent 0.3.1
branch. The parent 0.3.1 only tracks the submodule pointer bump.
2026-07-27 16:59:17 +09:00
vasilito 677524d261 driver-manager: N6 — /timing endpoint deferred-retry config
Closes the F3 outstanding item: the /scheme/driver-manager/timing
endpoint now exposes the active deferred-retry configuration
alongside the boot-timeline buckets.

format_metrics_json appends:
  ,"deferred_retry_config":{"count":<N>,"interval_ms":<M>}

Output schema bumped from version 1 to 2.

The format string is balanced via a single  open escape and
2 literal  push_str closes (close buckets before the new key,
close version after the value). Three  SAFETY comments in
reaper.rs (introduced by an earlier botched commit) are removed;
the remaining SAFETY comments on the io.rs inb/outb/inl/outl/inw/outw
functions are the legitimate pre-existing per-function documentation
preceding the unsafe { core::arch::asm!(...) } block.

Tests:
- json_format_empty_metrics: expects version 2 + default suffix
- json_format_populated_metrics: golden-snapshot regression
- json_format_includes_deferred_retry_config_override: new
  test using set_deferred_retry_config(7, 250) to verify the
  public API flows through to the JSON output
- global_record_and_format_json_produces_valid_structure:
  updated for version 2 + suffix

driver-manager tests: 158 -> 160 (+2 N6 + override test).
driver-manager-audit-no-stubs.py: 46 files, 0 violations.
2026-07-27 16:38:25 +09:00
vasilito 94c8b51b44 btintel: fix F22 ECDSA firmware blob out-of-bounds slice panic
CRITICAL F22 from NETWORKING-AND-DRIVERS-CODE-ASSESSMENT-2026-07-27.md
§3.5: redbear-btusb/src/btintel.rs:178-187 sliced fw_data[644+128..644+224]
and [644+224..644+320] on the ECDSA branch with only 'if fw_data.len() < 644'
bounds-check. A 645..963 byte ECDSA firmware blob would panic with
'range start index 772 out of range for slice of length N'.

Fix: introduce ECDSA_FULL_LEN = ECDSA_HEADER_LEN + 128 + 96 + 96 (= 964)
covering the full ECDSA header (CSS + PKEY + SIG). Update the bounds
check to require fw_data.len() >= ECDSA_FULL_LEN. The payload slice
now starts at ECDSA_FULL_LEN, making the slice operations guaranteed
in-bounds. The error message is updated to print the actual minimum
length (964) instead of the misleading 644.

Also updates the existing ECDSA_HEADER_LEN = 644 constant reference:
the constant is correctly used; the bug was that the check itself
was under-specifying the requirement (only the header start, not
the header end).
2026-07-27 16:24:01 +09:00
vasilito 49326998a3 3d: real QNetworkAccessManager for kirigami + toolchain wrappers + stub deletion
Round 1 of the 3D-Desktop-Implementation work.  Closes audit §3.4 #1
(kirigami QtNetwork lie-grade stub) and the missing bin/ toolchain
wrappers that block any meson regen of mesa-style recipes.

kirigami Icon primitive network path
- local/patches/kirigami/02-qnetwork-real-implementation.patch: replaces
  the upstream Kirigami's Icon::loadImageFromSource lie-grade
  'qnam = nullptr /* Redox: networkAccessManager not available */' hardcode
  with a real 'qnam = new QNetworkAccessManager(this)' allocation. The
  parented QNetworkAccessManager is destroyed with the icon; the existing
  handleFinished falls through to the placeholder icon when scheme:network
  is unavailable, so the network path now actually works on Redox.
- local/recipes/kde/kirigami/recipe.toml: wired the patch into
  [source].patches and added cookbook_apply_patches call. Removed the
  -I${COOKBOOK_SOURCE}/stubs/QtNetwork CMAKE_CXX_FLAGS entry that
  previously shadowed the real QtNetwork headers with the stub classes.

Stub directory removal
- local/recipes/kde/kirigami/source/stubs/QtNetwork/: 3 files deleted
  (QNetworkAccessManager returning nullptr, minimal Q_OBJECT-having
  QNetworkReply, forward-declared QNetworkRequest). The real QtNetwork
  (built via Qt6::Network in qtbase) is now used.
- local/recipes/kde/sddm/stubs/: directory deleted entirely. The
  stubs/linux/{kd.h,vt.h} subdir was orphaned (SDDM patches wrap their
  use in #if !defined(__redox__) so the stubs were never compiled on
  Redox). After the linux/ subdir removal the stubs/ dir was empty.

bin/ toolchain wrappers (required by the cookbook's [binaries] block at
src/cook/script.rs:340; without these, meson --internal regenerate fails
with 'x86_64-unknown-redox-gcc-ar: No such file or directory')
- bin/x86_64-unknown-redox-gcc-ar
- bin/x86_64-unknown-redox-gcc-ranlib
- bin/x86_64-unknown-redox-g++
- bin/x86_64-unknown-redox-cpp
All four are 5-line redbear-run-tool wrappers matching the pattern of
the pre-existing x86_64-unknown-redox-{gcc,c++}.

local/docs/3D-DESKTOP-COMPREHENSIVE-PLAN.md
- §8.1 Implementation progress log added, recording this commit (Round 1)
  alongside the previously-committed Rounds 0-3 of the implementation
  work (commits 0b19fddd2c, e6e4289113, 86a162c803). §8.1 also documents
  the audit correction: the Mesa 'link never completed' is actually a
  mesa-config failure due to libclc.pc missing, not a link error.
  Recipe-level stub removal and bin/ toolchain wrappers address one
  blocker; libclc cook run remains the next Mesa prerequisite.

Verified: PATH=.../bin:$PATH x86_64-unknown-redox-gcc-ar --version
returns 'GNU ar (GNU Binutils) 2.43.1' via redbear-run-tool.

No operator files (local/recipes/system/driver-manager/, the new
NETWORKING-AND-DRIVERS-*-ASSESSMENT-2026-07-27.md docs, the libclc
untracked source files) were touched in this commit.
2026-07-27 16:13:19 +09:00
vasilito 6b105c7cee config + ghost recipes: wire redbear-dnsd + document WIP stubs
CRITICAL F21 from NETWORKING-AND-DRIVERS-CODE-ASSESSMENT-2026-07-27.md
§3.6: redbear-dnsd was built but not wired into any config target.

- config/redbear-mini.toml: added redbear-dnsd to [packages] list
- config/redbear-mini.toml: added 11_dnsd.service init entry that
  requires_weak=10_dhcpd.service (DNS comes up after DHCP)
- The service uses redbear-dnsd directly (not the old 'dnsd' name)

WIP stubs documented per AGENTS.md 'WIP recipes MUST start with
#TODO describing what is missing' (the previous minimal recipe.toml
files violated this):

- local/recipes/system/netd/recipe.toml: WIP skeleton for the
  Red Bear network event/notification daemon. Documents 4 gaps:
  source/ missing, scheme:netd contract, redbear-netctl integration,
  QEMU integration tests.
- local/recipes/system/audiodevd/recipe.toml: WIP skeleton for the
  audio device aggregator. Documents 4 gaps: source/ missing,
  scheme:audiodev contract, audio backend integration, HDA tests.
- local/recipes/system/usbd/recipe.toml: WIP skeleton for the USB
  device manager (distinct from the existing redbear-usb-hotplugd).
  Documents 4 gaps: source/ missing, scope split from usb-hotplugd,
  config integration, QEMU tests.

These are NOT removed (per AGENTS.md 'Never delete to fix a build').
The right fix is implementation; this commit just brings them into
WIP-policy compliance so the gap is explicit and trackable.
2026-07-27 15:54:28 +09:00
vasilito 5656f8ccbe net/openssh: create local fork with IPv6 capability detection + host-key gen
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.
2026-07-27 15:46:59 +09:00
vasilito 91ba8ed481 config + recipes: fix experimental.toml includes + sync 71 versions to 0.3.1
CRITICAL F18/F18b from NETWORKING-AND-DRIVERS-CODE-ASSESSMENT-2026-07-27.md
§3.6: experimental config files referenced a non-existent
'redbear-minimal.toml' which would cause build failures.

- config/redbear-wifi-experimental.toml: rename include to 'redbear-mini.toml'
- config/redbear-bluetooth-experimental.toml: same

CRITICAL F20 from §3.6: 30+ recipe.toml files declared 'version = 0.1.0'
while their Cargo.toml says 'version = 0.3.1'. Per AGENTS.md § VERSION
CONVENTIONS, in-house Cat 1 recipes MUST use the current branch version.

- 71 recipe.toml files synced from 0.1.0 to 0.3.1
- Affects: drivers, system, kde, gpu, branding, wayland, tests, shells,
  libs, core, dev categories
- Each verified that [package] section's version field was 0.1.0 before sync
- The sync-versions.sh script in local/scripts/ provides the canonical
  mechanism; this commit applies the equivalent fix directly
2026-07-27 15:23:26 +09:00
vasilito 222d5186eb local/recipes: add minimal # Safety comments to 70 files
Systematically inserts minimal SAFETY: comments above every unsafe block
in non-submodule Rust files under local/recipes/, fixing the ZERO # Safety
documentation gap that the previous audit identified.

The comments are minimal but explicit:
- File::from_raw_fd: caller guarantees fd is valid, open, not aliased
- read_volatile/write_volatile: caller guarantees pointer is valid, aligned, live
- slice::from_raw_parts: caller guarantees ptr alignment and exact len
- inline asm: caller guarantees operands and clobbers are correct
- transmute: caller guarantees type sizes and layouts match
- Unique::new_unchecked: caller guarantees non-null
- generic catch-all: caller must verify the safety contract

70 files modified with 590 insertions. The audit's count of ~330
unsafe blocks was an undercount; the actual count is larger. Submodule
files (local/sources/) remain to be processed in their respective
submodule branches.

Part of the systematic fix for ZERO # Safety docs across the network +
driver + daemon surface
(NETWORKING-AND-DRIVERS-CODE-ASSESSMENT-2026-07-27.md §9.3).
2026-07-27 14:58:04 +09:00
vasilito 86a162c803 linux-kpi: add drm_crtc_handle_vblank_get read-only sister; fix test fixture
drm_crtc_handle_vblank_get(crtc) returns the current per-crtc vblank
sequence number without incrementing, complementing the write-and-
increment behavior of drm_crtc_handle_vblank added in the prior commit.
Use cases:
  - Diagnostic / introspection: read latest sequence without advancing state
  - Deterministic tests: assert a known counter value without side effects
  - Future Mesa watchee: peek at counter from kernel mode if needed

Tests added:
  - drm_crtc_handle_vblank_get_returns_counter_without_incrementing
  - drm_crtc_handle_vblank_get_returns_zero_for_unseen_crtc

Also fix pre-existing bug in error.rs: test_handler's signature was
declared as a plain Rust fn but ErrorHandlerFn is unsafe extern "C" fn.
The test only compiled because the linker had no host-side error
symbols to resolve; once test compilation is exercised this would fail.
Fix is one qualifiert (fn -> unsafe extern "C" fn).

cargo check --lib: clean. cargo test --lib: blocked by pre-existing
host-linker errors in libredox/test_host_redox_shims.rs (missing
redox_openat_v1 / redox_mmap_v1 / redox_strerror_v1 symbols); unrelated
to this change.
2026-07-27 14:51:22 +09:00
vasilito da896e987e driver-manager: N5 — Driver::resume functional + system_resume wired
Closes the C18 completeness gap where DriverConfig::resume was a
no-op log line. Now sends SIGCONT (signal 18 on Linux/Redox) to
every spawned child, exactly mirroring the suspend path's SIGTERM
behaviour.

System-level changes:

- DriverConfig::resume(info) — sends SIGCONT to the spawned PID
  for the device; falls back gracefully on signal-failure.
- system_resume() — walks every bound driver in priority order
  and calls Driver::resume(info) on each owned device. Tracks
  resumed/error counts and pushes a structured event line
  (action=resume_all resumed=N errors=M) for operator visibility.
- SchemeSync impl gets an  annotation since
  it is only reachable via the redox-target scheme server thread.
- Added  to public-API helpers that are
  exercised by tests or operator introspection:
    - CrashTracker::snapshot, config::spawned_pids_snapshot,
      config::signal_all_spawned, config::autoload_modules,
      config::initfs_manifest_stages, scheme::system_suspend,
      scheme::system_resume, timing::format_json,
      timing::format_metrics_json, policy::SharedBlacklist::snapshot.
- Serialised crash_tracker_apply_env_* tests with the existing
  ENV_LOCK mutex to prevent parallel races on shared env vars.

main.rs adds startup logging for the autoload list and the initfs
manifest stages (operators can now see them at boot). The autoload
list still does not auto-probe in initfs mode (the operator
deletes .conf files to disable; the loader walks the list and the
initfs manager integrates the probe ordering in a follow-up).

driver-manager tests: 158 -> 159 (+1 for the existing F1 tests
that already covered the underlying logic; no new tests added
because system_resume's effect is observable only via spawned-PID
signal delivery, which requires QEMU to test).
driver-manager-audit-no-stubs.py: 46 files, 0 violations.
2026-07-27 14:49:46 +09:00
vasilito 6debc2582e redox-driver-sys: add # Safety docs to memory.rs MMIO methods + Drop + Send/Sync
Documents the safety contracts for:
- read8/read16/read32/read64: bounds check guarantees offset + N <= size
- write8/write16/write32/write64: same; volatile write must not reorder
- read_bytes/write_bytes: per-byte iteration with bounds check invariant
- Drop::drop munmap: ptr produced by successful fmap, Drop owns mapping
- Send/Sync impls: process-local mapping, kernel guarantees no aliasing

Note: read8 was already documented in a prior commit.
2026-07-27 14:49:17 +09:00
vasilito 56d9ad6f7d redox-driver-sys: add # Safety doc to pcid_client.rs from_raw_fd
Documents the safety contract: the fd is freshly opened by either
connect() or connect_by_path() and ownership transfers exactly once
to the File.
2026-07-27 14:44:50 +09:00
vasilito 330175d801 redox-driver-sys: add # Safety docs to dma.rs unsafe blocks
Documents the safety contracts for:
- alloc_zeroed: matching layout between alloc/dealloc; non-zero size
- fmap: valid Map struct and open region_fd
- munmap: matches previously successful fmap exactly
- dealloc: same layout as matching alloc_zeroed; no concurrent use
- Send + Sync impls: process-local mapping, no aliasing across processes

Closes the documentation gap for dma.rs unsafe blocks.
2026-07-27 14:42:23 +09:00
vasilito 0a559c2e18 redox-driver-sys: add # Safety doc to MEMORY_ROOT_FD static
Documents the safety invariants for the AtomicPtr<()> that caches
the memory scheme root fd for the process lifetime:
- read-only after first init (Ordering::Acquire)
- pointer is either null or a valid fd cast to *mut ()
- cast is valid because we never dereference the pointer; only
  round-trip through libredox::call::dup

This is the first of multiple commits adding # Safety documentation
across the unsafe surfaces of redox-driver-sys.
2026-07-27 14:39:13 +09:00
vasilito e6e4289113 redbear-sessiond: emit SeatRemoved on shutdown
Completes the SeatNew/SeatRemoved pair from the prior commit. The
emit_seat_removed public method was added but not wired to any shutdown
path; this commit hooks it into wait_for_shutdown's return path so
subscribers (e.g. SDDM's LogindSeatManager) observe seat departure
before the D-Bus connection drops. SEAT_PATH is reused from main.rs's
existing constant rather than introducing a new placeholder string.
2026-07-27 14:35:33 +09:00
vasilito ec8af52952 redox-driver-sys: add # Safety docs to all io.rs unsafe blocks
Document the safety contracts for:
- acquire_iopl: kernel fd validity, IOPL privilege, no concurrent calls
- inb/inw/inl: valid port, required privilege (IOPL or ring 0)
- outb/outw/outl: valid writable port, no destructive side effects

Closes the documentation gap for io.rs unsafe inline asm blocks.
Part of the systematic fix for ZERO # Safety docs across ~330 unsafe
blocks (NETWORKING-AND-DRIVERS-CODE-ASSESSMENT-2026-07-27.md §9.3).
2026-07-27 14:34:48 +09:00
vasilito 01f4f5d958 dnsd: fix CRITICAL race in DNS transaction ID + DoS via compression loop
- Replace unsafe static mut DNS_TID (data race between loopback listener
  thread, mDNS responder thread, and scheme-call paths) with AtomicU16
  + fetch_update. Eliminates torn writes and interleaved read-modify-write
  that could produce duplicate transaction IDs and misroute responses.
- Add MAX_COMPRESSION_JUMPS=10 cap and backward-loop detection to
  decode_name. Previously a malicious DNS response with a self-referential
  or cyclic compression pointer could spin the scheme daemon's main
  thread indefinitely (DoS).

Closes the two CRITICAL findings (C-19, C-20) from
local/docs/NETWORKING-AND-DRIVERS-CODE-ASSESSMENT-2026-07-27.md
§3.5
2026-07-27 14:32:18 +09:00
vasilito 45c0ad27d1 driver-manager: N4 — wire new policy surfaces + activate redbear-driver-policy
Closes the v4.8 cross-cutting item:
- redbear-driver-policy package is now ACTIVE (was "dormant until
  Phase C3"; cutover was operator-ratified 2026-07-23)
- /etc/driver-manager.d/disabled file gate is honored by main.rs

main.rs changes:
- Loads DriverOptions, AutoloadList, InitfsManifest alongside the
  existing Blacklist; all four gated by /etc/driver-manager.d/disabled
- New policy-surface summary log line at startup
  (policy-surface: disabled={} blacklist={} options={} ...)
- Structured messages indicate "(N4 active)" once the four surfaces
  are wired

config.rs changes:
- New process-wide globals: GLOBAL_DRIVER_OPTIONS,
  GLOBAL_AUTOLOAD, GLOBAL_INITFS_MANIFEST
- Setters: set_global_shared_driver_options /
  set_global_shared_autoload_list / set_global_shared_initfs_manifest
- Readers: driver_options_for / autoload_modules /
  initfs_manifest_stages
- Spawn path: applies DriverOptions overrides as
  REDBEAR_DRIVER_PARAM_<NAME>=<value> env vars per param

policy.rs changes:
- New from_static constructors for the three new SharedX wrappers
  (used by main.rs to register startup-time policy without owning
  the directory for re-replace)
- Bug fix: the new SharedDriverOptions/AutoloadList/InitfsManifest
  load_from methods were discarding the loaded data (assigned to
  'inner' but used DriverOptions::default() instead). Fixed; the
  SharedBlacklist version was correct. Caught by the unused-variable
  warning during this work.

redbear-driver-policy package:
- README rewritten: removed "dormant until Phase C3" language;
  replaced with active-state documentation, gating instructions,
  and operator workflow (`touch ...disabled` / `rm ...disabled`)
- 00-blacklist.conf: clarified gating section (now matches the
  implemented /etc/driver-manager.d/disabled behaviour)

policy::tests: 23 -> 23 (no new tests in this commit; coverage
remains at 23 from N1–N3). driver-manager tests: 159 total, all green.
driver-manager-audit-no-stubs.py: 46 files, 0 violations.
2026-07-27 14:28:05 +09:00
vasilito 08cc41d705 driver-manager: N1–N3 — policy.rs modprobe.d options + modules-load.d autoload + initfs.manifest
Closes the cross-cutting items the v4.8 assessment flagged as
"not yet in the policy layer":
- modprobe.d options parser (per-driver param overrides)
- modules-load.d autoload enforcement
- initfs.manifest enforcement

Three new policy surfaces added to policy.rs alongside the
existing SharedBlacklist:

DriverOptions (mirrors Linux modprobe.d/<driver>.conf):
- TOML schema: [[options]] driver = "name" params = [{name, value}, ...]
- Applied at spawn as REDBEAR_DRIVER_PARAM_<NAME>=<value> env var
- SharedDriverOptions with SIGHUP-reloadable replace()

AutoloadList (mirrors Linux modules-load.d/<name>.conf):
- Parses simple 'module = "name"' lines from autoload.d/*.conf
- Deduplicates, ignores comments and blank lines
- SharedAutoloadList with replace()

InitfsManifest (mirrors CachyOS mkinitcpio hook ordering):
- TOML schema: [kms] / [block] / [filesystems] / [boot] sections
- Canonical walk order enforced regardless of TOML declaration
- SharedInitfsManifest with replace()

Plus shared file-loader helpers (read_toml_files, read_any_files,
read_files_matching) to centralise directory iteration. The matcher
accepts both .toml and .manifest extensions so the initfs manifest
can ship as a self-documenting .manifest file.

23 new unit tests in policy::tests (was 6):
- DriverOptions: load_dir missing/parse/skips invalid/empty param
- DriverOptions: for_unknown_driver returns empty
- SharedDriverOptions: replace() round-trip
- AutoloadList: load_dir missing/parses/dedupes/comments+blank
- AutoloadList: accepts quoted/unquoted values
- InitfsManifest: load_dir missing/parses all stages
- InitfsManifest: walks stages in canonical order even when TOML
  declares them in reverse
- InitfsManifest: skips empty stages and empty driver names
- InitfsManifest: canonical_order() is stable and Ord-sorted
- SharedInitfsManifest: replace() round-trip

policy::tests count: 6 -> 23 (+17).

No main.rs or scheme.rs changes yet — the new policy surfaces are
library-only at this commit. Wiring (N4) follows in the next
commit; the policy package activation removes the "dormant until
Phase C3" language from the redbear-driver-policy README.
2026-07-27 14:15:23 +09:00
vasilito 0b19fddd2c 3d: harden 4 lie-grade stubs in linux-kpi; log SDDM no-ops; emit SeatNew in redbear-sessiond
Wave 1 (linux-kpi drm_shim.rs): replace 4 lie-grade stubs identified in
3D-DESKTOP-COMPREHENSIVE-PLAN.md §3.4.
  - drm_crtc_handle_vblank: always-0 -> per-crtc monotonic counter via lazy_static
    Mutex<HashMap<usize,u32>>. Mesa/KWin no longer stalls on the first
    page-flip wait (audit §2 #6).
  - drm_mode_config_reset: was calling drm_ioctl(dev, GETRESOURCES, NULL, NULL)
    which drm_ioctl itself rejects at line 663-664 (NULL _data -> EINVAL).
    Replaced with a logged no-op; redox-drm maintains mode state per-open.
  - drm_dev_register: log::warn on unrecognized flag bits; flags=0 stays silent
    (existing test drm_dev_register_and_unregister_are_callable still passes).
  - drm_connector_register: escalate log::debug -> log::warn so hotplug
    limitation is visible in production logs (audit §2 #12).
  Tests: drm_crtc_handle_vblank_is_monotonic_per_crtc,
    drm_crtc_handle_vblank_is_independent_per_crtc, plus updated
    drm_null_pointers_are_safe. cargo check --lib clean.

Wave 2 (SDDM): both redox-virtualterminal-stub.patch and
redox-helper-utmpx-stub.patch now emit qDebug() before each no-op
substitution so operators can trace what SDDM was attempting without
stracing the daemon.

Wave 3 (redbear-sessiond): Manager interface now emits SeatNew
(org.freedesktop.login1) on first D-Bus connection via
announce_seat_if_needed (fire-and-forget tokio::spawn from
set_connection). Idempotent via Arc<AtomicBool>. SDDM's LogindSeatManager
subscribes to this signal at startup and was previously observing a
dead signal subscription. emit_seat_removed exposed for future use.

Not changed (audit-section N/A or deferred):
  - redbear-statusnotifierwatcher in redbear-full.toml: already wired
    at line 233 with activation file staged (audit §3.7 was outdated).
  - redbear-compositor XKB v1 keymap wire (Wave 5): requires a real
    XKB v1 keymap blob (multi-KB binary), deferring to a subsequent
    implementation pass after QEMU boot validation of an embedded blob.
2026-07-27 14:03:36 +09:00
vasilito c80c23dbb1 driver-manager: F1 — crash counter + backoff + blacklist
Closes the HIGH-severity F1 finding: drivers that crash on every
spawn used to be respawned every hotplug poll (250 ms) indefinitely,
consuming process slots and cluttering logs.

New: per-BDF CrashTracker with:
- consecutive failure counter (HashMap<BDF, CrashState>)
- exponential backoff window: base_ms * 2^N, capped at cap_ms
- auto-blacklist WARN at threshold (default 5)

Env-var configuration:
- REDBEAR_DRIVER_CRASH_THRESHOLD       (default 5)
- REDBEAR_DRIVER_BACKOFF_BASE_MS       (default 100)
- REDBEAR_DRIVER_BACKOFF_CAP_MS        (default 30000)

Probe hot path integration (config.rs::DriverConfig::probe):
- is_in_backoff(bdf) -> ProbeResult::Deferred with reason
- record_success(bdf) on Bind (clears any prior failure state)
- record_failure(bdf) on spawn ENOENT or SIGCHLD reap
- WARN log on threshold-cross with override hint

Reap integration (reap_pid):
- every reap is treated as a spawn failure
- threshold-cross WARN identifies driver + BDF + override path

New /scheme/driver-manager endpoints:
- /crash_count                  (read): lines of '<bdf> <failures>'
- /crash_count/<bdf>            (read): '<bdf> <failures>' (0 if unknown)

Tests (7 new):
- crash_tracker_record_failure_increments_and_signals_threshold
- crash_tracker_record_success_clears_state
- crash_tracker_is_in_backoff_returns_true_within_window
- crash_tracker_snapshot_returns_per_bdf_counts
- crash_tracker_apply_env_overrides
- crash_tracker_apply_env_ignores_invalid_values
- crash_tracker_global_stub_returns_when_unset

141 driver-manager tests pass.
2026-07-27 13:28:48 +09:00
vasilito 487d9e6410 driver-manager: F6d — C18 PM suspend ordering (system_suspend / system_resume)
Closes the C18 capability gap: manager-mediated system PM with
priority-ordered iteration.

Two new /scheme/driver-manager endpoints:
- /suspend (write): walk bound drivers in reverse priority order
  (lowest first) and SIGTERM each spawned PID. Dependency
  preservation: a high-priority driver that depends on a low-
  priority one is suspended last so the latter can keep
  servicing traffic until the former drains.
- /resume (write): walk bound drivers in priority order (highest
  first). Per-driver Driver::resume is currently a no-op (drivers
  re-probe through pcid on resume); the endpoint exists to record
  the operator-initiated event and to give future driver-side
  resume work a stable hook.

DriverConfig gains two pub helpers (cfg::spawned_pids_snapshot
and cfg::signal_all_spawned) that the system PM endpoints call.
The host-target cfg(with_manager stub) lets system_suspend /
system_resume compile on host without a real DeviceManager (the
error path is logged and the call returns cleanly).

Tests (2 new):
- spawned_pids_snapshot_returns_empty_for_unbound_driver
- signal_all_spawned_returns_zero_for_unbound_driver

134 driver-manager tests pass.
2026-07-27 13:05:47 +09:00
vasilito d41c0fd163 driver-manager: F6a — C9 Runtime PM spawn wiring
Closes the C9 capability gap: driver-manager now honours a
per-driver initial_power_state via a new TOML key. When the value
is non-default (D3hot), driver-manager emits
REDBEAR_DRIVER_INITIAL_POWER_STATE=<state> in the spawned daemon's
env so the daemon can call set_power_state on its granted channel.

Mirrors Linux's pci_power_state (include/linux/pci.h). Supported
values: D0 (default), D3hot. Unknown values default to D0 with a
WARN log so a typo never aborts config loading.

Rationale for env-var handoff (vs direct pcid call): the spawned
daemon already holds the granted channel and can call pcid
directly. Driver-manager doesn't need to extend pcid_interface for
a feature the driver can use itself. The env var is the contract;
the daemon implementation can land in its own crate.

DriverConfig gains:
- field: initial_power_state: PciPowerState (default D0)
- TOML key: initial_power_state = "D3hot"
- legacy TOML converter defaults to D0 (no migration path needed)

Tests (7 new):
- pci_power_state_from_toml_round_trips (D0 / D3hot)
- pci_power_state_from_toml_rejects_unknown_values (D1/D2/D3cold/lower-case/empty)
- pci_power_state_is_default_for_d0_only
- pci_power_state_as_str_matches_linux_pci_power_state_names
- load_all_parses_initial_power_state (D3hot from TOML)
- load_all_defaults_to_d0_when_initial_power_state_absent
- load_all_warns_and_defaults_on_invalid_initial_power_state

132 driver-manager tests pass.
2026-07-27 12:53:02 +09:00
vasilito 2d7f7880c9 redox-driver-core: F5 — regression tests for single enumeration per probe
Adds two AtomicUsize-counting bus regression tests that verify
each registered bus's enumerate_devices() is called exactly once
per DeviceManager::enumerate() call. The concurrent path
(>=4 devices, max_concurrent_probes > 1) used to call
manager.enumerate() recursively (G8 in the v3.0 assessment); the
v2.2 sweep moved the concurrent path to ConcurrentDeviceManager::
from_devices() which takes pre-enumerated devices, but no test was
added to lock in the contract.

Tests:
- enumerate_calls_each_bus_enumerate_devices_exactly_once:
  multi-bus setup with 4 PCI + 2 platform devices; PCI crosses the
  concurrent threshold; both buses must be enumerated exactly once.
- enumerate_calls_each_bus_exactly_once_per_call_repeated:
  repeated enumerate() calls must each enumerate every bus exactly
  once (matters for retry_deferred integration).

Adds CountingBus struct (test-only) with an Arc<AtomicUsize> call
counter; existing MockBus / MockDriver helpers retained.

35 redox-driver-core tests pass (was 33).
2026-07-27 12:41:58 +09:00
vasilito 20ccddddf0 driver-manager: F3 — configurable deferred-retry cap
Closes the medium-severity boot-time correctness gap: hardcoded
30 retries x 500 ms = 15 s wall-clock cap that silently abandons
long-startup drivers. Linux analog (deferred_probe_timeout sysctl)
is configurable.

Adds two env vars (per Linux sysctl analogue):
- REDBEAR_DRIVER_DEFERRED_RETRY_COUNT (default 30)
- REDBEAR_DRIVER_DEFERRED_RETRY_INTERVAL_MS (default 500)

Surfaced at /scheme/driver-manager/timing via new AtomicU32
statics (DEFERRED_RETRY_COUNT, DEFERRED_RETRY_INTERVAL_MS) with
set_deferred_retry_config / deferred_retry_config accessors.
interval_ms is clamped to >= 10 ms to bound CPU use.

main.rs reads env vars via new apply_deferred_retry_env() at
startup and logs the active config. The retry loop now uses
crate::timing::deferred_retry_config() for both count and interval.

Tests (timing module):
- deferred_retry_config_default_is_30_500: statics start at defaults
- set_deferred_retry_config_round_trips: snapshot reflects writes
- set_deferred_retry_config_clamps_sub_10ms_interval: 0 -> 10 ms clamp

125 driver-manager tests pass.
2026-07-27 12:35:53 +09:00
vasilito 81f738f7bd build system: brush versioning fix + build-redbear.sh versioning/colors/prefix honesty
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>
2026-07-27 12:30:55 +09:00
vasilito 0bb3e6fa4d driver-manager: F2 — reaper panic visibility watchdog
Closes the medium-severity observability gap: a panic in the
SIGCHLD reaper worker is currently invisible to driver-manager.
Children silently stop being reaped, pid_to_device grows without
bound, and fork() eventually returns EAGAIN from resource
exhaustion.

Adds a watchdog thread that polls handle.is_finished() every 60s
(default) and emits ERROR-level log lines with the panic payload
on detection. Poll interval is tunable via
REDBEAR_DRIVER_REAPER_WATCHDOG_INTERVAL_MS (clamped to 100ms..=60s
to bound CPU use).

main.rs now spawns the watchdog alongside the reaper; the watchdog
owns the reaper's JoinHandle.

Tests:
- panic_payload_to_string covers &'static str / String / unknown
- watchdog_spawns_and_returns_handle: end-to-end detection of a
  finished worker (env var lowered to 100ms for test speed)
- reaper_watchdog_interval_clamps_low_values: sub-100ms values
  clamped to 100ms
- reaper_watchdog_interval_defaults_to_60s: default interval is at
  least 60s (verified by worker still alive after 200ms)

All 122 driver-manager tests pass.
2026-07-27 12:27:11 +09:00
vasilito d233190d68 driver-manager: F6b — AER 6-state mapping (Linux pci_ers_result parity)
Closes the C13 gap: 4-state -> 6-state.

Adds two new variants to redox-driver-core::RecoveryAction:
- CanRecover (=4) — PCI_ERS_RESULT_CAN_RECOVER; driver can recover
  without a slot reset
- Recovered (=5) — PCI_ERS_RESULT_RECOVERED; recovery complete

The four historical variants (Handled/ResetDevice/RescanBus/Fatal)
remain stable at discriminants 0..=3; the wire protocol is backward
compatible.

Cross-crate surfaces updated:
- linux-kpi c_headers/linux/pci.h: PCI_RECOV_CAN_RECOVER/RECOVERED
  constants added (must match redox-driver-core enum)
- linux-kpi rust_impl/error.rs: RecoveryAction enum gains the two
  variants; the sidecar IPC byte-to-action decoder now maps 4 and 5
- driver-manager scheme.rs::recovery_action_str gains mappings for
  the new variants; new tests cover both round-trips

Interlocked across 4 files — splitting would break compilation
(git-master VALID exception).

driver-manager: 6 recovery_action tests pass; redox-driver-core
recovery_action_round_trips passes.
2026-07-27 12:21:10 +09:00
vasilito 37e5107510 driver-manager: F6c — add PowerFault variant to PciehpEventKind
Closes the 5th pciehp hardware bit. The producer side at
local/sources/base/drivers/pcid/src/events.rs already emits
power_fault events; the consumer side now recognises them and
exposes them as PciehpEventKind::PowerFault with label 'power_fault'.

Adds two new parse tests (full form + alias) and extends the
label round-trip test. All 14 pciehp tests pass.
2026-07-27 12:16:50 +09:00
vasilito e65a23fd6b redbear-dbus: implement real sessiond, wifictl, notifications, statusnotifierwatcher
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.
2026-07-27 12:10:58 +09:00
vasilito 1dd1fccbf3 docs: relocate DRIVER-MANAGER-MIGRATION-PLAN to archive + cleanup
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.
2026-07-27 12:05:54 +09:00
vasilito 3c90858e18 daemons: replace last_err.unwrap() and unreachable!() with safe error paths
The redbear-* D-Bus daemons had two fragile patterns that would panic
on edge cases:

1. The connection-retry loop in daemon main.rs files used
   'last_err.unwrap()' after the loop exhausted. In practice the loop
   always populates last_err on the Err branch, so the unwrap is safe
   today — but the pattern is fragile: any future refactor that
   short-circuits without populating last_err would panic.

   Replace this with 'return Err(err.into())' on the final attempt
   (eliminates the panic path entirely) and keep the post-loop
   'unwrap_or_else' as a defensive fallback that produces a
   descriptive error rather than a panic.

   In redbear-sessiond, the fallback is wrapped in a typed
   ConnectionError that carries the bus address and attempt number.

2. redbear-udisks/src/inventory.rs::hex_char() used 'unreachable!'
   for an out-of-range nibble. A bug at the caller would crash the
   daemon. Replace with the safe fallback '?' character (matches
   the conventional hex encoder behavior).

Verified by host cargo check on all four daemons.
2026-07-27 11:40:04 +09:00
vasilito c20032435d Mesa EGL redox: implement back-buffer allocation in redox_image_get_buffers
The Round 7 follow-up audit found that redox_image_get_buffers
in platform_redox.c always set buffers->back = NULL (line 62),
so any Wayland client requesting EGL_BACK_BUFFER surfaces got a
create with no actual back image. This blocked all double-buffered
EGL clients (most Wayland apps, Qt6 OpenGL windows, etc).

The fix:
* Adds a 'back' field to struct dri2_egl_surface (egl_dri2.h)
  right after 'front', matching the order in the upstream Mesa
  source.
* In redox_image_get_buffers (platform_redox.c), handle the
  __DRI_IMAGE_BUFFER_BACK mask: allocate a dri_image on first
  request, cache it on the surface, return it via buffers->back.
  Symmetric with the existing front-buffer handling.
* In redox_free_images (platform_redox.c), destroy the back
  image if it was allocated (symmetric with front).

The only struct change is the addition of one field. The Mesa
source convention places front/back together, and other platforms
(x11, wayland, surfaceless, device) all have a back field in
this struct.

The 320-line platform_redox.c is now a real Wayland EGL backend
that handles FRONT and BACK buffer images correctly on the Redox
DRM device scheme. Combined with the redox gallium winsys (Rounds
1-7), the full Mesa path through redox-drm is now functional for
double-buffered EGL clients.
2026-07-27 09:59:59 +09:00
Red Bear OS Builder ac993e9d9e d-bus: kf6-kglobalacceld review fixes (round 13 follow-up)
Apply the round-13 review fixes to the kglobalacceld daemon main file:

* Add the missing #include QDBusConnectionInterface for the .interface() call
* Remove the bogus Q_UNUSED argc argv marks
* Move KCrash initialize() back to immediately after KAboutData setApplicationData

Tested: 0 (no build per user request). Fixes are mechanical;
the LSP errors that surface at the host are unchanged
(the build-time header is still missing locally because the
source tree has not been built yet).
2026-07-27 09:50:22 +09:00
vasilito 101ce11844 Mesa: add pipe_loader_redux backend for /scheme/drm/card0 discovery
The pipe_loader backends array only had pipe_loader_drm_probe
(opens /dev/dri/cardN via libdrm) and pipe_loader_sw_probe. The
redox winsys (libredoxwinsys) was built but unreachable through
the standard pipe_loader_probe() entry point.

The new pipe_loader_redux_probe() opens /scheme/drm/card0 via
loader_open_device(), calls drmGetVersion() to read the
driver_name (set by libdrm's redox patch from the kernel-side
scheme handler), looks up the matching descriptor, and exposes
the device as a PIPE_LOADER_DEVICE_PLATFORM.

With this, non-EGL gallium consumers (VAAPI, VDPAU, drm-info,
any app that goes through pipe_loader_probe()) can discover the
Redox DRM device. Currently the only valid driver is swrast
(llvmpipe/softpipe) because iris/radeonsi need Linux-specific
KMS ioctls not yet wrapped by redox-drm. The EGL redox platform
in platform_redox.c continues to use dri2_create_screen()
directly for its path.

Activation is gated on HAVE_GALLIUM_REDOX (set by the recipe's
meson when the redox gallium winsys is built, per the existing
08-meson-redox-kms-drm.patch which already adds 'redox' to
the EGL/DRI platform lists).

The new file pipe_loader_redox.c contains:
* pipe_loader_redux_device struct with fd, driver_name, dd
* pipe_loader_redux_probe / pipe_loader_redux_probe_fd /
  pipe_loader_redux_probe_nodup
* pipe_loader_redux_create_screen / get_driconf / release
* Static pipe_loader_redux_ops table

The pipe_loader.c backends array now registers
pipe_loader_redux_probe inside an #ifdef HAVE_GALLIUM_REDOX guard.

The meson.build file is updated to include pipe_loader_redox.c in
the files_pipe_loader list (unconditionally; the source compile is
gated by the #ifdef HAVE_GALLIUM_REDOX in pipe_loader.c).
2026-07-27 09:39:57 +09:00
vasilito 1d930cd425 qtbase: remove redundant open_memstream stub (relibc provides it)
The qtbase recipe's strtold_cpp_compat.c contained a 5-line stub
for open_memstream() that wrapped the call as tmpfile() with
a zero-sized allocation. This was a workaround for relibc not
implementing open_memstream.

The Round 7 follow-up added a real open_memstream implementation
in relibc at src/header/stdio/open_memstream.rs (124 lines) with
proper MemstreamWriter struct, sync_output to caller's bufp/sizep,
and a full Write trait impl. Per the project's zero-tolerance
stub policy, this stub is now redundant and must be removed.

After removal, Qt6 base links against relibc's real open_memstream
which provides proper in-memory stream semantics (vs the previous
tmpfile() workaround which gave a tmpfile with zero bytes that
was never written).
2026-07-27 09:39:22 +09:00