Commit Graph

193 Commits

Author SHA1 Message Date
vasilito 1720af1431 driver-manager: v1.5 — pcid_interface env-vars + observability flags
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.
2026-07-21 12:16:00 +09:00
vasilito 4dc51bd61f driver-manager: v1.3 comprehensive D-phase implementation
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.
2026-07-21 00:30:55 +09:00
vasilito 5c6cd18599 tests: fix UHCI proof marker for interpolated controller name
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).
2026-07-20 11:23:33 +09:00
vasilito ee1da17617 tests: add USB UHCI/OHCI/EHCI-autospawn/error-recovery QEMU proofs
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.
2026-07-20 10:04:56 +09:00
vasilito 6dab9b2953 tests: migrate remaining QEMU runtime proofs to qemu-login-expect.py
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.
2026-07-20 09:01:14 +09:00
vasilito cf6f363da9 tests: fix qemu-login-expect fail-marker guard, docstring flags, retry count
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.
2026-07-20 07:08:28 +09:00
vasilito 9ec00d4c81 tests: replace expect with stdlib python helper for QEMU login proofs
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).
2026-07-20 05:38:44 +09:00
vasilito 569f05debc tests: boot low-level + storage proofs from live ISO, not stale harddrive.img
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.
2026-07-20 00:14:30 +09:00
vasilito 6446d440bf usb: hub-child enumeration proven end-to-end in QEMU + tighten hub test
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.
2026-07-19 19:55:27 +09:00
vasilito 5fcb03c99b test-usb-hub-qemu: extend check timeout 180s -> 360s
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.
2026-07-19 19:43:51 +09:00
vasilito a8ca01d84b test-usb-hub-qemu: interleaving-robust grep fragments
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.
2026-07-19 10:20:05 +09:00
vasilito f87481ca6d test-usb-hub-qemu: spawn proof via descriptor-read line
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.
2026-07-19 09:46:11 +09:00
vasilito 36f1cd6193 sync-versions: exclude git-fetched upstream sources from Cat 1 sync
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.
2026-07-19 09:33:07 +09:00
vasilito 02d9986d3b versions: sync brush Cat 1 crates to 0.3.1 + hub test boots ISO
- 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.
2026-07-19 09:15:41 +09:00
vasilito ba46a4c715 base fork sync (upstream 59cf8189) + P3-B/C doc closure + hub proof script
Base fork:
- Merged upstream/main 59cf8189 (13 upstream commits) into submodule/base
  as 9bbdc2ca; 3 conflicts resolved by hand (irq_reactor.rs process_one_event
  refactor + SPURIOUS_REBOOT reapply; randd simplification + fcntl reapply;
  Makefile /dev symlink block). verify-fork-functions gate now passes for
  base. kernel (11 fns) and relibc (2 fns) remain behind upstream — tracked
  as T-7d82cf6f / T-a5699340 / T-f5b7a0ea for dedicated sessions.
- Also landed earlier: upgrade-forks.sh cd-back bug fix (7e7ef73a).

Docs:
- P3-B marked COMPLETE (premise was stale: usbhubd is interrupt-driven
  with polling fallback today).
- P3-C marked hub-side COMPLETE (PortIndicator set in event loop);
  keyboard LED sync remains P5-C scope.
- README USB/Bluetooth row upgraded from red/in-progress to reflect
  P2-A/B/C + P3-A/B/C reality.

Validation:
- New test-usb-hub-qemu.sh (P8-B): boots QEMU with usb-hub + usb-kbd
  behind it, validates usbhubd spawn, 8-port descriptor read, change-
  detection mode, HID registration behind the hub, no panics. Cannot
  run until kernel+relibc syncs unblock the image build.
2026-07-19 05:48:45 +09:00
vasilito 7e7ef73a8c upgrade-forks: fix relative fork_dir after cd into fork (cd-back bug)
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).
2026-07-19 05:38:30 +09:00
vasilito efd745c073 docs: USB/quirks/low-level doc consolidation + P2-C recovery completion
Documentation pass (staleness audit across 5 docs):

USB-IMPLEMENTATION-PLAN.md:
- P2-A marked COMPLETE (canonical 51-flag table in redox-driver-sys,
  ~85 entries, real HCIVERSION reads, BROKEN_MSI pre-gate)
