verify-patch-sanity.py validates every active recipe .patch has internally-
consistent hunk line counts — catching the 'malformed patch at line N' failure
at commit/CI/preflight time instead of hours into a cook. This cycle hit that
class three times (qtwaylandscanner, sddm, xwayland), each only discovered when
cookbook tried to apply the patch.
Running it across the repo found 29 latent malformed patches (validated against
GNU patch: e.g. relibc/P3-sysv-ipc reproduces 'malformed patch at line 22').
They were harmless only because they sit in vendored recipes (baked, not re-
applied) — but would fail on any version-bump re-derivation. --fix recounts the
hunk headers (body untouched) and repaired all 29.
Wired into build-preflight.sh (Phase 1.0D) and redbear-ci.yml, with a unit test
(test-patch-sanity.sh). Skips archived/legacy trees and unvalidatable formats
(empty placeholders, bare-@@ git hunks).
Proves build-redbear.sh's vendored source/ staleness loop: seeds on first sight
(no spurious rebuild), stays quiet unchanged, and invalidates target/ on
committed/uncommitted/untracked source/ changes. Keeps the loop body in sync.
Found by extending the edge-case suite to the baked-shim path (E17-E19) after a
sync reported 'ready' but silently dropped a module's Redox shim:
- git show used an ABSOLUTE recipe path ('HEAD:/mnt/.../source/f') which git
rejects (needs repo-relative) -> empty content -> garbage delta. Now uses
${dir#$ROOT/}.
- diff|patch under 'set -o pipefail': diff exits 1 whenever files differ (always
here), so the pipeline looked failed even when patch succeeded -> EVERY shim
false-rejected. Now captures the delta to a file and checks patch's own exit.
- a shim whose file was renamed/removed upstream, or unreadable from HEAD, was
silently skipped. Now: Redox-added files are carried in verbatim; a missing
target or unreadable HEAD file -> SHIM-REJECT (manual), never a silent drop.
Also: old-version URL derivation now rewrites the major.minor dir component too
(KDE mirrors nest tarballs under .../6.28/foo-6.28.0). CI branch glob widened to
[0-9]* so 0.4.0/0.5.0 release branches keep triggering.
Integration (answers 'does it run automatically'):
- redbear-ci.yml now runs test-versioning-machinery.sh (33 cases) and
verify-external-source-versions.sh on every push/PR; trigger widened to
0.3.* so a release-branch increment keeps CI (and these checks) firing.
- The validator already runs in build-preflight.sh Phase 1.0C (every build),
and bump-graphics-recipes.sh (invoked by bump-release.sh --with-external)
now calls the sync engine — so an external bump propagates + is validated.
Engine hardening (both regression-tested):
- reconcile_blake3: a vendored bump often left recipe blake3 stale (URL bumped,
hash not); the engine now sets recipe blake3 to the authoritative source.tar
hash (only when source.tar version matches the URL version; no-op under --check).
- transient recipes (no vendored source/) now get their stale cached source.tar
bumped to the declared version too, instead of being skipped.
Phase 4D CI workflow at .github/workflows/redbear-ci.yml.
Runs on push to 0.3.1/master and all PRs:
- sync-versions.sh --check (enforces Cat 1/Cat 2 +rb policy)
- cargo fmt --check on all redbear-* Cargo.toml files
- cargo check --target x86_64-unknown-redox on all redbear-* recipes
- Host unit tests for library-only / pure-logic crates
The cross-target cargo check uses --locked and continue-on-error=true
because the redoxer cross toolchain may not be provisioned on every
runner. cargo fmt --check is the strict gate that always passes.
sync-versions.sh --check still passes (76 Cat 1 crates, 0 drift).
cargo check passes for all 49 packages per --check-sweep redbear-mini.