development
name: forked-dependencies description: The complete inventory of forked crates and [patch.crates-io] overrides that the onde stack depends on — mistral.rs, candle, sysctl, mio, tqdm, core2 — including the retired ones. Explains what each fork is for, where it is consumed, how the git-vs-published two-tier model works, and how to update or add one. Apply whenever a build fails on a missing/incompatible crate for an Apple or Android target, when bumping the mistral.rs or candle fork, or when adding a new patched dependency. allowed-tools: Read, Write, Edit, Glob, Grep, Bash
user-invocable: true
Skill: Forked Dependencies
The onde stack pulls several crates from forks instead of crates.io. They exist
for three reasons: platform support the upstream crate lacks (watchOS,
visionOS), unreleased APIs a dependency needs before upstream cuts a release
(candle), and registry constraints (cargo publish rejects git deps, so the
mistral.rs fork is republished under onde-* names).
This skill is the single source of truth for every fork and patch. When a build breaks on a missing symbol or unsupported target, or you are bumping a fork, start here.
The two-tier consumption model (read this first)
There are two distinct ways the same dependency tree gets built, and they resolve forks differently. Almost every confusing bug in this area comes from mixing them up.
Building the mistral.rs fork from source (its own CI, or
ondelocal dev with the git override uncommented). Here the fork'sCargo.tomlgit deps and[patch.crates-io]entries apply directly.Publishing to crates.io (
cargo publishof theonde-mistralrs-*crates).cargo publishstrips everygit =field and the entire[patch.crates-io]table. Published crates fall back to theversion = "..."registry requirement on each dep. So a git-only dep is invisible to anyone installing from crates.io.onde consuming the published crates. onde depends on the registry
onde-mistralrs-*crates, so it gets the registry-resolved tree — the stripped-down one from step 2, not the fork's git tree. onde then re-applies whatever patches it still needs in its own[patch.crates-io]. Those apply to onde's from-source CI builds (Swift XCFramework, Android/Kotlin, thecargo checkmatrix) but are themselves stripped when onde publishes to crates.io.
Consequence that used to bite (now fixed — kept as the canonical example):
originally the tqdm fork bumped crossterm to 0.29 (which pulls mio 1.x, which
supports visionOS) but was a git dep of mistral.rs, so it was stripped on
publish. onde therefore resolved crates.io tqdm 0.8.0 → crossterm 0.25 →
mio 0.8.11, which does not support visionOS — so onde needed its own mio
visionOS patch even though the tqdm fork "already fixed" crossterm upstream of
it.
The fix that removed the whole problem was to make the crossterm-0.29 tqdm a
registry dep of the mistral.rs fork rather than a git one, since a registry
dep survives publish: onde's resolved tree then gets crossterm 0.29 → mio
1.x and the mio 0.8.11 line disappears entirely. That shipped first as the
stopgap fork crate onde-tqdm (in onde-mistralrs-* 0.9.3), which let onde
delete its [patch.crates-io] mio entry and retire the mio fork.
Upstream has since merged the crossterm bump (mrlazy1708/tqdm#28) and released
it as tqdm 0.8.1, so the fork crate is no longer needed: the mistral.rs
fork depends on plain tqdm = "0.8.1" and onde-tqdm is retired. See the
tqdm and mio entries.
Inventory
| Crate | Fork / source | Ref | Purpose | Consumed where |
|---|---|---|---|---|
| mistral.rs (12 crates) | setoelkahfi/mistral.rs |
branch fix/all-platform-fixes |
All-platform fixes; published as onde-mistralrs-* |
onde deps (registry) |
| candle-core, candle-nn | setoelkahfi/candle |
branch onde/candle-0.11.0-27f20fea (rev 27f20fea) |
Post-0.11.0 candle APIs; published as onde-candle-{core,nn} |
mistral.rs fork deps (registry) |
| tqdm | none — upstream | crates.io tqdm 0.8.1 |
Crossterm 0.29 (→ mio 1.x) is upstream as of 0.8.1 | mistral.rs fork dep (registry) |
| sysctl | setoelkahfi/sysctl-rs |
branch feature/watchos |
watchOS (target_os = "watchos") support |
[patch.crates-io] in onde and mistral.rs fork |
| mio | setoelkahfi/mio |
branch feature/visionos |
visionOS support for the mio 0.8.11 line |
RETIRED — patch removed from onde once it consumed onde-mistralrs 0.9.3 (crossterm 0.29 → mio 1.x). Fork kept for history/upstream PR. |
Retired:
onde-tqdm(setoelkahfi/tqdm, branchrelease/onde-tqdm, published 0.8.1/0.8.2) — the stopgap republish of the crossterm-0.29 tqdm fork. Upstream merged the bump and releasedtqdm 0.8.1, so the mistral.rs fork now depends on upstream directly. See the tqdm entry.Retired:
core2(bbqsrc/core2rev545e84bc) — was a[patch.crates-io]workaround for the yankedcore2 0.4.0; removed from the mistral.rs fork afterbitstream-io4.x droppedcore2. No longer present.
Per-fork detail
mistral.rs → onde-mistralrs-*
- Fork:
setoelkahfi/mistral.rs, branchfix/all-platform-fixes. - Why: carries fixes upstream hasn't merged (iOS 32-bit memory limits, watchOS/visionOS Metal compile, Android 32-bit const overflows, HF cache seeding, metallib link flags, and more).
- Published as:
onde-mistralrs,-core,-quant,-paged-attn,-flash-attn,-metal-compile,-code-exec,-sandbox,-macros,-vision,-audio,-mcp. The rename is apackage = "onde-..."override on each workspace dep entry, so Rust source stillusesmistralrs_*unchanged. - Publishing + bump flow: see [sdk-regressions].
candle → onde-candle-{core,nn}
- Fork:
setoelkahfi/candle, branchonde/candle-<ver>-<rev>(currentlyonde/candle-0.11.0-27f20fea). - Why: mistral.rs pins a candle git rev past the latest release for APIs no
published candle has (
QTensor::indexed_gemv,gemv_fused_shared_lhs,BarrierPool::execute_chunked). Publishing theonde-mistralrs-*crates fails verification (E0080/E0599) if their candle dep resolves to the released crate, so the pinned rev is republished underonde-candle-*. - Only the diverged crates are renamed. At the 0.11.0 rev only
candle-coreandcandle-nndiffer from the release;candle-metal-kernelsandcandle-flash-attn-v3are byte-identical, so the mistral.rs fork points those at the official0.11.0crates.candle-nnmust be republished whenevercandle-coreis (even if unchanged) or the officialcandle-nndrags the officialcandle-coreback into the graph → twocandle-corecrates → type mismatch.
sysctl → watchOS
- Fork:
setoelkahfi/sysctl-rs, branchfeature/watchos. Upstream PR: johalun/sysctl-rs#74. - Why: upstream sysctl has no
target_os = "watchos"support. - Applied in:
[patch.crates-io]in both onde and the mistral.rs fork (each workspace root that builds for watchOS needs its own patch entry).
mio → visionOS (RETIRED)
- Status: the onde
[patch.crates-io] mioentry has been removed. onde now consumesonde-mistralrs 0.9.3, whoseonde-tqdmdep pullscrossterm 0.29 → mio 1.x, somio 0.8.11is gone from onde's tree. The fork below is kept only for history and a possible upstream PR; it is no longer wired into any build. - Fork:
setoelkahfi/mio, branchfeature/visionos(commit683fca8). Based onmio 0.8.11. This is the official GitHub fork of tokio-rs/mio (in tokio's fork network, so it can open upstream PRs). An earlier standalone clone that carried this branch was renamed tosetoelkahfi/mio-patchand deleted; the branch now lives on the real fork. - Why:
mio 0.8.11hitscompile_error!("unsupported target for mio::unix::pipe")on visionOS, and its Apple cfg gates (kqueueFilter/Flagstype aliases,net.rssin_len/sin6_len,tcp.rsaccept path,uds/listener.rsaccept4/SOCK_NONBLOCK) omit visionos, breaking the Swift XCFramework build and the visionOS CI checks. The fork addstarget_os = "visionos"to every cfg gate that already liststvos/watchos. tokio'smio 1.xalready supports visionOS, so only the 0.8.x line needs it. - Where 0.8.11 came from:
tqdm → crossterm 0.25 → mio 0.8.11, andsignal-hook-mio → crossterm. Not from tokio (that usesmio 1.2.2). - Applied in: (historical) was
[patch.crates-io]in onde. The fork's version (0.8.11) stayed semver-compatible with the^0.8requirement it replaced; it did not touch tokio's^1. - How it was retired (the real fix): the
onde-tqdmpublish (below) removed themio 0.8.11line from onde's registry-resolved tree entirely. Verified: with onde consuming the onde-tqdm-carryingonde-mistralrs 0.9.3crates, onde's lockfile resolvesmio 1.2.2only — no 0.8.11 — and both visionOS targets (aarch64-apple-visionos{,-sim})cargo +nightly check -Z build-stdpass with themiopatch deleted.
tqdm → upstream (onde-tqdm RETIRED)
- Status: no fork.
setoelkahfi/tqdmbranchdeps/bump-crosstermwas merged upstream as mrlazy1708/tqdm#28 and released astqdm 0.8.1, which carries the crossterm 0.29 bump (→ mio 1.x) that the wholemio 0.8.11visionOS problem hinged on. - Consumed in: the mistral.rs fork's
[workspace.dependencies]as plaintqdm = "0.8.1". It must stay a registry dep —cargo publishstrips git deps, so a git tqdm would never reach onde. - The
onde-tqdmstopgap (retired): branchrelease/onde-tqdmsetpackage = "onde-tqdm"(lib name stayedtqdm, souse tqdm::…and doctests were unchanged) and was published asonde-tqdm0.8.1/0.8.2 — the same rename trick asonde-mistralrs-*andonde-candle-*, needed only because upstream hadn't released the bump yet. Its source was byte-identical to upstreamtqdm 0.8.1apart from the package metadata, so the swap back is a drop-in. - Which release drops it:
onde-mistralrs-core0.9.2 used plaintqdm ^0.8.0(crossterm 0.25), 0.9.3 usedonde-tqdm 0.8.2, and the next publish (0.9.4) goes back to upstreamtqdm 0.8.1. The publishedonde-tqdmversions stay up so 0.9.3 keeps resolving; don't yank them.
core2 → removed
- Was:
bbqsrc/core2rev545e84bc, a[patch.crates-io]workaround for the yankedcore2 0.4.0(pulled viabitstream-io → rav1e → ravif → image). - Status: deleted from the mistral.rs fork.
bitstream-io4.x moved offcore2(tono_std_io2), so nothing pulls it. Removed in the same commit that wiredonde-tqdmand bumped to 0.9.3.
Operational gotchas (hit these during the 1.2.1 release)
- A patched fork must be pushed to GitHub before the patch works in CI. The
miofork existed only locally; the patch URL 404'd until it was pushed tosetoelkahfi/mio. Verify withgit ls-remote <url> <branch>before relying on a patch. - Shallow clones cannot be pushed (
remote unpack failed: index-pack failed). If a fork was cloned shallow,git fetch --unshallow <upstream>first, then push. - Local fork fetches need
CARGO_NET_GIT_FETCH_WITH_CLI=true. This machine rewrites GitHub URLs to SSH aliases; cargo's built-in fetcher can't auth, so export that var (or run thecargo updatethat pulls the fork with it). CI fetches public https forks fine without it — same as the long-standing sysctl patch. [patch.crates-io]version must be semver-compatible with the requirement it replaces. A0.8.11fork replaces^0.8, not a^1requirement of the same crate — which is how themiopatch touches only the crossterm line and leaves tokio'smio 1.xalone.- Forks are public (mio, sysctl-rs, tqdm are MIT/Apache): keep the upstream
LICENSEintact. See [[legal-and-trademarks]] for attribution obligations (candle and mistral.rs especially).
Adding a new patch
- Fork upstream, add the fix on a descriptive branch, push it public to
setoelkahfi/<crate>, keep theLICENSE. - Add to
[patch.crates-io]in every workspace root that builds the affected target (onde, and the mistral.rs fork if it builds there too). Match the fork's crate version to the requirement being replaced. CARGO_NET_GIT_FETCH_WITH_CLI=true cargo update -p <crate>@<ver>to move the lockfile onto the git source; verifysource = "git+..."inCargo.lock.- If it fixes a mistral.rs-fork build (not just onde), remember it is stripped
on publish — onde will still need its own copy of the patch unless the fix
also lands in a published
onde-*crate. cargo checkon host, then let CI validate the target that was failing.
Update this skill whenever a fork's branch/rev changes, a patch is added or removed, or a fork gets published under an `onde-` name.*