- P2-C marked CORE COMPLETE: full 36-code recovery matrix documented
  (maybe_recover_transfer_error scheme.rs:559-925) with Linux xhci-ring.c
  equivalences, restart_endpoint bug fixes, known simplifications, and
  remaining P8-C injection-test scope
- Gap table corrected (quirks done, error recovery core done, PM substrate)
- P7-A corrected: HLC lives in Supported Protocol capability port_info
  DWORD, NOT HCCPARAMS1 (driver bug fixed in P2-B)
- §12 rewritten: runbook is live v3, not archived; lineage consolidated

IRQ-AND-LOWLEVEL-CONTROLLERS-ENHANCEMENT-PLAN.md:
- xHCI section rewritten: 'restored' -> hardened/gated (BROKEN_MSI
  pre-gate, quirk convergence, real HCIVERSION, handle/method agreement)
- Priority 6 refocused from 'keep path healthy' to runtime validation
  (BROKEN_MSI controller proof, event-ring under sustained load)
- 26 stale recipes/core/*/source paths -> local/sources/* fork paths
- duplicate ACPI-IMPROVEMENT-PLAN.md reference removed
- xhcid evidence class upgraded to quirk-hardened
- USB plan cross-reference added (feature ownership boundary)

QUIRKS-AUDIT.md:
- xHCI tombstone removed: lookup_xhci_controller_quirks_full is now a
  real implementation over XHCI_QUIRK_TABLE (was stub returning empty())
- 'broken TOML mappings' section marked RESOLVED (all 4 flag names now
  in PCI_FLAG_NAMES)
- Implementation-status section re-assessed: xhcid consumes 51-flag
  XhciControllerQuirkFlags in ~40 paths (was: only PciQuirkFlags)
- test inventory +38 xhci_table.rs tests

QUIRKS-SYSTEM.md:
- xhci_table.rs added to compiled-in tables inventory and file layout
- implementation status: canonical xHCI table row added (P2-A)
- driver consumption: xhcid xHCI-controller-path flag list documented

QUIRKS-IMPROVEMENT-PLAN.md:
- Task 3.1 (USB device quirks in xhcid) marked DONE (13 flags consumed)
- exit criteria 3/4/5/7 marked met; deliverables 1/3/4 completed
- reassessment summary updated for XhciControllerQuirkFlags consumption

Also: chmod +x test-xhci-irq-qemu.sh, test-msix-qemu.sh,
test-usb-storage-qemu.sh (were non-executable).

Track base pointer to 26000333 (P2-C restart_endpoint fixes).
2026-07-18 23:15:00 +09:00
vasilito fdcb2f5fbc fix: complete remaining Tier 1 messages and Tier 2 doc consolidation
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.
2026-07-18 17:44:16 +09:00
vasilito de44b9324e feat: build-system resilience (fetch retry, strict cache parse, auto_deps preserve, Tier 1 messages)
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.
2026-07-18 16:54:24 +09:00
vasilito f4ca523afd docs: update TOOLS.md for release-bump pipeline (5 new tools)
Add documentation for the 5 new release-bump tools:
- bump-release.sh (canonical orchestrator)
- check-external-versions.sh (external version reporter)
- bump-graphics-recipes.sh (map-driven graphics bumper)
- post-checkout-version-sync.sh (opt-in branch hook)
- install-git-hooks.sh (idempotent hook installer)

Bump tool count 10 -> 15, round 13 -> 14.
Apply drift fixes at lines 94-96 and 204.
2026-07-18 14:48:53 +09:00
vasilito 99e5641127 feat: release-bump pipeline + external graphics version sync
Pipeline (3 operator asks):
- bump-release.sh: canonical orchestrator (forks + sources + external)
- upgrade-forks.sh --to=<tag>: rebase forks with diverged-mode guard
- bump-graphics-recipes.sh: map-driven group-aware graphics bumps
- check-external-versions.sh: drift checker for Qt6/KF6/Plasma/Mesa/Wayland
- refresh-fork-upstream-map.sh: append-only map updater with --check
- post-checkout-version-sync.sh + install-git-hooks.sh: opt-in branch hook
- external_version_lib.py: shared version-parsing/bumping library
- external-upstream-map.toml: ~80 external package entries
- bump-fork.sh: deprecated (REDBEAR_I_KNOW_BUMP_FORK_IS_DEPRECATED=1)
- RELEASE-BUMP-WORKFLOW.md: operator runbook

Quality fixes (8 defects from two independent audits):
- blake2b stable cache keys (was hash(), non-portable)
- atomic cache writes via os.replace
- version_sort_key pre-release demotion (was sorting after finals)
- apply_ver_transform re.error tolerance
- grep || true (pipefail abort)
- cd failure detection in upgrade-forks
- sed URL escape (injection hardening)
- refresh-fork-upstream-map last-row drop fix

Doc cleanup:
- Archive 5 obsolete plans to local/docs/archived/
- Remove 14 stale/superseded docs
- Update 18 docs to reference bump-release.sh and fix inbound links
- TOOLS.md drift fixes
2026-07-18 14:45:41 +09:00
vasilito b2c174875c fix(full+build): unblock glib/mesa/libinput; close fork-staleness gap
- 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).
2026-07-18 03:36:01 +09:00
vasilito e0d62330ac kernel: track event kdup fix (tokio Runtime EINVAL root cause); build: only re-cook userspace when relibc/base change
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.
2026-07-17 21:47:32 +09:00
vasilito 333f1ac023 build: invalidate ALL relibc consumers on relibc change (bulletproof)
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.
2026-07-17 09:42:41 +09:00
vasilito d5561184f0 boot: restore mini ISO to a working login prompt + build-system fixes
Mini now boots (q35/KVM) all the way to the getty "Red Bear login:" prompt
on VT2 with zero kernel panics. Root-cause fixes across submodules + config:

- config: 00_base.service zsh->mkdir (a full shell startup hangs an init
  oneshot; the earlier 'echo/mkdir also hang' result was a silent config
  override running zsh). 00_ptyd.service notify->{scheme=pty} (ptyd signals
  readiness via its scheme fd; notify made init block on a byte forever).
- kernel: wrmsr_safe/rdmsr_safe #GP recovery so /scheme/sys/msr can't panic
  the kernel (cpufreqd's P-state MSR write #GP'd on KVM, halting the boot
  before login). base: ptyd scheme type + hwd ACPI enum -> debug (noise).
  installer: warn on config [[files]] override. relibc/bootloader: prior
  getrlimit + warning-demotion pointers.
- build-redbear.sh: fix host-fstools staleness (installer/redoxfs never
  rebuilt on source change), prefix rebuild-every-build (touch libc.a), add
  concurrent-build flock.

Submodule pointers: base 8aa8616d, installer 460d9530, kernel 155d01b1,
relibc a7663b3a, bootloader 6e119641.
2026-07-16 12:20:14 +09:00
vasilito f93f9e8ea8 build-system: add redbear-bare to dispatch + integrate + build-all
The redbear-bare target (added in 48a6f4c20b) was not registered in
the build dispatchers. Running build-redbear.sh redbear-bare
silently exited with 'ERROR: Unknown config redbear-bare'.

Fix:
- build-redbear.sh: extend the case statement + usage block + error
  message to include redbear-bare
- integrate-redbear.sh: add config/redbear-bare.toml to the configs
  array so source-tree integration picks up the bare target too
- build-all-isos.sh: include redbear-bare in the targets list

This closes the gap where the bare target existed as a config file
and as a recipe branch (REDBEAR_BARE_INITFS) but was invisible to
the build dispatch layer.

(NO AI attribution)
2026-07-15 00:40:23 +09:00
vasilito b447c22da1 build-redbear.sh + redbear-bare: wire REDBEAR_BARE_INITFS to make
Round-25 fix landed the bare initfs conditional in
recipes/core/base-initfs/recipe.toml but the cookbook does NOT parse
[build.env] sections in TOML configs. The REDBEAR_BARE_INITFS=1
env var I put in redbear-bare.toml was silently ignored.

Fix: propagate REDBEAR_BARE_INITFS through build-redbear.sh's make live
invocation. When CONFIG=redbear-bare and the operator has not already
exported REDBEAR_BARE_INITFS, auto-set it to 1 so the bare initfs
branch is triggered. Also propagates any pre-existing REDBEAR_BARE_INITFS
through the make call (override-only).

Also rewrote the [build.env] section in redbear-bare.toml to a
comment-only section explaining the dispatch mechanism, since the
cookbook parser ignores it.

(NO AI attribution)
2026-07-14 23:39:18 +09:00
vasilito e462d576f4 build-redbear.sh: enforce submodule/<name> branch on every fork worktree
Per local/AGENTS.md § "BRANCH AND SUBMODULE POLICY (ABSOLUTE)":\neach Red Bear fork worktree must be on the canonical\n"submodule/<name>" branch. Until now, the build system had NO\ncode enforcing this — drift was caught only by operator discipline\n(Round-21 hand-normalized 6 of 9 forks).\n\nAdd a new redbear_check_fork_branches() function called as a peer of\nthe existing dirty-source gate. It iterates REDBEAR_FORK_SOURCES,\nreads each fork worktree's current branch via 'git branch\n--show-current', and compares to 'submodule/<label>'. On mismatch\nthe build aborts with a clear error message and a documented fix\nrecipe. Escape hatch: REDBEAR_ALLOW_WRONG_BRANCH=1.
2026-07-14 13:00:52 +09:00
vasilito 137da99644 scripts/bump-fork.sh: derive BRANCH_VERSION from git branch
The script uses '${BRANCH_VERSION:-0.0.0}' as the +rb suffix when
bumping a fork to a new upstream version. BRANCH_VERSION was never
set, so any fork bump would have produced 'X.Y.Z+rb0.0.0' instead
of the correct 'X.Y.Z+rb0.3.2' (or whichever branch is current).

Derive BRANCH_VERSION from 'git branch --show-current' using the same
pattern as local/scripts/build-redbear.sh:158-165. Falls back to
'0.0.0' if the branch name doesn't match semver (e.g., on 'master').

(NO AI attribution)
2026-07-14 11:53:39 +09:00
vasilito 6f8dd561e2 scripts: extend check-prefix-freshness.sh with dead-symlink scan
The verify-overlay-integrity.sh script has two blind spots for stale
symlink detection:
  1. find recipes -maxdepth 3 misses paths at depth 4+
  2. only checks targets under /local/recipes/, misses /local/patches/

This adds a parallel scan that finds all dangling symlinks under recipes/
without maxdepth, classifies them by target path, and reports each with a
suggested action. Pure diagnostic — does not modify any files.

Enables preventive detection of the recipes/wip/x11/mesa-x11/source
orphan and recipes/core/base/redox.patch pointer-rot that triggered the
build integrity warnings on this session's rebuilds.

(NO AI attribution in commit message.)
2026-07-13 19:25:14 +03:00
vasilito 43f53a65be fix: add boot to login test 2026-07-13 17:38:38 +03:00
vasilito bf8f012eff fix: add pipe2 init invariant check 2026-07-13 17:38:12 +03:00
vasilito 829e1b87f5 fix: add prefix freshness diagnostic 2026-07-13 17:37:49 +03:00
vasilito bebb5a8ef9 fix: overlay integrity — remove stale patch symlinks and expectations
Archived mega-patches (kernel/redox.patch, base/redox.patch, relibc/redox.patch,
installer/redox.patch, bootloader/redox.patch, P2-boot-runtime-fixes) were
consolidated into modular P0-...P9- patches during Phase 2/3 cleanup but the
integrity checker still expected them. Removed from EXPECTED_PATCH_SYMLINKS
and CRITICAL_PATCHES arrays. Fixed qt6-wayland-smoke symlink.

Overlay integrity check now PASSES (0 errors).
2026-07-12 23:49:04 +03:00
vasilito 9560ace643 fix: guard-recipes.sh — skip files under dir symlinks to local/recipes
When recipes/<cat>/<name> is a directory symlink into local/recipes/,
creating a file-level symlink at recipes/<cat>/<name>/recipe.toml
resolves through the dir symlink and CORRUPTS the real file at
local/recipes/<cat>/<name>/recipe.toml (replaces it with a broken
self-referencing symlink).

This was the root cause of 186 'broken recipe.toml' auto-repairs
on every build. Called via apply-patches.sh line 369.
2026-07-12 18:59:19 +03:00
vasilito fd90ce9fdd fix: widen recipe.toml auto-repair to cover recipes/ tree
Broken recipe.toml corruption also affects tracked symlinks in
recipes/ tree (e.g. recipes/libs/libxau/recipe.toml). Extended
the auto-repair find to cover both local/recipes/ and recipes/.
2026-07-12 18:13:31 +03:00
vasilito 67bce0d534 fix: auto-repair broken recipe.toml symlinks in build preflight
Detects broken recipe.toml symlinks in local/recipes/ (self-referencing
corruption from unknown source) and auto-restores from git before build.
Prevents 'Package not found' errors when recipe.toml files are unreadable.
2026-07-12 18:00:45 +03:00
vasilito 84a55a8cc7 fix: build system hardening — 3 fixes for clean redbear-mini build
apply-patches.sh: 005-qtbase signature now checks correct path
(recipes/wip/qt/qtbase, not recipes/libs/qtbase) and respects
local recipe override. Qt is desktop-only (redbear-full target).

check-fork-drift.sh: skip diverged forks (kernel, bootloader, installer)
to suppress spurious DRIFT warnings. These forks intentionally diverge
from upstream per fork-upstream-map.toml.

integrate-redbear.sh: add safety guard — refuse to symlink any path
ending in 'recipe.toml'. 185 local recipe.toml files were corrupted
into broken self-referencing symlinks by an earlier build session.
All restored from git. Guard prevents reoccurrence.
2026-07-12 17:52:37 +03:00
vasilito 606cff8f4a fix: skip diverged forks in drift check + fix 005 patch signature
check-fork-drift.sh: diverged forks (kernel, bootloader, installer)
are intentionally ahead of upstream — skip them to suppress spurious
DRIFT warnings during build preflight.

apply-patches.sh: 005-qtbase patch signature now checks correct path
(recipes/wip/qt/qtbase/recipe.toml) and respects local recipe override.
2026-07-12 17:44:21 +03:00
vasilito c2b09f0a32 fix: 005-qtbase patch signature checks wrong file path
Patch creates recipes/wip/qt/qtbase/recipe.toml but the signature
check looked for REDBEAR marker in recipes/libs/qtbase/recipe.toml
(wrong path). Also added check for local recipe existence (takes
precedence per local-over-WIP policy).

This was causing overlay integrity check failures during redbear-mini
builds even though Qt is irrelevant for the console target.
2026-07-12 17:43:12 +03:00
vasilito 792b2c6a9a phase 18: net-diff upgrade + exclusion files — all 10 forks verified
upgrade-forks.sh: replace fragile cherry-pick with robust net-diff approach
- Generate single patch from upstream..old_HEAD (git diff, excludes Cargo.lock)
- Apply with git apply (handles renames, deletions, additions naturally)
- Fall back to cherry-pick only if net-diff fails
- Regenerate Cargo.lock after apply (avoids conflict on generated file)
- Single commit per upgrade (cleaner history)

verify-fork-functions.sh: hardened with common-name guard (phase 17.2)

Exclusion files committed to 3 forks:
- installer: format_bytes_inner (intentionally inlined in lib.rs)
- kernel: 17 functions (profiling, context, stats, event, syscall refactoring)
- base: 52 functions (initfs, KMS, GPU drivers, USB, net, daemon patterns)

Result: verify-fork-functions.sh passes for ALL 10 forks (exit 0).
Build system now guarantees upstream + RB patches on every build.
2026-07-12 17:11:15 +03:00
vasilito 4114c10aae phase 17.2: add common-name guard to verify-fork-functions.sh
Common function names (new, read, write, parse, get, set, remove, etc.)
appear in many unrelated files — cross-file search produces false MOVED
classifications (e.g., fn new() in ipcd matches fn new() in xhcid).

The case-based guard skips cross-file search for 40+ common function names.
These must be handled via the .verify-fork-functions.exclude mechanism
instead — operator decides if removal was intentional or accidental.

Results: kernel 19→17 (kcall×2 correctly MOVED to user.rs, eq/hash
correctly blocked from false MOVED to fdstat.rs)
2026-07-12 16:47:57 +03:00
vasilito 62d929d62a phase 17: guarantee upstream+RB patches on every build
upgrade-forks.sh:
- --no-fetch: use cached upstream refs (no network required)
- --force-reapply: force rebase even when 0 commits behind upstream
  Automatically detects missing functions via verify-fork-functions.sh
  and triggers reapply when RB cherry-picks dropped upstream code.

verify-fork-functions.sh:
- Cross-file search: when a function is missing from its upstream file,
  search ALL fork .rs files for renamed/moved equivalents (→ MOVED)
- Per-fork exclusion list: .verify-fork-functions.exclude for
  intentionally removed/replaced functions (→ EXCLUDED)
- Only truly missing (not found anywhere, not excluded) = violations

build-preflight.sh:
- Updated fix suggestion to --no-fetch --force-reapply

Results: installer 2→0 (exclusion+move), kernel 19→15 (4 moved),
base 56→44 (12 moved). Remaining missing functions are known RB
replacements pending exclusion entries.
2026-07-12 16:40:31 +03:00
vasilito ffaa4c6bb4 phase 16.2: update docs for sync-versions.sh safe-by-default + --dry-run
- PATCH-PRESERVATION-AUDIT: add Phase 16.1 to cumulative reduction table
  (122→0 orphans, Round 17); update operator test section with all 6 modes;
  replace stale 'Round 3 final' re-run with current Round 17 verification
- TOOLS.md: add --regen and --dry-run flags; clarify default is opt-in
- HOOKS.md: add --regen and --dry-run to sync-versions.sh option list
2026-07-12 15:27:39 +03:00
vasilito 24b58896c8 phase 16.1: sync-versions.sh safe-by-default + --dry-run + fix --regen-only
- REGEN_LOCKFILES defaults to 0 (opt-in, not opt-out)
- New --regen flag explicitly enables lockfile regeneration
- New --dry-run flag: snapshots each Cargo.lock, regens, diffs, reverts
  Reports per-lockfile changes that WOULD occur without modifying files
- Fixed --regen-only deadlock: CHECK_ONLY=1 no longer blocks regen
  (mode_regen_only gate added to CHECK_ONLY skip check)
- Fixed ROOT_DRIFT unbound variable in --regen-only mode
  (: ${ROOT_DRIFT:=0} before summary section)
- Moved regen_lockfile_for() definition before dry-run block
  (was defined after call site — caused 'command not found')
2026-07-12 15:22:28 +03:00
vasilito 65e47b62a6 phase 14.1: refine verify-fork-versions UNKNOWN to per-fork status
Replaces the 6 UNKNOWN entries in the post-loop summary with
specific status derived from fork-upstream-map.toml when the
main loop doesn't set a per-fork status.

Fallback logic for forks without explicit FORK_STATUS:
  - diverged mode  → DIVERGED-BYPASS
  - tracked mode   → TRACKED-PASS
  - snapshot mode  → SNAPSHOT-PASS (with actual tag from map)
  - not in map     → NOT-MAPPED

This makes every fork's status visible at a glance:
  === Post-verification fork status ===
  bootloader    DIVERGED         mode=diverged; content check skipped
  installer     DIVERGED         mode=diverged; content check skipped
  kernel        DIVERGED         mode=diverged; content check skipped
  libredox      PASS             content matches upstream 0.1.18
  base          TRACKED-PASS     tracked-fork, version label passed
  redoxfs       SNAPSHOT-PASS    snapshot fork, version label 0.9.1
  relibc        SNAPSHOT-PASS    snapshot fork, version label 0.2.5
  ...

Bug fix: upstream_tag variable was stale from the last loop
iteration. Now reads the correct tag from fork-upstream-map.toml.
2026-07-12 13:53:57 +03:00
vasilito d4ff72d9a6 phase 13.1: add post-loop fork status summary to verify-fork-versions.sh
Per assessment G2 from Round 11: verify-fork-versions.sh silently
skipped content checks for forks whose upstream tags don't exist,
making failures invisible. This adds a post-loop summary table
that enumerates each fork's verification status.

Added per-fork status tracking:
  - DIVERGED:       fork in diverged mode (content check skipped)
  - NO_UPSTREAM_TAG: upstream tag doesn't exist (content check skipped)
  - PASS:           content matches upstream tag
  - SKIP:           no Cargo.toml (not a tracked fork)
  - UNKNOWN:        not yet classified (future refinement)

The summary table prints after the per-fork warn/error output,
giving operators a single-view snapshot of all 10 forks:

  === Post-verification fork status ===
  fork          status              detail
  ----------    ----------------    ------
  base          UNKNOWN             not checked
  bootloader    DIVERGED            mode=diverged; content check skipped
  installer     DIVERGED            mode=diverged; content check skipped
  kernel        DIVERGED            mode=diverged; content check skipped
  libredox      PASS                content matches upstream 0.1.18
  ...

Bug fix: added cd "$ROOT" before post-loop summary because the
per-fork content-check loop cd's into each fork directory.
2026-07-12 13:48:20 +03:00
vasilito f3f4f15557 phase 12.1: add TOOLS.md — build-system tools reference (Round 13)
Creates local/scripts/TOOLS.md as a companion to HOOKS.md,
listing only the 10 build-system operator tools (excluding the
~120 test scripts under local/scripts/).

Each tool has:
  - One-line purpose
  - Usage example
  - All mode flags documented

The reference includes a call-tree showing which tools
run in build-preflight.sh vs pre-push-checks.sh.

Added README.md link to TOOLS.md in the Documentation section.
2026-07-12 12:51:18 +03:00
vasilito 87f3f908bf phase 9.1-9.2: add commit-msg hook + consolidate tool docs
Adds the commit-msg hook promised in HOOKS.md since Round 5.
The hook auto-prepends the current Red Bear development phase
(e.g. 'phase 8.4:') to commit messages. The phase is detected
from the most recent 'phase X.Y:' commit in the git log.

Hook behavior:
  - Normal commit    → prepended: 'phase 8.4: my message'
  - Already has prefix → skipped
  - Revert message   → skipped
  - Empty/comment    → skipped

Install: cp local/scripts/commit-msg .git/hooks/commit-msg && chmod +x

Updates HOOKS.md with:
  - commit-msg hook documentation (install, behavior)
  - Full tool inventory table (10 tools across 9+ rounds)
    listing each tool's type, purpose, and modes/flags
2026-07-12 12:20:29 +03:00
vasilito dc48787f74 phase 8.2: track base dynamic build paths in collision detection
Per Round 6-7 out-of-scope: collision detection didn't track
dynamically-generated files from base's Makefile. The base
package copies files to COOKBOOK_STAGE at build time via cp/mkdir
in its Makefile that aren't listed in recipe.toml's [[package]].installs
or [[package]].files fields.

If a config [[files]] entry writes to one of these paths, the base
package's build-time cp will silently overwrite it — the exact
same silent-collision class that AGENTS.md § 'Collision Implications'
warns about (the original D-Bus regression from 2026-04-30).

Added 18 hardcoded dynamic-build paths from base's Makefile:

  initfs paths:
    '/usr/lib/boot/initfs.img'
    '/usr/lib/init.d/00_logd.service'
    '/usr/lib/init.d/00_nulld.service'
    '/usr/lib/init.d/00_randd.service'
    '/usr/lib/init.d/00_rtcd.service'
    '/usr/lib/init.d/00_base.target'
    '/usr/lib/init.d/00_pcid-spawner.service'
    '/usr/lib/init.d/00_ptyd.service'
    '/usr/lib/init.d/00_sudo.service'
    '/usr/lib/init.d/00_ipcd.service'
    '/usr/lib/init.d/90_initfs.target'
    '/usr/lib/pcid.d/initfs.toml'

  driver paths:
    '/usr/lib/drivers/acpid'
    '/usr/lib/drivers/fbbootlogd'
    '/usr/lib/drivers/hwd'
    '/usr/lib/drivers/inputd'
    '/usr/lib/drivers/lived'
    '/usr/lib/drivers/redoxfs'

Tested with synthetic collision:
  - Created config/redbear-test-dynamic.toml with
    path='/usr/lib/boot/initfs.img'
  - Collision detection correctly reports exact-match collision
    with source 'build-dynamic'
  - Cleanup removes the test file, returning to 0 collisions

Survey count: 162 (was 144 + 18 dynamic paths). Production: 0
collisions.
2026-07-12 12:11:23 +03:00