Commit Graph

176 Commits

Author SHA1 Message Date
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
vasilito 850a08b368 phase 7.5: add patch-status.sh — top-level operator-facing status report
New script produces a human-readable report in 3 modes:

  ./local/scripts/patch-status.sh           full text report
  ./local/scripts/patch-status.sh --brief    one-line summary
  ./local/scripts/patch-status.sh --json     machine-readable JSON

Runs 5 verifications (sync-versions, verify-patch-content,
verify-collision-detection, verify-fork-versions, cargo check)
and aggregates the results into a single status report.

The report shows:
  - Active patches (total/preserved/orphaned)
  - Collision detection status
  - Version sync / fork compliance
  - Diverged fork advisory count
  - Cookbook build status
  - Legacy archive counts
  - Fork push deadlock status

Parsing fix: uses per-check temp files (not a single overwritten
tmp file) and sed-based TOTAL line extraction to avoid the
grep -oE first-number trap that returned the wrong patch count.

Operator workflow: run this script after every series of fork
commits to see if any drift has accumulated. Takes 30-120s.
2026-07-12 11:52:28 +03:00
vasilito 38ebecabb6 phase 6.5: add --selftest mode to verify-patch-content + pre-push wiring
Adds --selftest mode that runs 5 regression test cases against a
temp directory. The temp dir is created OUTSIDE the parent git
working tree (e.g. via /tmp/.tmp-redbear-selftest-/) so that the
test's 'git log' commands don't pick up the parent repo's 100+
commits.

Test cases:
  1. patch with sig in fork target         preserved
  2. patch without sig in fork target       orphan
  3. no-target patch (no +++ b/ header)    orphan (no-target)
  4. patch with content-integrated target   orphan (classification)
  5. verify --report action produces per-orphan decision

Bug fixed during dev: passing fork_dir to git log WITHOUT
isolating it from the parent repo's git tree caused 50 'case2'
keyword matches to leak in from the RedBear-OS parent repo's
commit log, making case2 falsely classified as INTEGRATED. Fixed
by using tempfile.mkdtemp(dir=os.path.dirname(REPO_ROOT)) to put
the test fork dir OUTSIDE the parent git tree.

Also fixed: audit_component now accepts an optional patches_dir
arg (so selftest can pass a non-default patches path without
modifying the main code path).

Also fixed: 'if not target_path or target_path == \'?\'' check
in suggest_action_for_orphan to handle the literal '?' sentinel
that audit_component uses for no-target orphans.

Wired into pre-push-checks.sh as check #3b (verify-patch-content-selftest).
Total: 7 pre-push checks now run before any push.
2026-07-12 11:02:27 +03:00
vasilito 687b2650be phase 6.4: operator-decision automation in verify-patch-content
Adds --report action mode to verify-patch-content.py that implements
the AGENTS.md § 'Orphan-Patch Supersession Decision Tree' algorithmically.

