# Collision Detection — Status (Updated 2026-07-18, Phase 15.0 / Round 16) ## History - **2026-07-18 (Phase 15.0 — runtime detection landed)**: Implemented the runtime package-vs-config collision tracker in the installer's `install_dir()`. Lives at `local/sources/installer/src/collision.rs` (module `redox_installer::collision`), wired into all four installer layers via `CollisionTracker`. Integration tests at `local/sources/installer/tests/collision.rs` (6 tests, public-API only). Warn-only by default; strict mode opt-in via `REDBEAR_INSTALLER_STRICT_COLLISIONS=1`. Emits `[COLLISION-WARN]` / `[COLLISION-ERROR]` markers for `scripts/validate-collision-log.sh`. Suppresses Layer 3 (postinstall overrides — intentional) and the known-safe override pairs (`/etc/init.d` over `/usr/lib/init.d`, `/etc/environment.d` over `/usr/lib/environment.d`). This closes the gap item 1 below: runtime Layer 2 overwrites Layer 1 is now caught. - **2026-07-12 (Phase 0)**: AGENTS.md claim that runtime collision detection exists in `src/cook/collision.rs` was **disproven** — the file does not exist in source code. The init-service variant is caught by `scripts/lint-config-paths.sh`; the general package-vs-config variant was not implemented. `local/docs/COLLISION- DETECTION-STATUS.md` documented this gap. - **2026-07-12 (Phase 4.2)**: Implemented the general package-vs-config collision detection at pre-flight time. Located at `local/scripts/verify-collision-detection.py`. Wired into `local/scripts/build-preflight.sh` with `REDBEAR_SKIP_COLLISION_CHECK=1` bypass env var. - **2026-07-12 (Phase 5.1)**: Extended collision detection to also parse `[[package]].files` (the TOML inline table of install paths used by 39 recipes including the Round 3 system drivers like redbear-power, redbear-acmd, evdevd). The forward coverage ensures future recipes using this pattern are caught. - **2026-07-12 (Phase 5.4)**: Added `--selftest` mode with 8 regression test cases that exercise the algorithm's edge cases (exact match, parent-dir prefix, /etc/init.d override, /etc/environment.d override, non-overlapping, parent-of-subpath, two siblings, different base names). The selftest is wired into `pre-push-checks.sh` so future algorithm changes must keep these cases passing or the pre-push hook fails. ## How it works The script compares: - **Recipe installs**: `recipes///recipe.toml` `[[package]].installs` fields (canonical list) — files the package WILL install at build time - **Recipe files**: `recipes///recipe.toml` `[[package]].files` dict (path → source mapping) — also checked (Phase 5.1) - **Config [[files]]**: `config/redbear-*.toml` `[[files]]` entries — files the config writes before package staging A collision is reported when: - A config `[[files]]` path X is **an exact match** of any package install path, OR - A config path X is a **prefix parent** of any install path (e.g., `/etc/foo` collides with `/etc/foo/bar`) - AND the path is NOT a known-safe override Known-safe overrides (per AGENTS.md "Init Service File Ownership"): - `/etc/init.d/*` overrides `/usr/lib/init.d/*` - `/etc/environment.d/*` overrides `/usr/lib/environment.d/*` ## Initial result (2026-07-12, post-Phase-4.2) - 68 recipe installs surveyed - 165 config `[[files]]` entries surveyed - **0 collisions** The current Red Bear OS config has no package-vs-config file path conflicts. The 2026-04-30 D-Bus regression class (per AGENTS.md historical) is not present in the active build. ## What this does NOT cover 1. **Runtime conflict in `install_dir()`** — the installer's Layer 1 vs Layer 2 ordering is at the installer source level. The pre-flight check catches the BUILD-TIME planning. **COVERED as of Phase 5.1: `[[package]].files` paths are now checked alongside `[[package]].installs` (39 recipes use this field). 162 total paths surveyed.** **COVERED as of Phase 15.0: runtime `CollisionTracker` in `install_dir()` now detects Layer 2 (package staging) overwriting Layer 1 (config pre-install) at install time. See `local/sources/installer/src/collision.rs` and the 6 integration tests in `local/sources/installer/tests/collision.rs`.** 2. **Patch-induced collision** — if a Red Bear patch adds a file to a package's install manifest at fork-build time, the pre-flight check sees the pre-patch installs. The pre-flight catches the static recipe state, not fork-merge state. 3. **Dynamic file generation** — the `base` package's initfs generator creates files at build time (`/usr/lib/boot/initfs.img`, `/usr/lib/init.d/*`, `/usr/lib/drivers/*`). **PARTIALLY COVERED as of Phase 8.2: 18 hardcoded dynamic-build paths from base's Makefile are now checked.** Future work: auto-detect these paths from the Makefile rather than hardcoding. 4. **In-file test cases** — the `--selftest` mode (Phase 5.4) tests the algorithm against 8 hard-coded cases. A more comprehensive fuzzing test (random paths, deeper prefix trees) would catch more edge cases. Future work: add property-based test using hypothesis or similar. ## Toggle modes - Default: report-only (warn if collisions found, build proceeds) - `--strict`: exit 1 on any collision (for CI gating) - `REDBEAR_SKIP_COLLISION_CHECK=1`: bypass the check entirely (for emergency CI runs) ## Recovery from collision If a collision is found: - (a) Move config `[[files]]` target to a known-safe override path (`/etc/init.d/*`, `/etc/environment.d/*`) - (b) Remove the conflicting path from the recipe's `[[package]].installs` list - (c) Add an explicit `[path.collision.allow]` exception to the config (not yet implemented — Phase 4.3+ work)