Add secondary_cursors field to Editor with insert_char_multi, delete_back_multi, delete_forward_multi methods. Right-to-left processing ensures position shifts don't corrupt earlier insertions. 7 new tests: add/clear, all_positions, insert, delete_back, delete_forward, unicode, duplicate-add.
6.2 KiB
Cargo Patch Propagation — Fork Dependency Policy
Created: 2026-07-02 Status: Active policy Scope: All Rust recipes that depend on forked packages
The Rule
Every recipe that uses a forked package MUST depend on the local fork — never on the upstream/crates.io version.
Upstream package (gitlab.redox-os.org / crates.io)
│
▼
Our local fork (local/sources/<package>/)
│ (patches applied, version bumps tracked)
▼
ALL downstream recipes depend on THIS fork
Forked packages (as of 2026-07-02)
| Package | Local fork | Version | Symlink |
|---|---|---|---|
redox_syscall |
local/sources/syscall/ |
0.8.1 | recipes/core/base/syscall |
libredox |
local/sources/libredox/ |
0.1.18 | recipes/core/base/libredox |
Lifecycle: when upstream bumps version
- Update fork first —
git fetch upstream && git rebase upstream/masterinlocal/sources/<package>/ - Rebase all patches — ensure Red Bear patches still apply against the new upstream
- Rebuild prefix —
touch <component> && make prefixif the fork affects the cross-toolchain sysroot - All dependents automatically use the updated fork — no per-recipe changes needed
- Adapt downstream code — if the upstream bump changed an API, fix every recipe that breaks (Golden Rule: Red Bear adapts to upstream, never the reverse)
Why This Matters
The Problem: Cargo [patch] doesn't propagate
Cargo's [patch.crates-io] only applies from the root package being compiled. When
a recipe depends on a base workspace member (like daemon) via path dependency, the base
workspace's own [patch] entries are silently ignored.
This means:
- Recipe
redox-drmdepends ondaemonviapath = ".../base/source/daemon" daemonis part of thebaseworkspace, which patchesredox_syscallandlibredox- But when cargo compiles
redox-drmas root, onlyredox-drm's own[patch]applies libredoxfrom crates.io vendors its own copy ofredox_syscallinternally- Two different
syscall::Errortypes exist at compile time → E0277 type mismatch
The Fix: Use path dependencies, not version dependencies
Every recipe that needs redox_syscall or libredox should use the local fork via path
dependency or [patch.crates-io] entry. The path is always the same relative depth from
local/recipes/<category>/<name>/source/Cargo.toml:
../../../../../recipes/core/base/syscall → local fork of redox_syscall
../../../../../recipes/core/base/libredox → local fork of libredox
How to Make a Recipe Depend on the Fork
Option A: Direct path dependency (preferred for direct deps)
[dependencies]
redox_syscall = { path = "../../../../../recipes/core/base/syscall", features = ["std"] }
libredox = { path = "../../../../../recipes/core/base/libredox" }
Option B: Version dep + patch redirect (when transitive deps also need redirection)
[dependencies]
redox_syscall = { version = "0.8", features = ["std"] }
libredox = "0.1"
daemon = { path = "../../../../../recipes/core/base/source/daemon" }
[patch.crates-io]
redox_syscall = { path = "../../../../../recipes/core/base/syscall" }
libredox = { path = "../../../../../recipes/core/base/libredox" }
Use Option B when the recipe depends on ANY base workspace member via path (daemon,
scheme-utils, etc.). The [patch] entries redirect ALL transitive redox_syscall and
libredox dependencies (from redox-scheme, etc.) to the local fork.
Symlinks required
The paths above resolve through symlinks that must exist:
recipes/core/base/syscall → ../../../local/sources/syscall
recipes/core/base/libredox → ../../../local/sources/libredox
These symlinks bridge the base workspace's relative path resolution. Without them, the
base workspace's path = "../syscall" resolves to a non-existent directory.
Validation
Run the validation gate to check all recipes:
./target/release/repo validate-cargo-deps
This scans every Cargo.toml in recipes/ and local/recipes/, detects:
- Path dependencies on base workspace members without matching
[patch]entries - Version dependencies on forked packages that should use the local fork
- Missing or broken symlinks
Exit code 0 = all OK, exit code 1 = warnings found.
Recipes Currently Violating This Policy
As of 2026-07-02, the following recipes pull redox_syscall or libredox from crates.io
instead of the local fork. These are policy violations that should be fixed incrementally:
redox_syscall from crates.io (25 recipes)
Recipes using version 0.8 (straightforward conversion to fork):
drivers/ehcid,drivers/linux-kpi,drivers/redbear-btusbdrivers/redox-driver-syssystem/driver-manager,system/evdevd,system/firmware-loadersystem/hwrngd,system/iommusystem/redbear-btctl,system/redbear-hwutilssystem/redbear-sessiond,system/redbear-traceroutesystem/redbear-wifictl,system/thermald,system/udev-shimtui/tlc
Recipes using version 0.7 (need API adaptation to 0.8):
drivers/virtio-inputd,system/devfsd,system/diskd
Recipes using version 0.4 (need significant API adaptation to 0.8):
system/redbear-accessibility,system/redbear-ime,system/redbear-keymapdgpu/redox-drm(usessyscall04for legacy PCI config — separate concern)
libredox from crates.io (21 recipes)
All recipes using libredox = "0.1" or libredox = "0.1.x" from crates.io should
switch to the local fork at local/sources/libredox/ (version 0.1.18).
Migration Plan
- Phase 1 (done): Fix
redox-drm— the only recipe with a path dep ondaemon - Phase 2: Convert all 0.8.x recipes to use the local fork (straightforward)
- Phase 3: Adapt 0.7.x recipes to 0.8.x API and switch to fork
- Phase 4: Adapt 0.4.x recipes to 0.8.x API and switch to fork
Each conversion is: change version = "0.x" to path = "...", cook, fix any API breaks.
Related
local/AGENTS.md§ "GOLDEN RULE — Red Bear adapts to upstream, never the reverse"local/AGENTS.md§ "LOCAL FORK MODEL (CORE COMPONENTS)"local/sources/base/Cargo.tomllines 133-157 — the base workspace[patch]section that ONLY applies within the base workspace