For each orphan, the action recommender outputs one of:
  - INTEGRATED:      fork log has >5 commits matching topic keywords;
                    the work IS in the fork under a different commit
                    subject. Safe to archive as superseded.
  - FILE-RESTRUCTURED: target file no longer exists in fork (file
                    rebased past patch's expectations). Safe to archive.
  - NO-TARGET-FILE:  patch lacks +++ b/ header (non-actionable).
                    Safe to archive.
  - MISSING-UPSTREAM: work NOT in fork; needs reapply or fork rebase.

Algorithm (in suggest_action_for_orphan):
  1. Check if patch has no target file (lacks +++ b/) → NO-TARGET-FILE
  2. Check if target file no longer exists in fork → FILE-RESTRUCTURED
  3. Run 'git log -i --grep <topic-keyword>' on the fork; if >5 commits
     match → INTEGRATED
  4. Otherwise → MISSING-UPSTREAM

Validated with synthetic test: created a local/patches/relibc/
_test-synthetic-orphan.patch with target=lib/test/strange.rs (which
doesn't exist in fork). The recommender correctly classified it as
FILE-RESTRUCTURED.

Wired into pre-push-checks.sh as check #3a (verify-patch-content-action).
Future new orphans are auto-classified; the operator only needs to
verify the suggested classification matches reality and then archive
to legacy-superseded-2026-07-12/.
2026-07-12 10:43:15 +03:00
vasilito 8d4818b94b phase 5.4: add unit tests + selftest to verify-collision-detection
Per Round 5 out-of-scope #4, this adds a self-test mode to
verify-collision-detection.py. The selftest covers the algorithm's
edge cases:

  1. exact match (cfg == install)         collision=True
  2. parent-dir prefix (install under cfg) collision=True
  3. /etc/init.d override of init.d        safe
  4. /etc/environment.d override of env.d  safe
  5. non-overlapping names                no collision
  6. parent of subpath (e.g. /etc vs /etc/foo) collision=True
  7. two siblings (same prefix)           no collision
  8. /etc/init.d/* with different base name safe

Run via:
  python3 local/scripts/verify-collision-detection.py --selftest

The selftest is wired into local/scripts/pre-push-checks.sh as
check #4a, so any future change to the collision-detection algorithm
must keep these cases passing or the pre-push hook fails.

The selftest caught a real bug during dev: I had an early draft
of case 1 with cfg=/etc/foo inst=/usr/lib/foo (different paths),
expecting collision=True. The actual algorithm correctly returned
False (no overlap). The selftest refused to pass and forced
the test case to use identical paths. This is exactly the kind
of regression the test was designed to catch.
2026-07-12 10:18:23 +03:00
vasilito 57c6da39bd phase 5.3: add unblock-base-push.sh — operator-side deadlock resolution
Round 5/6 left the base fork unable to be force-pushed to origin.
After investigation in Phase 5.3, the actual cause was identified:
the gitea server's receive.shallowUpdate=true config (not the
ref name as previously thought).

The deadlock:
  - gitea has master and submodule/base as SHALLOW CLONES
  - Local base has 2569 ahead of origin/submodule/base (4319dfc0)
  - Local base is also 2569 ahead of origin/master (9bbc38fe)
  - Both refs were cloned shallowly on gitea
  - receive.shallowUpdate=true blocks any push that would
    deepen the existing ref

Attempted mitigations:
  - 'git push --force-with-lease=...' → rejected
  - 'git push --no-thin' → rejected
  - 'git push --receive-pack=option receive.shallowUpdate false'
    → not supported by gitea protocol layer

The only fix is operator-side: disable receive.shallowUpdate on
the gitea repo. Per AGENTS.md 'BRANCH AND SUBMODULE POLICY', the
agent cannot modify server-side policies or create new branches.

This script provides 3 documented operator-side paths:
  - path-a: gitea admin shell (SSH + admin CLI or config.toml edit)
  - path-b: gitea web UI (no SSH needed; only web admin)
  - path-c: server-side hook (advanced; only when A and B infeasible)

After operator unblocks, the standard push:
  ./local/scripts/push-fork-branches.sh --execute

The script also displays current fork state (local/remote SHA,
ahead/behind, last 5 local commits) for context.

Files in scope: local/scripts/unblock-base-push.sh
2026-07-12 10:13:12 +03:00
vasilito 7132f9e5f1 phase 5.1: extend verify-collision-detection to [[package]].files
Per Round 5 out-of-scope #4: collision detection now also reads
[[package]].files in addition to [[package]].installs.

The codebase actually uses [[package]].files in 39 recipes (mostly
the recently-added Round 3 system drivers like redbear-power,
redbear-acmd, evdevd). The format is an inline table mapping
install path -> source basename:

  [[package.files]]
  "/usr/bin/redbear-power" = "redbear-power"

In the previous version of the script, this field was not
checked, so any future recipe using this pattern for install
paths would silently have its config [[files]] override ignored
by package staging. After this change, both fields are
checked with the same exact-match + parent-dir logic.

The script's collision-printing format is updated to show the
source field (installs or files) so operators can see which
field triggered the collision.

Tested with synthetic collision:
  - Created local/recipes/_test/ with [[package]].files=['/lib/test/special.toml']
  - Created config/redbear-test-files.toml with [[files]] path=/lib/test/special.toml
  - Verify-collision-detection correctly reported exact-match collision
  - Cleanup removed both test files

Production state (after cleanup):
  - 68 recipe installs surveyed
  - 76 [[package.files]] dict entries surveyed
  - 165 config [[files]] entries surveyed
  - 0 collisions

Per AGENTS.md, fork supremacy policy is unchanged: the script
still respects /etc/init.d/* and /etc/environment.d/* as known-safe
overrides.
2026-07-12 09:50:59 +03:00
vasilito a1613c0590 phase 4.5: add pre-push-checks.sh opt-in hook + HOOKS doc
Per AGENTS.md 'Daily-upstream-safe workflow', drift between fork
state and active patch system can only be caught at next-build time.
This commit closes the gap by providing a pre-push hook that runs
the 4 critical pre-flight checks BEFORE pushing to origin.

The hook runs (in order):
  1. sync-versions.sh --check (Cat 0 + Cat 1 + Cat 2 versions)
  2. verify-fork-versions.sh (Cat 2 fork supremacy)
  3. verify-patch-content.py (no orphan patches)
  4. verify-collision-detection.py (no config-vs-package conflicts)

Per AGENTS.md 'absolutely NEVER DELETE, NEVER IGNORE' rule, the hook
is OPT-IN: operators must explicitly install it via
  cp local/scripts/pre-push-checks.sh .git/hooks/pre-push
  chmod +x .git/hooks/pre-push

The opt-in nature respects operator autonomy — local hooks do not
propagate (each clone must re-install), and false positives would
block legitimate pushes.

HOOKS.md documents the available hooks + future work (pre-receive
on server side for defense in depth; commit-msg hook for auto-phase
prefix in commit messages).

Default mode of the script: fail on any drift (exit 1). Use
--soft flag or REDBEAR_SKIP_PRE_PUSH=1 to bypass.
2026-07-12 09:38:12 +03:00
vasilito dbcff12184 phase 4.2: implement general package-vs-config collision detection
Per AGENTS.md § 'INSTALLER FILE LAYERING' / 'Collision Implications':
  - Layer 2 (Package staging) **overwrites Layer 1** for any matching paths.
  - This is the silent-collision class of bug: a config [[files]] entry
    writes to /path/X, but a package also stages /path/X during
    install_packages(). Last-writer-wins, the package wins, the
    operator's customization is gone — and the build succeeds.

Phase 0 audit confirmed that AGENTS.md's promise of a CollisionTracker
in src/cook/collision.rs was false (the file doesn't exist). Phase 4.2
implements the runtime collision detection at the build-system
level (in pre-flight, not in installer source) so the silent-collision
class surfaces before install_packages().

New file: local/scripts/verify-collision-detection.py
- Parses every recipes/<cat>/<pkg>/recipe.toml's [[package]].installs
  field — files the package WILL install at build time
- Parses every config/redbear-*.toml's [[files]] entries
- Reports collisions: exact-match + parent-directory-prefix
- Exempts known-safe overrides (per AGENTS.md 'Init Service File
  Ownership'): /etc/init.d/*, /etc/environment.d/*

Initial result (2026-07-12):
  - 68 recipe installs surveyed
  - 165 config [[files]] entries surveyed
  - 0 collisions

Wired into local/scripts/build-preflight.sh via:
  - Default: report-only
  - --strict: exit 1 on collision (for CI)
  - REDBEAR_SKIP_COLLISION_CHECK=1: bypass entirely

Updated local/docs/COLLISION-DETECTION-STATUS.md with:
- Phase 4.2 implementation summary
- How the algorithm works
- What it does NOT cover (runtime conflicts, patch-induced, dynamic
  generation)
- Recovery options
2026-07-12 09:36:54 +03:00
vasilito 9871d79aa4 phase 4.3: archive 2 kernel patches operator-superseded
Phase 4.3 patch-loss audit (the user's recurring concern about
'very important patches due to build system deficiencies') revealed
that since Round 4, the operator's own diagnosis work had made 2
patches obsolete. Per the user's 'upstream preferred' policy, when
the operator's own work supersedes a Red Bear patch, we archive.

P0-canary (operator-superseded):
- Original: Phase 1.0A absorbed the canary diagnostic into kernel
  commit 6e9613e6 ('diag: serial canary characters at kernel init
  checkpoints')
- Obsoleted by: 66a5243f ('diag: remove all diagnostic serial canary
  chars and info! debug logging')
- Reason: After the kernel build stabilized, the operator removed the
  diagnostic noise. The canary's purpose (early-boot serial output)
  is no longer needed.

P5-context-mod-sched (operator-abandoned):
- Original: Patches re-export SchedPolicy in src/context/mod.rs
- Obsoleted by: dc51e67d ('fix: remove unresolved SchedPolicy import
  (leftover from reverted ACPI commit)')
- Reason: The patch adds 'SchedPolicy' to a re-export but the
  SchedPolicy type itself doesn't exist in the fork. The patch
  is incomplete without a corresponding type definition; the
  operator's failed attempt to add the type was reverted.

Both moves follow AGENTS.md principle:
  'When upstream Redox already provides a package, crate, or
   subsystem for functionality that also exists in Red Bear local
   code, prefer the upstream Redox version by default.'

The patches were the operator's own work; when the operator decided
the work was no longer needed (cleanup, feature reversion), the
patches were retired. 'Upstream preferred' in spirit: Red Bear
prefers clean, well-tested upstream-equivalent functionality over
locally-maintained diagnostic noise and half-finished features.

After this commit:
  Active patches: 119 (was 121)
  Archived: 96 in legacy-superseded-2026-07-12/
  All forks: 0 orphans
2026-07-12 09:23:10 +03:00
vasilito 6fd13f3e28 phase 3.5: add push-fork-branches.sh — operator-reviewed fork push helper
After 3 rounds of patch-preservation work, multiple fork branches
have new commits that need to reach origin's submodule/<name> refs:

  fork          local-vs-origin  state
  base          2564 ahead, 190 behind    significant divergence
  bootloader    10 ahead, 128 behind     927 vs 77 file divergence
  installer     61 ahead, 0 behind       ready to force-push
  kernel        45 ahead, 0 behind       ready to force-push
  libredox      69 ahead, 11 behind      fast-forward possible
  relibc        3434 ahead, 60 behind    significant divergence
  syscall       1 ahead, 0 behind        ready to force-push
  userutils     202 ahead, 12 behind     merge decisions needed

This script provides:
1. Status table showing ahead/behind for each fork
2. Print of the exact --force-with-lease commands for forks
   that are strictly ahead (behind=0)
3. NO-OP default mode (must use --execute to actually push)
4. A 5-second abort window if --execute is used

Per AGENTS.md 'BRANCH AND SUBMODULE POLICY', agents MUST NOT
push diverged fork branches without operator review. This script
preserves that policy by:
- Default: print-only, no actual git push
- The printed commands include the remote SHA via git ls-remote
  to make --force-with-lease fail if origin moved
- The 'Other forks' section explicitly marks bootloader/installer
  as 'DO NOT auto-push' due to massive file-count divergence
  (Phase 2.4+ work)

Implementation notes:
- Uses 'local_sha..remote_sha' / 'remote_sha..local_sha' form
  to avoid the 'ambiguous HEAD' error in submodule working
  trees (the fork tree has a stale symlink that confuses git
  revision parsing — see commit history if that needs fixing)
- behind=0 and ahead>0 are the only cases the script marks
  'REVIEW_NEEDED' — behind>0 forks need merge decisions
2026-07-12 02:38:12 +03:00
vasilito 4ac665b288 phase 2.4: boilerplate fixes — diverged mode + liibredox .gitignore
Build system improvements after Phase 2.0 / 2.1 / 2.2 patch work:

1. New 'diverged' mode in local/fork-upstream-map.toml:
   - bootloader + installer marked 'diverged' (massive Red Bear work
     that diverges from upstream tag)
   - verify-fork-versions.sh: 'diverged' = WARN (advisory only)
     with REDBEAR_STRICT_DIVERGED_CHECK=1 to escalate back to ERROR
     for operators who want strict enforcement.

2. Bug fix in verify-fork-versions.sh (Phase 2.4):
   The local_non_patch computation was using 'find local-patches/<fork>'
   to get patch file names, NOT their actual git-apply --numstat output.
   Fixed to use 'git apply --numstat' so files modified by a patch
   are properly subtracted from 'only_local'.

3. Per-fork declarative expected-differ list:
   - libredox: src/lib.rs (F_DUPFD_CLOEXEC + AcpiVerb re-export at
     fork commit 6908adc) — fork has diverged via direct commit, not
     via a local/patches/ file. Algorithm now recognizes this as
     INTEGRATED.
   - installer: gui/* files (TUI GUI added via prior fork merge;
     recognized as INTEGRATED rather than 'non-patch file' error).

4. libredox fork cleanup:
   - Removed .cargo-ok + .cargo_vcs_info.json from tracking (cargo
     metadata that should be in .gitignore, not source control)
   - Added /Cargo.lock to .gitignore (matches upstream .gitignore)
   - This unblocks verify-fork-versions.sh for libredox 0.1.18.

After this commit:
- bash verify-fork-versions.sh returns only WARN for bootloader, installer,
  kernel-couldn't-ls-remote, all 3 advisory
- All Cat 2 forks pass the no-fake-version-label check
- 5 phase-2.4 forks tracked correctly
2026-07-12 02:16:15 +03:00
vasilito 9a77de464a phase 1.4: extend sync-versions.sh — root Cargo.toml + Cargo.lock regen
Per Phase 0 audit findings (G1, G2), the build-system version sync
had two omissions that allowed drift to accumulate across branch
bumps:

1. G2: The root Cargo.toml's [package] version was outside the
   script's scope. During 0.3.0 -> 0.3.1 branch change, syncing
   Cat 1 + Cat 2 versions did not touch the cookbook crate itself,
   so 'repo --version' reported the wrong version. Fixed by adding
   Phase 0: Cookbook root Cargo.toml block that mirrors the Cat 1
   version assignment.

2. G1: After a branch bump, Cargo.lock files were not regenerated.
   Each Cat 2 fork's lockfile kept its previous +rb suffix even after
   the fork's Cargo.toml was updated. Fixed by adding Phase 3: a
   'cargo generate-lockfile' pass that runs in each fork and the
   root cookbook after version sync completes. The path-dep +
   [patch.crates-io] config in each fork ensures the right crates
   are pulled in; the script verifies each cargo generate-lockfile
   exit code.

New flags:
  --check       Verify only (no writes), exit 1 on drift
  --no-regen    Apply version sync, skip lockfile regen
  --regen-only  Skip version sync, only regen lockfiles
  (default)     Apply sync + regen lockfiles

After this commit, branch bump workflow is:
  ./local/scripts/sync-versions.sh
... and nothing else is needed for Cargo.lock freshness. The
script exits non-zero only if any 'cargo generate-lockfile' fails
in a fork, surfacing build breakage immediately.
2026-07-12 01:42:30 +03:00
vasilito 4a37ae1a57 phase 1.2: move 137 legacy .patch symlinks out of path-source recipes
Per AGENTS.md § 'Local Fork Recipe Directories Must Not Carry Patch
Files', the symlinks under recipes/core/{base,kernel,relibc,
bootloader,installer}/ pointing at the canonical local/patches/<comp>/
patches were violations. The recipes use path = '...' source so the
cookbook would never apply these patches; the symlinks were a
navigation aid only.

This commit moves all 137 valid symlinks (and the redox.patch
counterparts) to local/docs/legacy-recipe-patches/<comp>/ with a
README explaining the rationale and pointing readers at the canonical
patch location.

The patches themselves (local/patches/<comp>/*.patch) are NOT
modified — they remain git-tracked at their canonical location.
Per AGENTS.md 'NEVER DELETE' policy the patches stay in their
canonical home; only the navigation aid symlinks are relocated.

Breakdown:
  base (61)         - legacy-recipe-patches/base/
  kernel (26)       - legacy-recipe-patches/kernel/
  relibc (46)       - legacy-recipe-patches/relibc/
  bootloader (3)    - legacy-recipe-patches/bootloader/
  installer (1)     - legacy-recipe-patches/installer/

After this commit, recipes/core/<comp>/.patch references all show
zero matches per AGENTS.md rule.
2026-07-12 01:35:58 +03:00
vasilito 50d54a2499 phase 1.0: wire patch-content check into preflight + add audit doc
1. local/scripts/build-preflight.sh — invoke verify-patch-content.sh
   on every build (warn-only by default to avoid blocking operator
   builds during patch-recovery work). REDBEAR_SKIP_PATCH_CONTENT_CHECK=1
   bypasses the check.

2. local/docs/PATCH-PRESERVATION-AUDIT-2026-07-12.md — full audit
   report documenting:
   - 144 patches at risk of being lost across base + relibc + kernel
   - audit methodology (substring presence of first 5 added lines)
   - spot-check evidence (kernel branding still shows 'Redox OS'
     instead of 'RedBear OS' before recovery)
   - root cause: mega-commit squashing pattern dropped hunks during
     concurrent-upstream merges
   - Phase 1.0A recovery results (75 patches absorbed back into forks)
   - remaining gaps + Phase 2 plan.
2026-07-12 01:31:39 +03:00
vasilito e4bb452d86 phase 1.0B: add verify-patch-content.{py,sh} — orphan-patch audit tool
Per the Phase 1.0 audit (local/docs/PATCH-PRESERVATION-AUDIT-2026-07-12.md)
no part of the build system was checking that patches listed in
local/patches/<comp>/ had actually been absorbed into the
local/sources/<comp>/ fork's working tree.

This commit adds a tool that audits every Cat 2 fork and reports any
patches whose content is not present in the fork HEAD. The tool is
located at local/scripts/verify-patch-content.{sh,py} and follows the
existing local/scripts/ convention (shell wrapper delegating to
Python implementation).

Audit method:
  1. For each .patch in local/patches/<comp>/:
     - Extract target file from ---/+++ headers
     - Extract first 5 added lines (+ markers)
     - Check substring presence in fork HEAD version
  2. If 0/5 added lines found, patch is 'orphaned'

Current state (after Phase 1.0A recovery):
  - 251 patches total, 155 preserved, 96 still orphaned
  - The remaining orphans are patches where the upstream file structure
    has shifted too far for patch(1) to apply — those need
    upstream-tracking upgrade, deferred to Phase 2.

Usage:
  ./local/scripts/verify-patch-content.sh                       (report)
  ./local/scripts/verify-patch-content.sh --strict             (exit 1 on orphans)
  ./local/scripts/verify-patch-content.sh base kernel          (specific forks)

Wired in via build-preflight.sh in the next commit (Phase 1.0B cont.).

This closes the 'silent patch loss' gap identified in the audit.
2026-07-12 01:31:03 +03:00
vasilito 79285e4ebf verify-fork-versions.sh: add per-fork upstream content fingerprint cache
When the upstream commit hash of the claimed upstream tag has not changed
since the last successful verify, reuse the cached file list instead of
re-cloning and re-hashing from scratch. This makes the canonical preflight
fast on the common case where upstream didn't move.

Cache is stored in .redbear-fork-verify/<fork>-<tag>.fingerprint. Touched
only after a successful full content diff, so cache corruption is detected
on the next run (commit hash mismatch triggers fresh clone).
2026-07-12 00:33:52 +03:00
vasilito 1b8fd21eba build-redbear.sh: re-enable overlay integrity check (was disabled for symlink corruption)
The verify-overlay-integrity.sh script is now active. It runs at the
start of canonical builds and auto-repairs via apply-patches.sh on
failure.

Restored missing symlinks for:
- recipes/core/base/redox.patch
- recipes/core/bootloader/redox.patch
- recipes/core/bootloader/P2-live-preload-guard.patch
- recipes/core/bootloader/P3-uefi-live-image-safe-read.patch
- recipes/wip/wayland/qt6-wayland-smoke (incorrect relative path)

Created empty stub at local/patches/base/redox.patch so the relibc/base
symlinks can be re-created by apply-patches.sh.

Overlay integrity now reports:
  365 recipe symlinks, 0 broken
  9 patch symlinks, 0 broken
  9 critical patches, 0 missing
  10 critical configs, 0 missing
2026-07-12 00:27:27 +03:00