|
1
|
--- |
|
2
|
name: forked-dependencies |
|
3
|
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. |
|
4
|
allowed-tools: Read, Write, Edit, Glob, Grep, Bash |
|
5
|
user-invocable: true |
|
6
|
--- |
|
7
|
|
|
8
|
# Skill: Forked Dependencies |
|
9
|
|
|
10
|
The onde stack pulls several crates from forks instead of crates.io. They exist |
|
11
|
for three reasons: **platform support** the upstream crate lacks (watchOS, |
|
12
|
visionOS), **unreleased APIs** a dependency needs before upstream cuts a release |
|
13
|
(candle), and **registry constraints** (`cargo publish` rejects git deps, so the |
|
14
|
mistral.rs fork is republished under `onde-*` names). |
|
15
|
|
|
16
|
This skill is the single source of truth for every fork and patch. When a build |
|
17
|
breaks on a missing symbol or unsupported target, or you are bumping a fork, |
|
18
|
start here. |
|
19
|
|
|
20
|
--- |
|
21
|
|
|
22
|
## The two-tier consumption model (read this first) |
|
23
|
|
|
24
|
There are two distinct ways the same dependency tree gets built, and they |
|
25
|
resolve forks differently. Almost every confusing bug in this area comes from |
|
26
|
mixing them up. |
|
27
|
|
|
28
|
1. **Building the mistral.rs fork from source** (its own CI, or `onde` local dev |
|
29
|
with the git override uncommented). Here the fork's `Cargo.toml` git deps and |
|
30
|
`[patch.crates-io]` entries apply directly. |
|
31
|
|
|
32
|
2. **Publishing to crates.io** (`cargo publish` of the `onde-mistralrs-*` |
|
33
|
crates). **`cargo publish` strips every `git =` field and the entire |
|
34
|
`[patch.crates-io]` table.** Published crates fall back to the `version = "..."` |
|
35
|
registry requirement on each dep. So a git-only dep is invisible to anyone |
|
36
|
installing from crates.io. |
|
37
|
|
|
38
|
3. **onde consuming the published crates.** onde depends on the registry |
|
39
|
`onde-mistralrs-*` crates, so it gets the *registry-resolved* tree — the |
|
40
|
stripped-down one from step 2, not the fork's git tree. onde then re-applies |
|
41
|
whatever patches it still needs in **its own** `[patch.crates-io]`. Those |
|
42
|
apply to onde's from-source CI builds (Swift XCFramework, Android/Kotlin, |
|
43
|
the `cargo check` matrix) but are themselves stripped when onde publishes to |
|
44
|
crates.io. |
|
45
|
|
|
46
|
**Consequence that used to bite (now fixed — kept as the canonical example):** |
|
47
|
originally the `tqdm` fork bumped crossterm to 0.29 (which pulls mio 1.x, which |
|
48
|
supports visionOS) but was a *git* dep of mistral.rs, so it was stripped on |
|
49
|
publish. onde therefore resolved crates.io `tqdm 0.8.0` → `crossterm 0.25` → |
|
50
|
`mio 0.8.11`, which does *not* support visionOS — so onde needed its own `mio` |
|
51
|
visionOS patch even though the tqdm fork "already fixed" crossterm upstream of |
|
52
|
it. |
|
53
|
|
|
54
|
The fix that removed the whole problem was to make the crossterm-0.29 tqdm a |
|
55
|
**registry** dep of the mistral.rs fork rather than a git one, since a registry |
|
56
|
dep survives publish: onde's resolved tree then gets `crossterm 0.29` → `mio |
|
57
|
1.x` and the `mio 0.8.11` line disappears entirely. That shipped first as the |
|
58
|
stopgap fork crate `onde-tqdm` (in `onde-mistralrs-*` 0.9.3), which let onde |
|
59
|
delete its `[patch.crates-io] mio` entry and retire the `mio` fork. |
|
60
|
|
|
61
|
Upstream has since merged the crossterm bump (mrlazy1708/tqdm#28) and released |
|
62
|
it as **`tqdm 0.8.1`**, so the fork crate is no longer needed: the mistral.rs |
|
63
|
fork depends on plain `tqdm = "0.8.1"` and **`onde-tqdm` is retired**. See the |
|
64
|
tqdm and mio entries. |
|
65
|
|
|
66
|
--- |
|
67
|
|
|
68
|
## Inventory |
|
69
|
|
|
70
|
| Crate | Fork / source | Ref | Purpose | Consumed where | |
|
71
|
|-------|---------------|-----|---------|----------------| |
|
72
|
| mistral.rs (12 crates) | `setoelkahfi/mistral.rs` | branch `fix/all-platform-fixes` | All-platform fixes; **published** as `onde-mistralrs-*` | onde deps (registry) | |
|
73
|
| 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) | |
|
74
|
| 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) | |
|
75
|
| sysctl | `setoelkahfi/sysctl-rs` | branch `feature/watchos` | watchOS (`target_os = "watchos"`) support | `[patch.crates-io]` in onde **and** mistral.rs fork | |
|
76
|
| 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. | |
|
77
|
|
|
78
|
> **Retired:** `onde-tqdm` (`setoelkahfi/tqdm`, branch `release/onde-tqdm`, |
|
79
|
> published 0.8.1/0.8.2) — the stopgap republish of the crossterm-0.29 tqdm |
|
80
|
> fork. Upstream merged the bump and released `tqdm 0.8.1`, so the mistral.rs |
|
81
|
> fork now depends on upstream directly. See the tqdm entry. |
|
82
|
|
|
83
|
> **Retired:** `core2` (`bbqsrc/core2` rev `545e84bc`) — was a `[patch.crates-io]` |
|
84
|
> workaround for the yanked `core2 0.4.0`; removed from the mistral.rs fork after |
|
85
|
> `bitstream-io` 4.x dropped `core2`. No longer present. |
|
86
|
|
|
87
|
--- |
|
88
|
|
|
89
|
## Per-fork detail |
|
90
|
|
|
91
|
### mistral.rs → `onde-mistralrs-*` |
|
92
|
|
|
93
|
- **Fork:** `setoelkahfi/mistral.rs`, branch `fix/all-platform-fixes`. |
|
94
|
- **Why:** carries fixes upstream hasn't merged (iOS 32-bit memory limits, |
|
95
|
watchOS/visionOS Metal compile, Android 32-bit const overflows, HF cache |
|
96
|
seeding, metallib link flags, and more). |
|
97
|
- **Published as:** `onde-mistralrs`, `-core`, `-quant`, `-paged-attn`, |
|
98
|
`-flash-attn`, `-metal-compile`, `-code-exec`, `-sandbox`, `-macros`, |
|
99
|
`-vision`, `-audio`, `-mcp`. The rename is a `package = "onde-..."` override on |
|
100
|
each workspace dep entry, so Rust source still `use`s `mistralrs_*` unchanged. |
|
101
|
- **Publishing + bump flow:** see [[sdk-regressions]] (the 12-crate publish |
|
102
|
order, the candle Step 0, and the tqdm/core2 publish-verification snags). |
|
103
|
|
|
104
|
### candle → `onde-candle-{core,nn}` |
|
105
|
|
|
106
|
- **Fork:** `setoelkahfi/candle`, branch `onde/candle-<ver>-<rev>` (currently |
|
107
|
`onde/candle-0.11.0-27f20fea`). |
|
108
|
- **Why:** mistral.rs pins a candle git rev past the latest release for APIs no |
|
109
|
published candle has (`QTensor::indexed_gemv`, `gemv_fused_shared_lhs`, |
|
110
|
`BarrierPool::execute_chunked`). Publishing the `onde-mistralrs-*` crates |
|
111
|
fails verification (E0080/E0599) if their candle dep resolves to the released |
|
112
|
crate, so the pinned rev is republished under `onde-candle-*`. |
|
113
|
- **Only the diverged crates are renamed.** At the 0.11.0 rev only `candle-core` |
|
114
|
and `candle-nn` differ from the release; `candle-metal-kernels` and |
|
115
|
`candle-flash-attn-v3` are byte-identical, so the mistral.rs fork points those |
|
116
|
at the official `0.11.0` crates. `candle-nn` must be republished whenever |
|
117
|
`candle-core` is (even if unchanged) or the official `candle-nn` drags the |
|
118
|
official `candle-core` back into the graph → two `candle-core` crates → type |
|
119
|
mismatch. |
|
120
|
|
|
121
|
### sysctl → watchOS |
|
122
|
|
|
123
|
- **Fork:** `setoelkahfi/sysctl-rs`, branch `feature/watchos`. Upstream PR: |
|
124
|
johalun/sysctl-rs#74. |
|
125
|
- **Why:** upstream sysctl has no `target_os = "watchos"` support. |
|
126
|
- **Applied in:** `[patch.crates-io]` in **both** onde and the mistral.rs fork |
|
127
|
(each workspace root that builds for watchOS needs its own patch entry). |
|
128
|
|
|
129
|
### mio → visionOS (RETIRED) |
|
130
|
|
|
131
|
- **Status:** the onde `[patch.crates-io] mio` entry has been **removed**. onde |
|
132
|
now consumes `onde-mistralrs 0.9.3`, whose `onde-tqdm` dep pulls `crossterm |
|
133
|
0.29 → mio 1.x`, so `mio 0.8.11` is gone from onde's tree. The fork below is |
|
134
|
kept only for history and a possible upstream PR; it is no longer wired into |
|
135
|
any build. |
|
136
|
- **Fork:** `setoelkahfi/mio`, branch `feature/visionos` (commit `683fca8`). |
|
137
|
Based on `mio 0.8.11`. This is the **official GitHub fork** of tokio-rs/mio |
|
138
|
(in tokio's fork network, so it can open upstream PRs). An earlier standalone |
|
139
|
clone that carried this branch was renamed to `setoelkahfi/mio-patch` and |
|
140
|
deleted; the branch now lives on the real fork. |
|
141
|
- **Why:** `mio 0.8.11` hits `compile_error!("unsupported target for |
|
142
|
mio::unix::pipe")` on visionOS, and its Apple cfg gates (kqueue `Filter`/ |
|
143
|
`Flags` type aliases, `net.rs` `sin_len`/`sin6_len`, `tcp.rs` accept path, |
|
144
|
`uds/listener.rs` `accept4`/`SOCK_NONBLOCK`) omit visionos, breaking the Swift |
|
145
|
XCFramework build and the visionOS CI checks. The fork adds |
|
146
|
`target_os = "visionos"` to every cfg gate that already lists `tvos`/`watchos`. |
|
147
|
tokio's `mio 1.x` already supports visionOS, so **only the 0.8.x line** needs it. |
|
148
|
- **Where 0.8.11 came from:** `tqdm → crossterm 0.25 → mio 0.8.11`, and |
|
149
|
`signal-hook-mio → crossterm`. Not from tokio (that uses `mio 1.2.2`). |
|
150
|
- **Applied in:** *(historical)* was `[patch.crates-io]` in onde. The fork's |
|
151
|
version (`0.8.11`) stayed semver-compatible with the `^0.8` requirement it |
|
152
|
replaced; it did not touch tokio's `^1`. |
|
153
|
- **How it was retired (the real fix):** the `onde-tqdm` publish (below) removed |
|
154
|
the `mio 0.8.11` line from onde's registry-resolved tree entirely. Verified: |
|
155
|
with onde consuming the onde-tqdm-carrying `onde-mistralrs 0.9.3` crates, onde's |
|
156
|
lockfile resolves `mio 1.2.2` only — no 0.8.11 — and both visionOS targets |
|
157
|
(`aarch64-apple-visionos{,-sim}`) `cargo +nightly check -Z build-std` pass with |
|
158
|
the `mio` patch deleted. |
|
159
|
|
|
160
|
### tqdm → upstream (`onde-tqdm` RETIRED) |
|
161
|
|
|
162
|
- **Status:** no fork. `setoelkahfi/tqdm` branch `deps/bump-crossterm` was |
|
163
|
merged upstream as mrlazy1708/tqdm#28 and released as **`tqdm 0.8.1`**, which |
|
164
|
carries the crossterm 0.29 bump (→ mio 1.x) that the whole `mio 0.8.11` |
|
165
|
visionOS problem hinged on. |
|
166
|
- **Consumed in:** the mistral.rs fork's `[workspace.dependencies]` as plain |
|
167
|
`tqdm = "0.8.1"`. It must stay a **registry** dep — `cargo publish` strips git |
|
168
|
deps, so a git tqdm would never reach onde. |
|
169
|
- **The `onde-tqdm` stopgap (retired):** branch `release/onde-tqdm` set |
|
170
|
`package = "onde-tqdm"` (lib name stayed `tqdm`, so `use tqdm::…` and doctests |
|
171
|
were unchanged) and was published as `onde-tqdm` 0.8.1/0.8.2 — the same rename |
|
172
|
trick as `onde-mistralrs-*` and `onde-candle-*`, needed only because upstream |
|
173
|
hadn't released the bump yet. Its source was byte-identical to upstream |
|
174
|
`tqdm 0.8.1` apart from the package metadata, so the swap back is a drop-in. |
|
175
|
- **Which release drops it:** `onde-mistralrs-core` 0.9.2 used plain |
|
176
|
`tqdm ^0.8.0` (crossterm 0.25), 0.9.3 used `onde-tqdm 0.8.2`, and the next |
|
177
|
publish (0.9.4) goes back to upstream `tqdm 0.8.1`. The published `onde-tqdm` |
|
178
|
versions stay up so 0.9.3 keeps resolving; don't yank them. |
|
179
|
|
|
180
|
### core2 → removed |
|
181
|
|
|
182
|
- **Was:** `bbqsrc/core2` rev `545e84bc`, a `[patch.crates-io]` workaround for |
|
183
|
the yanked `core2 0.4.0` (pulled via `bitstream-io → rav1e → ravif → image`). |
|
184
|
- **Status:** **deleted** from the mistral.rs fork. `bitstream-io` 4.x moved off |
|
185
|
`core2` (to `no_std_io2`), so nothing pulls it. Removed in the same commit that |
|
186
|
wired `onde-tqdm` and bumped to 0.9.3. |
|
187
|
|
|
188
|
--- |
|
189
|
|
|
190
|
## Operational gotchas (hit these during the 1.2.1 release) |
|
191
|
|
|
192
|
- **A patched fork must be pushed to GitHub before the patch works in CI.** The |
|
193
|
`mio` fork existed only locally; the patch URL 404'd until it was pushed to |
|
194
|
`setoelkahfi/mio`. Verify with `git ls-remote <url> <branch>` before relying |
|
195
|
on a patch. |
|
196
|
- **Shallow clones cannot be pushed** (`remote unpack failed: index-pack |
|
197
|
failed`). If a fork was cloned shallow, `git fetch --unshallow <upstream>` |
|
198
|
first, then push. |
|
199
|
- **Local fork fetches need `CARGO_NET_GIT_FETCH_WITH_CLI=true`.** This machine |
|
200
|
rewrites GitHub URLs to SSH aliases; cargo's built-in fetcher can't auth, so |
|
201
|
export that var (or run the `cargo update` that pulls the fork with it). CI |
|
202
|
fetches public https forks fine without it — same as the long-standing sysctl |
|
203
|
patch. |
|
204
|
- **`[patch.crates-io]` version must be semver-compatible** with the requirement |
|
205
|
it replaces. A `0.8.11` fork replaces `^0.8`, not a `^1` requirement of the |
|
206
|
same crate — which is how the `mio` patch touches only the crossterm line and |
|
207
|
leaves tokio's `mio 1.x` alone. |
|
208
|
- **Forks are public** (mio, sysctl-rs, tqdm are MIT/Apache): keep the upstream |
|
209
|
`LICENSE` intact. See [[legal-and-trademarks]] for attribution obligations |
|
210
|
(candle and mistral.rs especially). |
|
211
|
|
|
212
|
--- |
|
213
|
|
|
214
|
## Adding a new patch |
|
215
|
|
|
216
|
1. Fork upstream, add the fix on a descriptive branch, **push it public** to |
|
217
|
`setoelkahfi/<crate>`, keep the `LICENSE`. |
|
218
|
2. Add to `[patch.crates-io]` in every workspace root that builds the affected |
|
219
|
target (onde, and the mistral.rs fork if it builds there too). Match the |
|
220
|
fork's crate version to the requirement being replaced. |
|
221
|
3. `CARGO_NET_GIT_FETCH_WITH_CLI=true cargo update -p <crate>@<ver>` to move the |
|
222
|
lockfile onto the git source; verify `source = "git+..."` in `Cargo.lock`. |
|
223
|
4. If it fixes a mistral.rs-fork build (not just onde), remember it is stripped |
|
224
|
on publish — onde will still need its own copy of the patch unless the fix |
|
225
|
also lands in a published `onde-*` crate. |
|
226
|
5. `cargo check` on host, then let CI validate the target that was failing. |
|
227
|
|
|
228
|
--- |
|
229
|
|
|
230
|
*Update this skill whenever a fork's branch/rev changes, a patch is added or |
|
231
|
removed, or a fork gets published under an `onde-*` name.* |