feat: build system hardening — collision detection, validation gates, init path enforcement

5-phase hardening to prevent silent file-layer collisions (the D-Bus
regression class):

Phase 1: lint-config-paths.sh + make lint-config in depends.mk
Phase 2: CollisionTracker in installer (content-hash comparison)
Phase 3: installs manifests in recipe.toml + validate-file-ownership.sh
Phase 4: validate-init-services.sh + make validate in disk.mk
Phase 5: documentation (AGENTS.md, BUILD-SYSTEM-HARDENING-PLAN.md)

Both redbear-mini and redbear-full build and validate clean.
66 declared install paths in base, zero conflicts.
This commit is contained in:
2026-05-03 22:25:22 +01:00
parent 907d447369
commit 2e764746e7
21 changed files with 1503 additions and 69 deletions
+45
View File
@@ -144,6 +144,51 @@ make all
- **Syscall ABI**: Unstable intentionally. Stability via `libredox` and `relibc`
- **Drivers**: ALL userspace daemons via scheme system. No kernel-space drivers (except serio)
## INSTALLER FILE LAYERING
The installer creates filesystem images in four layers. Understanding this ordering is critical
to avoid silent file overwrites.
### Layer Ordering During `install_dir()`
```
Layer 1: Config pre-install [[files]] (postinstall = false)
Layer 2: Package staging (install_packages())
Layer 3: Config post-install [[files]] (postinstall = true)
Layer 4: User/group creation (passwd, shadow, group)
```
### Collision Implications
- **Layer 2 overwrites Layer 1** silently (same path → last writer wins). This is the bug class
that caused the D-Bus regression: config overrides at `/usr/lib/init.d/` were overwritten by
the `base` package staging the same paths.
- **Layer 3 overwrites Layer 2** (intentional — postinstall overrides).
- For init services, config overrides **MUST** use `/etc/init.d/` so they survive Layer 2.
### Init Service File Ownership
- **Packages own `/usr/lib/init.d/`** — default service files installed by recipe staging
- **Config overrides own `/etc/init.d/`** — override files created by `[[files]]` entries
- The init system's `config_for_dirs()` gives `/etc/init.d/` priority via BTreeMap dedup
- **Config `[[files]]` entries MUST NOT use `/usr/lib/init.d/` paths for init services**
- Run `make lint-config` to detect violations
### Collision Detection
The installer now includes a `CollisionTracker` (in `collision.rs`) that detects when package
staging overwrites config pre-install files. Init service collisions always error. Other
collisions warn by default, error in strict mode (`REDBEAR_STRICT_COLLISION=1`).
### Validation Gates
After building an image, run `make validate` to verify:
- Init service path violations (via `lint-config`)
- Override effectiveness and scheme binary existence (via `validate-init-services.sh`)
- File ownership conflicts (via `validate-file-ownership.sh`)
See `local/docs/BUILD-SYSTEM-HARDENING-PLAN.md` for the full plan.
## ANTI-PATTERNS (THIS PROJECT)
- **DO NOT** suppress errors with `as any` / `@ts-ignore` — use proper `Result` handling