# Red Bear OS — External Recipe Versioning Model This document defines how versions are managed for **tar-based (external upstream) recipes** under `local/recipes/`, and the machinery that keeps them consistent. It exists because a class of silent bug — a version bump that updated recipe metadata but never reached the actual build input — shipped the wrong version of Qt and the entire KDE stack (Qt built at 6.11.0 instead of 6.11.1; KDE built at 6.10.0 while recipes declared 6.28.0). ## The two fork families Red Bear OS carries local forks of upstream code in two places, each with its own consistency guard: | family | location | build input | version guard | |---|---|---|---| | **source forks** | `local/sources/` (submodules) | the fork branch | `verify-fork-versions.sh`, `verify-fork-functions.sh` | | **recipe forks** | `local/recipes//source/` (vendored tree) | the vendored `source/` | `verify-external-source-versions.sh` | This document is about the **recipe forks**. ## Anatomy of a tar recipe A tar recipe has up to four version-bearing artifacts: 1. `recipe.toml` → `[source] tar = "…-.tar.xz"` + `blake3` + `[package] version` 2. `source.tar` — the downloaded pristine tarball 3. `source/` — the **vendored working tree**, committed to git. For a *vendored* recipe this is `pristine(VER)` + recipe patches (+ occasionally a Redox change committed directly, a "baked shim"). **This is what cookbook actually builds.** 4. `source/.redbear-src-version` — a stamp recording the version `source/` was laid down from. A recipe is **vendored** if `source/` is git-tracked, else **transient** (cookbook re-fetches + re-extracts from `source.tar` each build). ## The invariant > `recipe.toml` is the single source of truth for the version. For a vendored > recipe, `source.tar`, `source/`, and the `.redbear-src-version` stamp MUST all > equal the version declared by `[source] tar=`. `recipe.toml` is authoritative because it is the reviewable, diffable statement of intent. `source/` is *derived* from it. ## Why the invariant broke `bump-graphics-recipes.sh` (and manual edits) rewrote `tar=`/`blake3=` but **never propagated into the vendored `source/`**. Cookbook, for its part, does not re-extract an existing `source/` nor re-verify an existing `source.tar` against the recipe blake3. So a bump silently no-op'd on every vendored recipe: the metadata said the new version, the build kept compiling the old tree. ## The machinery ### `sync-recipe-source.sh` — the propagation engine Makes `source.tar` + `source/` + stamp agree with `recipe.toml`, by rebasing the vendored fork onto the declared upstream: ``` source/(Vnew) = pristine(Vnew) + recipe patches + captured baked delta ``` The **baked delta** is any change in the committed `source/` not produced by a listed patch (e.g. a Redox shim committed directly). It is captured against `pristine(Vold)` and re-applied onto `pristine(Vnew)` so a re-lay can never silently drop a Redox port change; injected line-duplication corruption is dropped. A patch or shim that will not apply to the new upstream is reported as `PATCH-REJECT`/`SHIM-REJECT` (needs a manual rebase) — never applied with fuzz. ``` sync-recipe-source.sh --check --all # triage every recipe, write nothing sync-recipe-source.sh --commit # rebase + stamp + commit one recipe ``` ### `verify-external-source-versions.sh` — the preflight gate Runs in `build-preflight.sh` (Phase 1.0C, skip with `REDBEAR_SKIP_EXTERNAL_SOURCE_CHECK=1`). Fails the build loudly on any divergence: `source.tar` blake3 ≠ recipe blake3, `source.tar` top-dir version ≠ tar-URL version, or vendored `source/` marker/stamp ≠ tar-URL version. ### `bump-graphics-recipes.sh` — now propagates After rewriting `tar=`/`blake3=`/`version`, it calls `sync-recipe-source.sh` for the bumped recipe. A vendored recipe whose Redox port needs a manual rebase is reported (`[propagate-manual]`) rather than left silently stale. ## How to bump an external recipe (the correct workflow) 1. Bump the version: `bump-graphics-recipes.sh` (auto, resolves latest) **or** edit `recipe.toml`'s `tar=` by hand. 2. It propagates into `source/` via the sync engine. If it reports `[propagate-manual]`, rebase the failing patch/shim onto the new upstream and re-run `sync-recipe-source.sh --commit `. 3. `verify-external-source-versions.sh` (in preflight) confirms consistency. ## Source-version markers understood by the tooling - `source/.redbear-src-version` — plain `X.Y.Z` (written by the sync engine) - `source/.cmake.conf` → `QT_REPO_MODULE_VERSION` (Qt modules) - `source/CMakeLists.txt` → `set(KF_VERSION …)` / `project(… VERSION …)` (KDE)