From 15749cf8e9c5ae889818cfe696f48f86afb42120 Mon Sep 17 00:00:00 2001 From: Kaden Schutt Date: Fri, 4 Sep 2026 09:04:32 +0000 Subject: [PATCH 1/8] chore(deps): drop declared-but-unused dependencies; single radiowave member cargo-machete pass over the workspace: hipfire-daemon (hipfire-dispatch, saddle-core, serde), hipfire-engine (hipfire-config, hipfire-dispatch, serde, tracing), hipfire-generate (hipfire-config, hipfire-dispatch, serde), saddle-quant (half, hipfire-config, hipfire-runtime, rayon), hipfire-pflash (serde, serde_json), hipfire-runtime (base64), hip-bridge/hsa-bridge (thiserror), hipfire-arch-toy (hip-bridge), serde in client/qwen35-vl/lfm2-vl/muse-glimmer/gemma4/saddle-core, memmap2 in deepseek4. Every removal verified by whole-crate grep and `cargo check -p --all-targets` (saddle-lab with --all-features: 56 examples). hipfire-daemon keeps dispatch/deltanet via hipfire-runtime (cargo tree -e features). crates/radiowave was listed twice in [workspace].members. Comment-only truth fixes in radiowave/Cargo.toml (workspace license is Apache-2.0) and hipfire-daemon/Cargo.toml (arches arrive via loader/generate). cargo machete: clean. --- Cargo.lock | 48 +-------------------- Cargo.toml | 1 - crates/hip-bridge/Cargo.toml | 1 - crates/hipfire-arch-deepseek4/Cargo.toml | 1 - crates/hipfire-arch-gemma4/Cargo.toml | 1 - crates/hipfire-arch-lfm2-vl/Cargo.toml | 1 - crates/hipfire-arch-muse-glimmer/Cargo.toml | 1 - crates/hipfire-arch-qwen35-vl/Cargo.toml | 1 - crates/hipfire-arch-toy/Cargo.toml | 1 - crates/hipfire-client/Cargo.toml | 1 - crates/hipfire-daemon/Cargo.toml | 7 +-- crates/hipfire-engine/Cargo.toml | 4 -- crates/hipfire-generate/Cargo.toml | 3 -- crates/hipfire-pflash/Cargo.toml | 2 - crates/hipfire-runtime/Cargo.toml | 1 - crates/hsa-bridge/Cargo.toml | 1 - crates/radiowave/Cargo.toml | 8 ++-- crates/saddle-core/Cargo.toml | 1 - crates/saddle-lab/Cargo.toml | 25 +++-------- crates/saddle-quant/Cargo.toml | 7 --- 20 files changed, 11 insertions(+), 105 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ac6a8af13b..17edf592fe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1102,7 +1102,6 @@ dependencies = [ "hipfire-config", "libloading", "redline-rocr", - "thiserror 2.0.18", ] [[package]] @@ -1129,7 +1128,6 @@ dependencies = [ "hipfire-reap", "hipfire-runtime", "libloading", - "memmap2", "rdna-compute", "saddle-core", "serde", @@ -1158,7 +1156,6 @@ dependencies = [ "hipfire-dispatch", "hipfire-runtime", "rdna-compute", - "serde", "serde_json", ] @@ -1171,7 +1168,6 @@ dependencies = [ "image", "libm", "rdna-compute", - "serde", "serde_json", ] @@ -1236,7 +1232,6 @@ dependencies = [ "hipfire-dispatch", "hipfire-runtime", "rdna-compute", - "serde", "serde_json", ] @@ -1278,7 +1273,6 @@ dependencies = [ "hipfire-runtime", "image", "rdna-compute", - "serde", "serde_json", ] @@ -1286,7 +1280,6 @@ dependencies = [ name = "hipfire-arch-toy" version = "0.3.0" dependencies = [ - "hip-bridge", "hipfire-runtime", "rdna-compute", ] @@ -1330,7 +1323,6 @@ name = "hipfire-client" version = "0.3.0" dependencies = [ "hipfire-config", - "serde", "serde_json", "thiserror 2.0.18", "ureq", @@ -1354,7 +1346,6 @@ dependencies = [ "hip-bridge", "hipfire-arch-qwen35", "hipfire-config", - "hipfire-dispatch", "hipfire-engine", "hipfire-generate", "hipfire-loader", @@ -1362,8 +1353,6 @@ dependencies = [ "hipfire-runtime", "libc", "rdna-compute", - "saddle-core", - "serde", "serde_json", "tracing", "tracing-subscriber", @@ -1416,15 +1405,11 @@ name = "hipfire-engine" version = "0.3.0" dependencies = [ "hip-bridge", - "hipfire-config", - "hipfire-dispatch", "hipfire-loader", "hipfire-runtime", "rdna-compute", "saddle-core", - "serde", "serde_json", - "tracing", ] [[package]] @@ -1446,15 +1431,12 @@ dependencies = [ "hipfire-arch-qwen2", "hipfire-arch-qwen35", "hipfire-arch-qwen35-vl", - "hipfire-config", - "hipfire-dispatch", "hipfire-engine", "hipfire-loader", "hipfire-pflash", "hipfire-runtime", "rdna-compute", "saddle-core", - "serde", "serde_json", "tracing", ] @@ -1494,8 +1476,6 @@ dependencies = [ "hipfire-dispatch", "hipfire-runtime", "rdna-compute", - "serde", - "serde_json", ] [[package]] @@ -1546,7 +1526,6 @@ dependencies = [ name = "hipfire-runtime" version = "0.3.0" dependencies = [ - "base64", "byteorder", "half", "hip-bridge", @@ -1590,6 +1569,7 @@ name = "hipfire-tui" version = "0.3.0" dependencies = [ "anyhow", + "base64", "crossterm", "hipfire-client", "hipfire-config", @@ -1607,7 +1587,6 @@ dependencies = [ "hip-bridge", "hipfire-config", "libloading", - "thiserror 2.0.18", ] [[package]] @@ -2878,49 +2857,28 @@ version = "0.3.0" dependencies = [ "hip-bridge", "rdna-compute", - "serde", ] [[package]] name = "saddle-lab" version = "0.3.0" dependencies = [ - "base64", "byteorder", - "half", "hip-bridge", - "hipfire-arch-cohere2moe", - "hipfire-arch-deepseek4", - "hipfire-arch-dots-ocr", "hipfire-arch-gemma4", "hipfire-arch-lfm2moe", "hipfire-arch-llama", - "hipfire-arch-minimax", "hipfire-arch-muse-glimmer", - "hipfire-arch-qwen2", "hipfire-arch-qwen35", "hipfire-arch-qwen35-vl", - "hipfire-atlas", "hipfire-config", "hipfire-detect", "hipfire-dispatch", - "hipfire-engine", - "hipfire-loader", - "hipfire-pflash", "hipfire-runtime", "libc", - "memmap2", - "minijinja", - "minijinja-contrib", - "rayon", "rdna-compute", - "regex", - "saddle-core", - "safetensors", "serde", "serde_json", - "smallvec", - "tracing", ] [[package]] @@ -2928,13 +2886,9 @@ name = "saddle-quant" version = "0.3.0" dependencies = [ "clap", - "half", - "hipfire-config", - "hipfire-runtime", "memmap2", "minijinja", "minijinja-contrib", - "rayon", "serde", "serde_json", "sha2", diff --git a/Cargo.toml b/Cargo.toml index 1f764a9b7b..2295f00545 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,6 @@ members = [ "crates/redline", "crates/redline-rocr", "crates/redline-dispatch", - "crates/radiowave", "crates/hipfire-dispatch", "crates/hipfire-dispatch-tests", "crates/hipfire-tui", diff --git a/crates/hip-bridge/Cargo.toml b/crates/hip-bridge/Cargo.toml index d359231adf..59ecf6390c 100644 --- a/crates/hip-bridge/Cargo.toml +++ b/crates/hip-bridge/Cargo.toml @@ -12,7 +12,6 @@ lab = [] [dependencies] hipfire-config = { path = "../hipfire-config" } libloading.workspace = true -thiserror = "2" [dev-dependencies] redline-rocr = { path = "../redline-rocr" } diff --git a/crates/hipfire-arch-deepseek4/Cargo.toml b/crates/hipfire-arch-deepseek4/Cargo.toml index 00b2e21a1d..9e0dd92ae1 100644 --- a/crates/hipfire-arch-deepseek4/Cargo.toml +++ b/crates/hipfire-arch-deepseek4/Cargo.toml @@ -21,7 +21,6 @@ serde_json = { version = "1", features = ["preserve_order"] } hipfire-dispatch = { path = "../hipfire-dispatch", features = ["from-hip-error"] } hipfire-reap = { path = "../hipfire-reap", default-features = false } saddle-core = { path = "../saddle-core" } -memmap2 = "0.9" [dev-dependencies] libloading.workspace = true diff --git a/crates/hipfire-arch-gemma4/Cargo.toml b/crates/hipfire-arch-gemma4/Cargo.toml index ce2765c2e5..448e33df84 100644 --- a/crates/hipfire-arch-gemma4/Cargo.toml +++ b/crates/hipfire-arch-gemma4/Cargo.toml @@ -21,7 +21,6 @@ hipfire-runtime = { path = "../hipfire-runtime" } hip-bridge = { path = "../hip-bridge" } rdna-compute = { path = "../rdna-compute" } hipfire-dispatch = { path = "../hipfire-dispatch" } -serde = { version = "1", features = ["derive"] } serde_json = "1" # --------------------------------------------------------------------------- diff --git a/crates/hipfire-arch-lfm2-vl/Cargo.toml b/crates/hipfire-arch-lfm2-vl/Cargo.toml index 8e26cfa218..775a690771 100644 --- a/crates/hipfire-arch-lfm2-vl/Cargo.toml +++ b/crates/hipfire-arch-lfm2-vl/Cargo.toml @@ -16,7 +16,6 @@ deltanet = ["hipfire-runtime/deltanet", "rdna-compute/deltanet"] hipfire-runtime = { path = "../hipfire-runtime" } hip-bridge = { path = "../hip-bridge" } rdna-compute = { path = "../rdna-compute" } -serde = { version = "1", features = ["derive"] } serde_json = "1" image = { version = "0.25", default-features = false, features = ["png", "jpeg"] } libm = "0.2" diff --git a/crates/hipfire-arch-muse-glimmer/Cargo.toml b/crates/hipfire-arch-muse-glimmer/Cargo.toml index ba06a25c56..612fbd5063 100644 --- a/crates/hipfire-arch-muse-glimmer/Cargo.toml +++ b/crates/hipfire-arch-muse-glimmer/Cargo.toml @@ -19,7 +19,6 @@ hipfire-runtime = { path = "../hipfire-runtime" } hip-bridge = { path = "../hip-bridge" } rdna-compute = { path = "../rdna-compute" } hipfire-dispatch = { path = "../hipfire-dispatch" } -serde = { version = "1", features = ["derive"] } serde_json = "1" # --------------------------------------------------------------------------- diff --git a/crates/hipfire-arch-qwen35-vl/Cargo.toml b/crates/hipfire-arch-qwen35-vl/Cargo.toml index 1e8654da49..7cbba19b7f 100644 --- a/crates/hipfire-arch-qwen35-vl/Cargo.toml +++ b/crates/hipfire-arch-qwen35-vl/Cargo.toml @@ -19,7 +19,6 @@ hipfire-config = { path = "../hipfire-config" } hipfire-runtime = { path = "../hipfire-runtime" } hip-bridge = { path = "../hip-bridge" } rdna-compute = { path = "../rdna-compute" } -serde = { version = "1", features = ["derive"] } serde_json = "1" # image preprocessing (PNG/JPEG decode + resize) for the vision encoder # input pipeline lives in this crate (`crate::image`). Same default-feature diff --git a/crates/hipfire-arch-toy/Cargo.toml b/crates/hipfire-arch-toy/Cargo.toml index 2b78af4c4e..ed7941e272 100644 --- a/crates/hipfire-arch-toy/Cargo.toml +++ b/crates/hipfire-arch-toy/Cargo.toml @@ -13,5 +13,4 @@ description = "Reference template for new arch crates: faithful skeleton of the [dependencies] hipfire-runtime = { path = "../hipfire-runtime" } -hip-bridge = { path = "../hip-bridge" } rdna-compute = { path = "../rdna-compute" } diff --git a/crates/hipfire-client/Cargo.toml b/crates/hipfire-client/Cargo.toml index 6e444c4a56..5805c422ae 100644 --- a/crates/hipfire-client/Cargo.toml +++ b/crates/hipfire-client/Cargo.toml @@ -6,7 +6,6 @@ license.workspace = true [dependencies] hipfire-config = { path = "../hipfire-config" } -serde = { version = "1", features = ["derive"] } serde_json = "1" thiserror = "2" ureq = "3" diff --git a/crates/hipfire-daemon/Cargo.toml b/crates/hipfire-daemon/Cargo.toml index a6dcda38d4..82f8a883df 100644 --- a/crates/hipfire-daemon/Cargo.toml +++ b/crates/hipfire-daemon/Cargo.toml @@ -14,12 +14,10 @@ default = ["deltanet"] deltanet = [ "hipfire-runtime/deltanet", "rdna-compute/deltanet", - "hipfire-dispatch/deltanet", "hipfire-pflash/deltanet", ] flash-attn-ck = [ "rdna-compute/flash-attn-ck", - "hipfire-dispatch/flash-attn-ck", "hipfire-runtime/flash-attn-ck", ] serve-fault-inject = ["hipfire-runtime/serve-fault-inject", "hipfire-generate/serve-fault-inject"] @@ -31,8 +29,6 @@ ep-fault-inject = ["hipfire-loader/ep-fault-inject", "hipfire-runtime/ep-fault-i hip-bridge = { path = "../hip-bridge" } hipfire-config = { path = "../hipfire-config" } rdna-compute = { path = "../rdna-compute" } -saddle-core = { path = "../saddle-core" } -hipfire-dispatch = { path = "../hipfire-dispatch" } hipfire-runtime = { path = "../hipfire-runtime" } hipfire-loader = { path = "../hipfire-loader" } hipfire-engine = { path = "../hipfire-engine" } @@ -40,11 +36,10 @@ hipfire-generate = { path = "../hipfire-generate" } hipfire-pflash = { path = "../hipfire-pflash" } hipfire-arch-qwen35 = { path = "../hipfire-arch-qwen35" } -# All arch crates — unconditional, no features. +# Arches via loader/generate; qwen35 direct for slots. # Direct external deps used by daemon.rs base64 = "0.22" -serde = { version = "1", features = ["derive"] } serde_json = { version = "1", features = ["preserve_order"] } tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter", "fmt", "json"] } diff --git a/crates/hipfire-engine/Cargo.toml b/crates/hipfire-engine/Cargo.toml index d2feeb5c8e..67ab49002e 100644 --- a/crates/hipfire-engine/Cargo.toml +++ b/crates/hipfire-engine/Cargo.toml @@ -7,12 +7,8 @@ description = "Architecture-neutral daemon machinery — scheduler, terminal con [dependencies] hip-bridge = { path = "../hip-bridge" } -hipfire-config = { path = "../hipfire-config" } hipfire-loader = { path = "../hipfire-loader" } hipfire-runtime = { path = "../hipfire-runtime" } -hipfire-dispatch = { path = "../hipfire-dispatch" } rdna-compute = { path = "../rdna-compute" } saddle-core = { path = "../saddle-core" } -serde = { version = "1", features = ["derive"] } serde_json = "1" -tracing = "0.1" diff --git a/crates/hipfire-generate/Cargo.toml b/crates/hipfire-generate/Cargo.toml index b23a5b9f76..f0241f746b 100644 --- a/crates/hipfire-generate/Cargo.toml +++ b/crates/hipfire-generate/Cargo.toml @@ -23,10 +23,8 @@ description = "Per-architecture generation bodies, lifted out of the daemon bina # generation code stays where it can actually see the architectures. [dependencies] hip-bridge = { path = "../hip-bridge" } -hipfire-config = { path = "../hipfire-config" } rdna-compute = { path = "../rdna-compute" } saddle-core = { path = "../saddle-core" } -hipfire-dispatch = { path = "../hipfire-dispatch" } hipfire-runtime = { path = "../hipfire-runtime" } hipfire-loader = { path = "../hipfire-loader" } hipfire-engine = { path = "../hipfire-engine" } @@ -45,7 +43,6 @@ hipfire-arch-maple = { path = "../hipfire-arch-maple" } hipfire-arch-gemma4 = { path = "../hipfire-arch-gemma4" } hipfire-arch-muse-glimmer = { path = "../hipfire-arch-muse-glimmer" } base64 = "0.22" -serde = { version = "1", features = ["derive"] } serde_json = { version = "1", features = ["preserve_order"] } tracing = "0.1" diff --git a/crates/hipfire-pflash/Cargo.toml b/crates/hipfire-pflash/Cargo.toml index 9de6d9b22e..e4a4c33f06 100644 --- a/crates/hipfire-pflash/Cargo.toml +++ b/crates/hipfire-pflash/Cargo.toml @@ -17,8 +17,6 @@ hipfire-dispatch = { path = "../hipfire-dispatch", features = ["from-hip-error"] rdna-compute = { path = "../rdna-compute" } hipfire-arch-qwen35 = { path = "../hipfire-arch-qwen35" } hipfire-config = { path = "../hipfire-config" } -serde = { version = "1", features = ["derive"] } -serde_json = "1" [[example]] name = "pflash_compress_demo" diff --git a/crates/hipfire-runtime/Cargo.toml b/crates/hipfire-runtime/Cargo.toml index e943b0d514..8e8488630c 100644 --- a/crates/hipfire-runtime/Cargo.toml +++ b/crates/hipfire-runtime/Cargo.toml @@ -66,7 +66,6 @@ serde = { version = "1", features = ["derive"] } # chat_template (HF apply_chat_template preserves insertion order). Feature- # unifies across the workspace build. serde_json = { version = "1", features = ["preserve_order"] } -base64 = "0.22" libc = "0.2" rayon = "1" # Inline-small token buffer for `spec::SpecStep::emit` — keeps the diff --git a/crates/hsa-bridge/Cargo.toml b/crates/hsa-bridge/Cargo.toml index 59b524ee6c..e04fe5d035 100644 --- a/crates/hsa-bridge/Cargo.toml +++ b/crates/hsa-bridge/Cargo.toml @@ -12,7 +12,6 @@ lab = [] [dependencies] hipfire-config = { path = "../hipfire-config" } libloading.workspace = true -thiserror = "2" [dev-dependencies] hip-bridge = { path = "../hip-bridge" } diff --git a/crates/radiowave/Cargo.toml b/crates/radiowave/Cargo.toml index 8537a60e68..30927f1620 100644 --- a/crates/radiowave/Cargo.toml +++ b/crates/radiowave/Cargo.toml @@ -7,10 +7,10 @@ # commit: f4a0994e2315645b74eef8dec9305c58d252e699 # path: crates/radiowave # -# This manifest is deliberately NOT workspace-inherited. hipfire's -# [workspace.package] is edition 2021 / license MIT, and does not define -# rust-version, authors, repository or homepage. radiowave is edition 2024 / -# Apache-2.0 — inheriting would fail to resolve AND misstate the license. +# This manifest is only partly workspace-inherited (version + license). +# hipfire's [workspace.package] is edition 2021 / license Apache-2.0, and does +# not define rust-version, authors, repository or homepage. radiowave is +# edition 2024 / Apache-2.0 — inheriting edition would fail to resolve. [package] name = "radiowave" version.workspace = true diff --git a/crates/saddle-core/Cargo.toml b/crates/saddle-core/Cargo.toml index 8f5a929047..6415674236 100644 --- a/crates/saddle-core/Cargo.toml +++ b/crates/saddle-core/Cargo.toml @@ -15,4 +15,3 @@ description = "saddle — target-agnostic model composition: grammar, KV, capabi [dependencies] rdna-compute = { path = "../rdna-compute" } hip-bridge = { path = "../hip-bridge" } -serde = { version = "1", features = ["derive"] } diff --git a/crates/saddle-lab/Cargo.toml b/crates/saddle-lab/Cargo.toml index d18fb866d4..4709815768 100644 --- a/crates/saddle-lab/Cargo.toml +++ b/crates/saddle-lab/Cargo.toml @@ -26,39 +26,19 @@ serve-fault-inject = [] hip-bridge = { path = "../hip-bridge" } hipfire-config = { path = "../hipfire-config" } rdna-compute = { path = "../rdna-compute" } -saddle-core = { path = "../saddle-core" } hipfire-dispatch = { path = "../hipfire-dispatch" } hipfire-runtime = { path = "../hipfire-runtime" } hipfire-arch-qwen35 = { path = "../hipfire-arch-qwen35" } hipfire-arch-qwen35-vl = { path = "../hipfire-arch-qwen35-vl" } hipfire-arch-llama = { path = "../hipfire-arch-llama" } -hipfire-arch-qwen2 = { path = "../hipfire-arch-qwen2" } hipfire-arch-lfm2moe = { path = "../hipfire-arch-lfm2moe" } -hipfire-arch-minimax = { path = "../hipfire-arch-minimax" } -hipfire-arch-cohere2moe = { path = "../hipfire-arch-cohere2moe" } -hipfire-arch-deepseek4 = { path = "../hipfire-arch-deepseek4" } -hipfire-arch-dots-ocr = { path = "../hipfire-arch-dots-ocr" } hipfire-arch-gemma4 = { path = "../hipfire-arch-gemma4" } hipfire-arch-muse-glimmer = { path = "../hipfire-arch-muse-glimmer" } -hipfire-pflash = { path = "../hipfire-pflash" } -hipfire-engine = { path = "../hipfire-engine" } -hipfire-loader = { path = "../hipfire-loader" } hipfire-detect = { path = "../hipfire-detect" } -hipfire-atlas = { path = "../hipfire-atlas" } -memmap2 = "0.9" -safetensors.workspace = true -half.workspace = true byteorder = "1" serde = { version = "1", features = ["derive"] } serde_json = { version = "1", features = ["preserve_order"] } -base64 = "0.22" libc = "0.2" -rayon = "1" -smallvec = "1" -regex = "1" -minijinja = { version = "2", features = ["loop_controls", "json", "preserve_order"] } -minijinja-contrib = { version = "2", features = ["pycompat"] } -tracing = "0.1" # ── Archived examples (relocated from hipfire-runtime) ─────────────────── # Each entry was `[[example]]` in hipfire-runtime/Cargo.toml with an identical @@ -273,3 +253,8 @@ required-features = [] [[example]] name = "imatrix_collect" required-features = [] + +[package.metadata.cargo-machete] +# byteorder: deliberately kept (workspace from_le_bytes convention); never referenced by path in code. +# hipfire-dispatch: no direct code reference, but [features].deltanet forwards hipfire-dispatch/deltanet. +ignored = ["byteorder", "hipfire-dispatch"] diff --git a/crates/saddle-quant/Cargo.toml b/crates/saddle-quant/Cargo.toml index ad2857e3ee..acc2a1b86c 100644 --- a/crates/saddle-quant/Cargo.toml +++ b/crates/saddle-quant/Cargo.toml @@ -14,18 +14,13 @@ license.workspace = true [features] default = [] -# Forward-pass-dependent surface: teacher oracle construction + candidate -# scoring. Pulls the runtime and therefore a GPU toolchain. -eval = ["dep:hipfire-runtime", "dep:hipfire-config"] [dependencies] -half.workspace = true memmap2 = "0.9" serde = { version = "1", features = ["derive"] } serde_json = "1" sha2 = "0.10" thiserror = "2" -rayon = "1" # Chat-template rendering for calibration corpora. Matching the workspace # pin in hipfire-runtime so a template renders identically in both. @@ -35,8 +30,6 @@ minijinja-contrib = { version = "2", features = ["pycompat"] } # CLI only. The library never parses arguments. clap = { version = "4.6", features = ["derive"] } -hipfire-runtime = { path = "../hipfire-runtime", default-features = false, optional = true } -hipfire-config = { path = "../hipfire-config", optional = true } [dev-dependencies] tempfile = "3" From cdd852527c6183f181efb70b3e6494af89b52655 Mon Sep 17 00:00:00 2001 From: Kaden Schutt Date: Fri, 4 Sep 2026 09:04:32 +0000 Subject: [PATCH 2/8] chore(tui): OSC 52 payload via base64 0.22 instead of a hand-rolled encoder base64 0.22.1 was already in the lock via other crates (zero new packages). The existing RFC 4648 vector test is retargeted to STANDARD.encode plus a 32-byte blob case; 153/153 tui tests pass. Refutes an audit claim while here: cargo tree shows ratatui 0.30 defaults do NOT pull termwiz/wezterm; termwiz and nix 0.29 are unreachable lock rows, and the live thiserror 1.x chain is sysctl <- gemm <- faer <- hipfire-quantize. ratatui is left untouched. --- crates/hipfire-tui/Cargo.toml | 1 + crates/hipfire-tui/src/main.rs | 53 ++++++++++++---------------------- 2 files changed, 20 insertions(+), 34 deletions(-) diff --git a/crates/hipfire-tui/Cargo.toml b/crates/hipfire-tui/Cargo.toml index 212e8f51ed..4b58d6367a 100644 --- a/crates/hipfire-tui/Cargo.toml +++ b/crates/hipfire-tui/Cargo.toml @@ -6,6 +6,7 @@ license.workspace = true [dependencies] anyhow = "1" +base64 = "0.22" crossterm = "0.29" hipfire-config = { path = "../hipfire-config" } hipfire-client = { path = "../hipfire-client" } diff --git a/crates/hipfire-tui/src/main.rs b/crates/hipfire-tui/src/main.rs index 6865f84118..4c28c6a2b7 100644 --- a/crates/hipfire-tui/src/main.rs +++ b/crates/hipfire-tui/src/main.rs @@ -11,6 +11,7 @@ use std::{io, panic}; use anyhow::Result; use app::App; +use base64::Engine as _; use crossterm::{ event::{ self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode, KeyEvent, KeyModifiers, @@ -166,31 +167,8 @@ fn emit_clipboard(text: &str) { /// The OSC 52 set-clipboard escape frame for `text` (extracted for testing). fn osc52_sequence(text: &str) -> String { - format!("\x1b]52;c;{}\x07", base64_encode(text.as_bytes())) -} - -/// Minimal standard-alphabet base64 (OSC 52 payload); avoids a new dependency. -fn base64_encode(data: &[u8]) -> String { - const T: &[u8; 64] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - let mut out = String::with_capacity(data.len().div_ceil(3) * 4); - for chunk in data.chunks(3) { - let n = (chunk[0] as u32) << 16 - | (*chunk.get(1).unwrap_or(&0) as u32) << 8 - | *chunk.get(2).unwrap_or(&0) as u32; - out.push(T[(n >> 18 & 63) as usize] as char); - out.push(T[(n >> 12 & 63) as usize] as char); - out.push(if chunk.len() > 1 { - T[(n >> 6 & 63) as usize] as char - } else { - '=' - }); - out.push(if chunk.len() > 2 { - T[(n & 63) as usize] as char - } else { - '=' - }); - } - out + use base64::engine::general_purpose::STANDARD; + format!("\x1b]52;c;{}\x07", STANDARD.encode(text.as_bytes())) } fn event_loop(terminal: &mut Terminal>, app: &mut App) -> Result<()> { @@ -373,16 +351,23 @@ mod tests { #[test] fn base64_matches_rfc4648_vectors() { - assert_eq!(base64_encode(b""), ""); - assert_eq!(base64_encode(b"f"), "Zg=="); - assert_eq!(base64_encode(b"fo"), "Zm8="); - assert_eq!(base64_encode(b"foo"), "Zm9v"); - assert_eq!(base64_encode(b"foob"), "Zm9vYg=="); - assert_eq!(base64_encode(b"foobar"), "Zm9vYmFy"); - // High bytes (0x80-0xFF) — the `& 63` masking keeps table indexing valid. - assert_eq!(base64_encode(&[0xFF, 0x00, 0x80]), "/wCA"); + use base64::engine::general_purpose::STANDARD; + assert_eq!(STANDARD.encode(b""), ""); + assert_eq!(STANDARD.encode(b"f"), "Zg=="); + assert_eq!(STANDARD.encode(b"fo"), "Zm8="); + assert_eq!(STANDARD.encode(b"foo"), "Zm9v"); + assert_eq!(STANDARD.encode(b"foob"), "Zm9vYg=="); + assert_eq!(STANDARD.encode(b"foobar"), "Zm9vYmFy"); + // High bytes exercise the full 6-bit table range. + assert_eq!(STANDARD.encode([0xFF, 0x00, 0x80]), "/wCA"); // Multibyte UTF-8 round-trips through the byte encoder. - assert_eq!(base64_encode("é".as_bytes()), "w6k="); + assert_eq!(STANDARD.encode("é".as_bytes()), "w6k="); + // 32-byte blob (OSC 52 payloads are rarely tiny): bytes 0..32. + let blob: Vec = (0..32).collect(); + assert_eq!( + STANDARD.encode(&blob), + "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=" + ); } #[test] From 4d46d2a00f320cbee01b9d25b45656122478b067 Mon Sep 17 00:00:00 2001 From: Kaden Schutt Date: Fri, 4 Sep 2026 09:04:32 +0000 Subject: [PATCH 3/8] refactor(dispatch): one hip! error-mapping macro instead of fourteen local copies Body byte-identical (map_err into DispatchError::Hip(e.to_string())); `#[macro_use] mod macros;` precedes every other module so textual scoping covers all 283 call sites unchanged. cargo test -p hipfire-dispatch: 237 passed. --- .../src/families/attention.rs | 6 --- .../src/families/fused_qkv.rs | 6 --- crates/hipfire-dispatch/src/families/gemm.rs | 5 --- crates/hipfire-dispatch/src/families/gemv.rs | 16 -------- crates/hipfire-dispatch/src/lib.rs | 3 ++ crates/hipfire-dispatch/src/macros.rs | 16 ++++++++ crates/hipfire-dispatch/src/pipeline/mod.rs | 40 ------------------- 7 files changed, 19 insertions(+), 73 deletions(-) create mode 100644 crates/hipfire-dispatch/src/macros.rs diff --git a/crates/hipfire-dispatch/src/families/attention.rs b/crates/hipfire-dispatch/src/families/attention.rs index 51e323cd22..ab4300ba46 100644 --- a/crates/hipfire-dispatch/src/families/attention.rs +++ b/crates/hipfire-dispatch/src/families/attention.rs @@ -214,12 +214,6 @@ impl KernelFamily for AttentionFamily { } } -macro_rules! hip { - ($e:expr) => { - $e.map_err(|e| DispatchError::Hip(e.to_string())) - }; -} - // ── Full attention dispatch (no KV cache — vision / DFlash) ── fn dispatch_full_attention( diff --git a/crates/hipfire-dispatch/src/families/fused_qkv.rs b/crates/hipfire-dispatch/src/families/fused_qkv.rs index f1883e206d..35c280dc3c 100644 --- a/crates/hipfire-dispatch/src/families/fused_qkv.rs +++ b/crates/hipfire-dispatch/src/families/fused_qkv.rs @@ -232,12 +232,6 @@ impl KernelFamily for FusedQkvFamily { } } -macro_rules! hip { - ($e:expr) => { - $e.map_err(|e| DispatchError::Hip(e.to_string())) - }; -} - fn dispatch_fused_qkv(gpu: &mut Gpu, params: &FusedQkvParams) -> Result<(), DispatchError> { // Guard: never route V2 bytes through a v1 kernel or vice-versa. guard_fused_qkv_dtype_key(params.weights, params.kind)?; diff --git a/crates/hipfire-dispatch/src/families/gemm.rs b/crates/hipfire-dispatch/src/families/gemm.rs index e67edfbf8b..1f3178a499 100644 --- a/crates/hipfire-dispatch/src/families/gemm.rs +++ b/crates/hipfire-dispatch/src/families/gemm.rs @@ -383,11 +383,6 @@ impl GemmFamily { w.dtype, key ))); } - macro_rules! hip { - ($e:expr) => { - $e.map_err(|e| DispatchError::Hip(e.to_string())) - }; - } use KernelKey as K; match key { diff --git a/crates/hipfire-dispatch/src/families/gemv.rs b/crates/hipfire-dispatch/src/families/gemv.rs index a6fc86ea0e..7d9bf65bdb 100644 --- a/crates/hipfire-dispatch/src/families/gemv.rs +++ b/crates/hipfire-dispatch/src/families/gemv.rs @@ -461,11 +461,6 @@ fn prepare_rotation_scratch( fn launch(gpu: &mut Gpu, key: KernelKey, p: &GemvParams) -> Result<(), DispatchError> { use KernelKey as K; let (w, x, y, m, k) = (p.w, p.x, p.y, p.w.m, p.w.k); - macro_rules! hip { - ($e:expr) => { - $e.map_err(|e| DispatchError::Hip(e.to_string())) - }; - } match key { K::GemvF32 => { // WeightRef is the source of truth for matrix shape. Some valid @@ -544,11 +539,6 @@ fn dispatch_residual(gpu: &mut Gpu, params: &GemvParams) -> Result<(), DispatchE let k = w.k; use DType::*; - macro_rules! hip { - ($e:expr) => { - $e.map_err(|e| DispatchError::Hip(e.to_string())) - }; - } match w.dtype { HFQ4G256 => hip!(gpu.gemv_hfq4g256_residual(w.buf, x, y, m, k)), HFQ3G256 => hip!(gpu.gemv_hfq3g256_residual(w.buf, x, y, m, k)), @@ -588,12 +578,6 @@ fn dispatch_swiglu_residual(gpu: &mut Gpu, params: &GemvParams) -> Result<(), Di let k = w.k; use DType::*; - macro_rules! hip { - ($e:expr) => { - $e.map_err(|e| DispatchError::Hip(e.to_string())) - }; - } - // SwiGLU+Residual dispatch. // // HFQ dtypes: caller must pre-compute silu(gate)*up and pass as `gate` diff --git a/crates/hipfire-dispatch/src/lib.rs b/crates/hipfire-dispatch/src/lib.rs index 178a58264a..7223c697bc 100644 --- a/crates/hipfire-dispatch/src/lib.rs +++ b/crates/hipfire-dispatch/src/lib.rs @@ -7,6 +7,9 @@ // The dispatch layer selects the correct kernel based on quant format, // arch capabilities, and feature flags — all resolved at init time. +#[macro_use] +mod macros; + pub mod context; pub mod families; pub mod ops; diff --git a/crates/hipfire-dispatch/src/macros.rs b/crates/hipfire-dispatch/src/macros.rs new file mode 100644 index 0000000000..e65fdd4a61 --- /dev/null +++ b/crates/hipfire-dispatch/src/macros.rs @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +// Copyright (c) 2026 Björn Bösel +// hipfire — see LICENSE and NOTICE in the project root. + +//! Shared dispatch macros. +//! +//! Single home for the `hip!` helper. Declared with `#[macro_use]` before +//! every other module in `lib.rs` so textual macro scoping makes it visible +//! to all `families::*` and `pipeline` call sites. + +/// Map a fallible HIP call into DispatchError::Hip, preserving the message. +macro_rules! hip { + ($e:expr) => { + $e.map_err(|e| DispatchError::Hip(e.to_string())) + }; +} diff --git a/crates/hipfire-dispatch/src/pipeline/mod.rs b/crates/hipfire-dispatch/src/pipeline/mod.rs index 90aced123a..1cf8897113 100644 --- a/crates/hipfire-dispatch/src/pipeline/mod.rs +++ b/crates/hipfire-dispatch/src/pipeline/mod.rs @@ -592,11 +592,6 @@ pub fn run_moe_decode( p: &crate::families::moe::MoeParams, ) -> Result<(), DispatchError> { use crate::families::moe::MoeResolution; - macro_rules! hip { - ($e:expr) => { - $e.map_err(|e| DispatchError::Hip(e.to_string())) - }; - } // Runtime guard matching the bias-aware decode guard (not debug_assert — // that would be stripped in release). batch_size=1 is the only valid @@ -1801,11 +1796,6 @@ fn run_moe_decode_cpu_fallback( shared_gate: &GpuTensor, shared_up: &GpuTensor, ) -> Result<(), DispatchError> { - macro_rules! hip { - ($e:expr) => { - $e.map_err(|e| DispatchError::Hip(e.to_string())) - }; - } // EP (Ship 6 substrate-EP) is not wired through the generic CPU-top-K // fallback yet — it still accumulates into x_residual directly. The @@ -2146,11 +2136,6 @@ pub fn run_moe_decode_bias_aware( gpu: &mut Gpu, p: &crate::families::moe::MoeBiasAwareParams, ) -> Result<(), DispatchError> { - macro_rules! hip { - ($e:expr) => { - $e.map_err(|e| DispatchError::Hip(e.to_string())) - }; - } if p.batch_size != 1 { return Err(DispatchError::UnsupportedVariant { family: "moe", @@ -2182,11 +2167,6 @@ pub fn run_moe_decode_selected( gpu: &mut Gpu, p: &crate::families::moe::MoeSelectedParams, ) -> Result<(), DispatchError> { - macro_rules! hip { - ($e:expr) => { - $e.map_err(|e| DispatchError::Hip(e.to_string())) - }; - } if p.batch_size != 1 { return Err(DispatchError::UnsupportedVariant { family: "moe", @@ -2523,11 +2503,6 @@ pub fn run_moe_prefill_bias_aware( p: &crate::families::moe::MoeBiasAwarePrefillParams, ) -> Result<(), DispatchError> { use crate::families::moe::MoePrefillRouting; - macro_rules! hip { - ($e:expr) => { - $e.map_err(|e| DispatchError::Hip(e.to_string())) - }; - } let (hidden, im, n_exp, k_top, batch_size) = (p.hidden, p.mi, p.n_exp, p.k_top, p.batch_size); // ── Routing → topk_indices / topk_weights ──────────────────────────────── @@ -2898,11 +2873,6 @@ fn dispatch_grouped_gemm( paro_i8: bool, paro_i8_k8: bool, ) -> Result<(), DispatchError> { - macro_rules! hip { - ($e:expr) => { - $e.map_err(|e| DispatchError::Hip(e.to_string())) - }; - } // Mixed per-expert: the merged grouped kernel carries the per-expert stride // via the dtype_tags table; takes priority over the uniform dtype dispatch. if let Some(tags) = expert_dtype_tags { @@ -3109,11 +3079,6 @@ pub fn run_moe_prefill( p: &crate::families::moe::MoePrefillParams, ) -> Result<(), DispatchError> { use crate::families::moe::MoePrefillResolution; - macro_rules! hip { - ($e:expr) => { - $e.map_err(|e| DispatchError::Hip(e.to_string())) - }; - } let res = MoePrefillResolution::resolve(&p.dtypes, &ctx.arch, &ctx.flags); let force_mq4_grouped_fp16 = res.force_mq4_grouped_fp16 || p.force_mq4_grouped_fp16; @@ -3736,11 +3701,6 @@ pub fn dispatch_fused( PipelineParams::Linear(p) => p, PipelineParams::Moe(p) => return run_moe_decode(ctx, gpu, p), }; - macro_rules! hip { - ($e:expr) => { - $e.map_err(|e| DispatchError::Hip(e.to_string())) - }; - } match key { KernelKey::GemvMfp4G32Fused => { gpu.ensure_mq_signs() From 1d609259a0c984eb8149b95463f8cb7fe6d06e03 Mon Sep 17 00:00:00 2001 From: Kaden Schutt Date: Fri, 4 Sep 2026 09:04:32 +0000 Subject: [PATCH 4/8] refactor(runtime): hipfire_runtime::chatml consts replace ChatML token-id literals IM_END = 151645 and ENDOFTEXT = 151643 live in one place; the qwen2 default EOS, MAPLE_EOS_FALLBACK, the generate dense stop pair, and the three minimax example stop sets import them. Remaining 15164x literals are tests, fixtures, prose, or dots-ocr (which also owns 151673; left for its owner). --- crates/hipfire-arch-maple/src/bundle.rs | 2 +- crates/hipfire-arch-minimax/examples/ep_minimax.rs | 2 +- crates/hipfire-arch-minimax/examples/infer_minimax.rs | 2 +- .../hipfire-arch-minimax/examples/minimax_prefill_bench.rs | 2 +- crates/hipfire-arch-qwen2/src/qwen2.rs | 2 +- crates/hipfire-generate/src/dense.rs | 2 +- crates/hipfire-runtime/src/chatml.rs | 7 +++++++ crates/hipfire-runtime/src/lib.rs | 1 + 8 files changed, 14 insertions(+), 6 deletions(-) create mode 100644 crates/hipfire-runtime/src/chatml.rs diff --git a/crates/hipfire-arch-maple/src/bundle.rs b/crates/hipfire-arch-maple/src/bundle.rs index e50bf02a5f..2af64afba8 100644 --- a/crates/hipfire-arch-maple/src/bundle.rs +++ b/crates/hipfire-arch-maple/src/bundle.rs @@ -65,7 +65,7 @@ impl ArchModel for MapleBundle { /// Maple's end-of-turn token. The checkpoint ships the Qwen tokenizer and /// `config.json` declares `eos_token_id` 151645 (`<|im_end|>`), not the /// `<|endoftext|>` (151643) that a vocab heuristic would pick. -pub const MAPLE_EOS_FALLBACK: u32 = 151645; +pub const MAPLE_EOS_FALLBACK: u32 = hipfire_runtime::chatml::IM_END; /// Resolve the end-of-turn id from the tokenizer, falling back to the /// config-declared ChatML id. diff --git a/crates/hipfire-arch-minimax/examples/ep_minimax.rs b/crates/hipfire-arch-minimax/examples/ep_minimax.rs index 4a2c90931e..f2d881bea6 100644 --- a/crates/hipfire-arch-minimax/examples/ep_minimax.rs +++ b/crates/hipfire-arch-minimax/examples/ep_minimax.rs @@ -134,7 +134,7 @@ fn main() { for step in 0..max { let next = argmax(&logits); gen.push(next); - if matches!(next, 200020 | 151643 | 151645 | 2) { + if matches!(next, 200020 | hipfire_runtime::chatml::ENDOFTEXT | hipfire_runtime::chatml::IM_END | 2) { break; } if step == 2 { steady_t = std::time::Instant::now(); steady = 0; } diff --git a/crates/hipfire-arch-minimax/examples/infer_minimax.rs b/crates/hipfire-arch-minimax/examples/infer_minimax.rs index a797c9cef3..191a3a4a24 100644 --- a/crates/hipfire-arch-minimax/examples/infer_minimax.rs +++ b/crates/hipfire-arch-minimax/examples/infer_minimax.rs @@ -100,7 +100,7 @@ fn main() { let next = argmax(&logits); gen.push(next); // common MiniMax/Qwen EOS ids; stop early if hit - if matches!(next, 200020 | 151643 | 151645 | 2) { + if matches!(next, 200020 | hipfire_runtime::chatml::ENDOFTEXT | hipfire_runtime::chatml::IM_END | 2) { break; } logits = diff --git a/crates/hipfire-arch-minimax/examples/minimax_prefill_bench.rs b/crates/hipfire-arch-minimax/examples/minimax_prefill_bench.rs index 488eb854e5..35bdcb3da2 100644 --- a/crates/hipfire-arch-minimax/examples/minimax_prefill_bench.rs +++ b/crates/hipfire-arch-minimax/examples/minimax_prefill_bench.rs @@ -151,7 +151,7 @@ fn main() -> Result<(), String> { let mut gen: Vec = Vec::new(); for _ in 0..gen_n { let next = am(&logits) as u32; - if matches!(next, 200020 | 151643 | 151645 | 2) { + if matches!(next, 200020 | hipfire_runtime::chatml::ENDOFTEXT | hipfire_runtime::chatml::IM_END | 2) { break; } gen.push(next); diff --git a/crates/hipfire-arch-qwen2/src/qwen2.rs b/crates/hipfire-arch-qwen2/src/qwen2.rs index 0535c2556f..2e700ee966 100644 --- a/crates/hipfire-arch-qwen2/src/qwen2.rs +++ b/crates/hipfire-arch-qwen2/src/qwen2.rs @@ -199,7 +199,7 @@ pub fn from_config_value( } } let eos_token_ids = if eos_token_ids.is_empty() { - vec![151645] + vec![hipfire_runtime::chatml::IM_END] } else { eos_token_ids }; diff --git a/crates/hipfire-generate/src/dense.rs b/crates/hipfire-generate/src/dense.rs index 96f35c92af..78eb719842 100644 --- a/crates/hipfire-generate/src/dense.rs +++ b/crates/hipfire-generate/src/dense.rs @@ -8182,7 +8182,7 @@ pub fn generate_maple( // `<|endoftext|>` (151643) is not Maple's declared eos — config.json says // 151645 — but emitting it mid-chat is a terminal condition either way, and // continuing past it produces garbage. Stop on both. - let eos_set: [u32; 2] = [eos_tok, 151643]; + let eos_set: [u32; 2] = [eos_tok, hipfire_runtime::chatml::ENDOFTEXT]; let mut hit_eos = false; // Explicit thinking cap enforcement. The HTTP layer resolves `max_think_tokens` // via the QwenJinja contract; without this router Maple would ignore it and diff --git a/crates/hipfire-runtime/src/chatml.rs b/crates/hipfire-runtime/src/chatml.rs new file mode 100644 index 0000000000..e0f8ce8d1e --- /dev/null +++ b/crates/hipfire-runtime/src/chatml.rs @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright (c) 2026 Kaden Schutt +// hipfire — see LICENSE and NOTICE in the project root. + +//! ChatML special-token ids shared by the Qwen-family vocabularies. +pub const IM_END: u32 = 151645; // <|im_end|> +pub const ENDOFTEXT: u32 = 151643; // <|endoftext|> diff --git a/crates/hipfire-runtime/src/lib.rs b/crates/hipfire-runtime/src/lib.rs index 503c460be3..53ae699739 100644 --- a/crates/hipfire-runtime/src/lib.rs +++ b/crates/hipfire-runtime/src/lib.rs @@ -23,6 +23,7 @@ pub mod bf16_loader; pub mod cache_plan; #[cfg(feature = "deltanet")] pub mod cask; +pub mod chatml; pub mod config; #[cfg(feature = "deltanet")] pub mod cpu_router; From 037b24004cd40488d488d40882c7b96b6d750cf0 Mon Sep 17 00:00:00 2001 From: Kaden Schutt Date: Fri, 4 Sep 2026 09:04:33 +0000 Subject: [PATCH 5/8] fix(cli): config commands and serve responses return errors instead of panicking `hipfire config list/get/set/explain/reset` (global and per-model) used expect() after schema/catalog lookups, so schema drift became a panic on a user command. They now return anyhow errors naming the key/id. serve/http.rs json_response and admission_error_response no longer unwrap the response builder / HeaderValue (500 fallback; RETRY_AFTER omitted on a bad value). hipfire-config ProcessConfig::validate maps a missing field to ConfigError::UnknownKey. `hipfire profile` now points at `scripts/kernel_atlas.py render-fit --row` instead of the transitional hipfire-atlas binary. cargo test -p hipfire-config: 65 passed. --- crates/hipfire-cli/src/main.rs | 80 +++++++++++++++++----------- crates/hipfire-cli/src/serve/http.rs | 40 +++++++++++--- crates/hipfire-config/src/lib.rs | 8 ++- 3 files changed, 88 insertions(+), 40 deletions(-) diff --git a/crates/hipfire-cli/src/main.rs b/crates/hipfire-cli/src/main.rs index 86764ac22c..a5cd1a4d70 100644 --- a/crates/hipfire-cli/src/main.rs +++ b/crates/hipfire-cli/src/main.rs @@ -693,19 +693,21 @@ fn config_command(paths: &Paths, args: ConfigArgs) -> Result<()> { let mut values = fields() .iter() .map(|field| { - let resolved = resolved.get(field.key).expect("schema key resolved"); - ( + let item = resolved.get(field.key).ok_or_else(|| { + anyhow!("configuration key '{}' is not set", field.key) + })?; + Ok::<_, anyhow::Error>(( field.key.to_owned(), serde_json::json!({ "legacy_key": field.legacy_key, - "value": resolved.value, + "value": item.value, "default": format_default(field), - "source": resolved.source, + "source": item.source, "overridden": loaded.layer.get(field.key).is_some(), }), - ) + )) }) - .collect::>(); + .collect::>>()?; for (key, item) in resolved .values .iter() @@ -739,7 +741,9 @@ fn config_command(paths: &Paths, args: ConfigArgs) -> Result<()> { } println!(); for schema in fields() { - let item = resolved.get(schema.key).expect("schema key resolved"); + let item = resolved.get(schema.key).ok_or_else(|| { + anyhow!("configuration key '{}' is not set", schema.key) + })?; let marker = if loaded.layer.get(schema.key).is_some() { "override" } else { @@ -804,8 +808,12 @@ fn config_command(paths: &Paths, args: ConfigArgs) -> Result<()> { let mut loaded = load_global(&paths.config)?; loaded.layer.set_cli(&key, &value)?; write_global_toml(&paths.config, &loaded.layer)?; - let canonical = canonical_config_key(&key).expect("set_cli accepted key"); - let value = loaded.layer.get(&canonical).expect("set value"); + let canonical = canonical_config_key(&key) + .ok_or_else(|| anyhow!("unknown configuration key '{key}'"))?; + let value = loaded + .layer + .get(&canonical) + .ok_or_else(|| anyhow!("configuration key '{canonical}' is not set"))?; println!("{canonical} = {value}"); if loaded.format == ConfigFormat::LegacyJson { println!( @@ -842,8 +850,8 @@ fn config_command(paths: &Paths, args: ConfigArgs) -> Result<()> { .get(&canonical) .ok_or_else(|| anyhow!("configuration key '{canonical}' is not set"))?; if is_developer_key(&canonical) { - let env_compat = - developer_env_for_key(&canonical).expect("validated developer key"); + let env_compat = developer_env_for_key(&canonical) + .ok_or_else(|| anyhow!("developer key '{canonical}' has no legacy env spelling"))?; if output.json { println!( "{}", @@ -888,7 +896,8 @@ fn config_command(paths: &Paths, args: ConfigArgs) -> Result<()> { } return Ok(()); } - let schema = field(&canonical).expect("stable configuration key"); + let schema = field(&canonical) + .ok_or_else(|| anyhow!("unknown configuration key '{canonical}'"))?; if output.json { println!( "{}", @@ -1097,8 +1106,10 @@ fn model_config_command( let values = fields() .iter() .map(|schema| { - let item = resolved.get(schema.key).expect("schema key resolved"); - ( + let item = resolved.get(schema.key).ok_or_else(|| { + anyhow!("configuration key '{}' is not set", schema.key) + })?; + Ok::<_, anyhow::Error>(( schema.key.to_owned(), serde_json::json!({ "legacy_key": schema.legacy_key, @@ -1106,9 +1117,9 @@ fn model_config_command( "source": item.source, "overridden": overrides.get(schema.key).is_some(), }), - ) + )) }) - .collect::>(); + .collect::>>()?; println!( "{}", serde_json::to_string_pretty(&serde_json::json!({ @@ -1129,7 +1140,9 @@ fn model_config_command( catalog.format ); for schema in fields() { - let item = resolved.get(schema.key).expect("schema key resolved"); + let item = resolved.get(schema.key).ok_or_else(|| { + anyhow!("configuration key '{}' is not set", schema.key) + })?; let marker = if overrides.get(schema.key).is_some() { "override" } else { @@ -1155,7 +1168,9 @@ fn model_config_command( } let resolved = resolved_for_model(paths, model_name, tag.as_deref(), entry)?; let schema = field(&key).ok_or_else(|| anyhow!("unknown configuration key '{key}'"))?; - let value = resolved.get(schema.key).expect("schema key resolved"); + let value = resolved.get(schema.key).ok_or_else(|| { + anyhow!("configuration key '{}' is not set", schema.key) + })?; if output.json { println!( "{}", @@ -1183,7 +1198,7 @@ fn model_config_command( .map(str::to_owned) .unwrap_or_else(|| tag.clone().unwrap_or_else(|| model_name.to_owned())); let local_path = find_model_path(paths, ®istry, model_name); - let saved = { + let (canonical, saved) = { let record = loaded.catalog.models.entry(id.clone()).or_default(); if record.path.is_none() { record.path = local_path; @@ -1192,12 +1207,17 @@ fn model_config_command( record.registry_tag = tag.clone(); } record.overrides.set_cli(&key, &value)?; - let schema = field(&key).expect("set_cli accepted key"); - record.overrides.get(schema.key).unwrap().clone() + let schema = field(&key) + .ok_or_else(|| anyhow!("unknown configuration key '{key}'"))?; + let saved = record + .overrides + .get(schema.key) + .ok_or_else(|| anyhow!("configuration key '{}' is not set", schema.key))? + .clone(); + (schema.key, saved) }; write_catalog_toml(&paths.config, &loaded.catalog)?; - let schema = field(&key).expect("set_cli accepted key"); - println!("{id} {} = {saved}", schema.key); + println!("{id} {canonical} = {saved}"); if loaded.format == CatalogFormat::LegacyJson { println!( "migrated model catalog to {}; preserved legacy JSON as rollback copies", @@ -1215,11 +1235,9 @@ fn model_config_command( println!("{model_name} has no per-model overrides"); return Ok(()); }; - let record = loaded - .catalog - .models - .get_mut(&id) - .expect("resolved model id"); + let record = loaded.catalog.models.get_mut(&id).ok_or_else(|| { + anyhow!("model '{model_name}' has no catalog entry for id '{id}'") + })?; if let Some(key) = key { let schema = field(&key).ok_or_else(|| anyhow!("unknown configuration key '{key}'"))?; @@ -1242,7 +1260,9 @@ fn model_config_command( } let resolved = resolved_for_model(paths, model_name, tag.as_deref(), entry)?; let schema = field(&key).ok_or_else(|| anyhow!("unknown configuration key '{key}'"))?; - let value = resolved.get(schema.key).expect("schema key resolved"); + let value = resolved.get(schema.key).ok_or_else(|| { + anyhow!("configuration key '{}' is not set", schema.key) + })?; if output.json { println!( "{}", @@ -4389,7 +4409,7 @@ fn profile_command(paths: &Paths, args: ProfileArgs) -> Result<()> { .unwrap_or("unknown"), ); } - println!("\nFor phase-aware ISA fit evidence, run hipfire-atlas."); + println!("\nFor phase-aware ISA fit evidence, run python3 scripts/kernel_atlas.py render-fit --row ."); } Ok(()) } diff --git a/crates/hipfire-cli/src/serve/http.rs b/crates/hipfire-cli/src/serve/http.rs index f42f543ac8..2728b13717 100644 --- a/crates/hipfire-cli/src/serve/http.rs +++ b/crates/hipfire-cli/src/serve/http.rs @@ -60,13 +60,35 @@ fn boxed_empty() -> BoxBody { } pub(crate) fn json_response(value: serde_json::Value, status: u16) -> Response { - let bytes = serde_json::to_vec(&value).expect("JSON value serializes"); + match json_response_result(&value, status) { + Ok(resp) => resp, + Err(message) => openai_error(&message, 500), + } +} + +fn json_response_result(value: &serde_json::Value, status: u16) -> Result, String> { + let bytes = serde_json::to_vec(value).map_err(|err| format!("failed to encode JSON response: {err}"))?; Response::builder() .status(status) .header(header::CONTENT_TYPE, "application/json") .header(header::ACCESS_CONTROL_ALLOW_ORIGIN, "*") .body(boxed_full(bytes)) - .unwrap() + .map_err(|err| format!("failed to build HTTP response: {err}")) +} + +/// Last-resort 500 body with no serde dependency, so error rendering always +/// terminates even if JSON encoding itself is what failed. +fn static_server_error() -> Response { + Response::builder() + .status(500) + .header(header::CONTENT_TYPE, "application/json") + .header(header::ACCESS_CONTROL_ALLOW_ORIGIN, "*") + .body(boxed_full( + br#"{"error":{"message":"internal server error","type":"server_error"}}"#.to_vec(), + )) + // Static status, headers, and body: the builder cannot fail on these + // inputs, and there is no further fallback below this point. + .expect("static 500 response builds") } pub(crate) fn openai_error(message: &str, status: u16) -> Response { @@ -75,20 +97,22 @@ pub(crate) fn openai_error(message: &str, status: u16) -> Response { } else { "server_error" }; - json_response( - serde_json::json!({ + json_response_result( + &serde_json::json!({ "error": { "message": message, "type": error_type } }), status, ) + .unwrap_or_else(|_| static_server_error()) } pub(crate) fn admission_error_response(error: &AdmissionError) -> Response { let mut resp = openai_error(&error.message, 503); - resp.headers_mut().insert( - header::RETRY_AFTER, - header::HeaderValue::from_str(&error.retry_after_seconds.to_string()).unwrap(), - ); + if let Ok(retry_after) = + header::HeaderValue::from_str(&error.retry_after_seconds.to_string()) + { + resp.headers_mut().insert(header::RETRY_AFTER, retry_after); + } resp } diff --git a/crates/hipfire-config/src/lib.rs b/crates/hipfire-config/src/lib.rs index 1c965e15d2..2a827295e9 100644 --- a/crates/hipfire-config/src/lib.rs +++ b/crates/hipfire-config/src/lib.rs @@ -3081,7 +3081,9 @@ impl ProcessConfig { if is_developer_key(key) { continue; } - let schema = field(key).expect("ConfigLayer::validate accepted stable key"); + let Some(schema) = field(key) else { + return Err(ConfigError::UnknownKey(key.clone())); + }; if schema.env_compat.is_none() { return Err(ConfigError::InvalidValue { key: key.clone(), @@ -3736,7 +3738,9 @@ fn validate_model_layer(layer: &ConfigLayer) -> Result<()> { .into(), }); } - let schema = field(key).expect("validated configuration field"); + let Some(schema) = field(key) else { + return Err(ConfigError::UnknownKey(key.clone())); + }; if matches!(schema.scope, ConfigScope::Process | ConfigScope::Diagnostic) { return Err(ConfigError::InvalidValue { key: key.clone(), From 103a5f15637b8f079aa7618bd6f358ebea823b7a Mon Sep 17 00:00:00 2001 From: Kaden Schutt Date: Fri, 4 Sep 2026 09:04:33 +0000 Subject: [PATCH 6/8] docs: fix contract drift found by the 2026-09-04 audit nix/package.nix built the daemon as a hipfire-runtime example (pre-saddle) and licensed the package MIT: it now builds -p hipfire-daemon / -p hipfire-cli like the Containerfile, license [asl20 mit] per NOTICE (kernels.nix too). docs/CONTAINER.md carried the same stale build line. ARCHITECTURE.md and CLI.md state the exact force_local list from hipfire-cli/src/main.rs:1911-1918. VALIDATION.md names the required checks. CONTRIBUTING.md said 'Rust 1.75+', which has been false since is_none_or / LazyLock / edition 2024; now 'current stable, no MSRV declared'. Also: saddle-lab example run-lines, the caps.rs BatchEligibilityRequest overclaim, the reap README cohere2moe promise, and the reap map.md purpose line. --- CONTRIBUTING.md | 11 ++++++----- crates/hipfire-reap/map.md | 2 +- crates/saddle-core/src/caps.rs | 12 ++++++++---- crates/saddle-lab/examples/imatrix_collect.rs | 2 +- crates/saddle-lab/examples/pp_parity.rs | 4 ++-- docs/ARCHITECTURE.md | 6 +++++- docs/CLI.md | 2 +- docs/CONTAINER.md | 5 +++-- docs/VALIDATION.md | 6 ++++++ nix/kernels.nix | 2 +- nix/package.nix | 18 +++++++----------- scripts/reap/README.md | 4 ++-- 12 files changed, 43 insertions(+), 31 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 76f66afe0b..d7a7a4d67c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -55,15 +55,16 @@ the case we want filed. ```bash git clone https://github.com/warpfront/hipfire cd hipfire -cargo build --release --features deltanet --example daemon -p hipfire-runtime +cargo build --release --locked -p hipfire-daemon +cargo build --release --locked -p hipfire-cli cargo build --release --features deltanet --example test_kernels -p hipfire-runtime cargo build --release -p hipfire-quantize ./scripts/install-hooks.sh ``` - -Requires Rust 1.75+ and ROCm 6+ (the dev workflow needs `hipcc` for -kernel JIT). Pre-compiled kernel blobs ship for gfx1010 / gfx1030 / -gfx1100 / gfx1200; other arches JIT-compile on first load. +Requires current stable Rust (CI tracks `stable`; 1.98 is what the +maintainers build with — no MSRV is declared yet) and ROCm 6+ (the dev +workflow needs `hipcc` for kernel JIT). Pre-compiled kernel blobs ship for +gfx1010 / gfx1030 / gfx1100 / gfx1200; other arches JIT-compile on first load. `scripts/install-hooks.sh` is idempotent; it sets `core.hooksPath=.githooks` and makes the local pre-commit hook diff --git a/crates/hipfire-reap/map.md b/crates/hipfire-reap/map.md index 4fb97b2b81..8a71f4b8b0 100644 --- a/crates/hipfire-reap/map.md +++ b/crates/hipfire-reap/map.md @@ -5,7 +5,7 @@ ## Purpose -Model-agnostic REAP: selective expert pruning + (SP2) selective re-quant overlay for MoE models. Owns `gather` (per-expert importance), `plan` (`ExpertPlan`), `hook` (`ReapArchHook`), `load`/`source` overlay applied at load. Spec is `docs/superpowers/specs/2026-06-11-generic-moe-reap-design.md`. The `//!` docs in [`src/lib.rs`](src/lib.rs) are the crate entry point. +Model-agnostic REAP: selective expert pruning + (SP2) selective re-quant overlay for MoE models. Owns `gather` (first-axis byte row-gather of kept rows for keep maps), `plan` (`ExpertPlan`), `hook` (`ReapArchHook`), `load`/`source` overlay applied at load. Spec is `docs/superpowers/specs/2026-06-11-generic-moe-reap-design.md`. The `//!` docs in [`src/lib.rs`](src/lib.rs) are the crate entry point. ## Gotchas diff --git a/crates/saddle-core/src/caps.rs b/crates/saddle-core/src/caps.rs index 26e78b6393..4e2671e0ff 100644 --- a/crates/saddle-core/src/caps.rs +++ b/crates/saddle-core/src/caps.rs @@ -166,10 +166,14 @@ impl Default for ArchCaps { /// Request-derived flags for [`is_batch_eligible`] style checks. /// -/// The daemon builds this from the incoming JSON, `LoadedModel` topology -/// (`pp`, `ep`), and feature flags (`speculator`, `kv_adaptive`, -/// `eviction`, `pflash`). `ArchCaps` is passed separately — the function -/// never inspects an identifier. +/// Consumed by `hipfire_engine::scheduler::is_batch_eligible` together with +/// [`ArchCaps`]: each field snapshots one request/topology input (`pp`, +/// `ep`, image/tools/stop payloads, `speculator`/`kv_adaptive`/`pflash` +/// activity, single-user history, think mode, continuous-batch opt-in and +/// size). Nothing in production constructs this struct today — it is built +/// in unit tests; the daemon's live request path decides through +/// `hipfire_generate::batch::is_batch_request_eligible`, which reads the +/// JSON message and `LoadedModel` directly. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct BatchEligibilityRequest { /// Pipeline-parallel degree from `LoadedModel::pp`. diff --git a/crates/saddle-lab/examples/imatrix_collect.rs b/crates/saddle-lab/examples/imatrix_collect.rs index f9029aaacf..e52946d018 100644 --- a/crates/saddle-lab/examples/imatrix_collect.rs +++ b/crates/saddle-lab/examples/imatrix_collect.rs @@ -32,7 +32,7 @@ //! tokenization-compatible). //! //! Usage: -//! cargo run --release -p hipfire-runtime --example imatrix_collect -- \ +//! cargo run --release -p saddle-lab --example imatrix_collect -- \ //! --bf16-gguf \ //! --corpus \ //! --output \ diff --git a/crates/saddle-lab/examples/pp_parity.rs b/crates/saddle-lab/examples/pp_parity.rs index 3ae3336ca9..25a527e45e 100644 --- a/crates/saddle-lab/examples/pp_parity.rs +++ b/crates/saddle-lab/examples/pp_parity.rs @@ -8,8 +8,8 @@ //! greedy token sequence matches for ≥ 100 decoded tokens (temp=0, //! same prompt token). //! -//! Run: HIP_VISIBLE_DEVICES=0,1 cargo run -p hipfire-runtime \ -//! --release --features deltanet --example pp_parity -- \ +//! Run: HIP_VISIBLE_DEVICES=0,1 cargo run -p saddle-lab \ +//! --release --features arch-qwen35,deltanet --example pp_parity -- \ //! ~/.hipfire/models/qwen3.5-0.8b.mq4 use hipfire_arch_qwen35::qwen35::{ diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 665f2c6f4d..999c60494a 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -104,7 +104,11 @@ hipfire run "…" Native CLI (`crates/hipfire-cli`) resolve registry tag → model path under ~/.hipfire/models/ (or local path) if serve up AND not forced local → HTTP POST /v1/chat/completions - forced local when HIPFIRE_LOCAL=1, --kv-mode, --json, or --no-stream + forced local when `HIPFIRE_LOCAL` is truthy or any of `--image`, + `--kv-mode`, `--kv-backend`, `--spec`/`--speculation`, `--model-draft`, + `--draft-max`, `--dspark-conf-threshold` is passed (`force_local` in + `crates/hipfire-cli/src/main.rs`; `--json`/`--no-stream` ride the HTTP + route and do not force local) if HTTP fails while serve still live → abort (no local spawn; would collide) else → spawn one-shot daemon binary │ diff --git a/docs/CLI.md b/docs/CLI.md index 471fa9e1c7..af74342570 100644 --- a/docs/CLI.md +++ b/docs/CLI.md @@ -62,7 +62,7 @@ hipfire run qwen3.5:27b -md ~/.hipfire/models/qwen35-27b-dflash-mq4.hfq "..." HIPFIRE_LOCAL=1 hipfire run qwen3.5:4b "..." # skip HTTP; always local spawn ``` -Local-forcing (skip a healthy serve): `HIPFIRE_LOCAL=1`, `--kv-mode`, or `--image`. JSON and non-streaming responses are supported by the native HTTP service and do not by themselves force a local daemon. +Local-forcing (skip a healthy serve): `HIPFIRE_LOCAL` truthy, `--image`, `--kv-mode`, `--kv-backend`, `--spec`/`--speculation`, `--model-draft`, `--draft-max`, or `--dspark-conf-threshold` (exact list: `force_local` in `crates/hipfire-cli/src/main.rs`). JSON and non-streaming responses are supported by the native HTTP service and do not by themselves force a local daemon. ### `hipfire serve` flags diff --git a/docs/CONTAINER.md b/docs/CONTAINER.md index 4160ade55a..1c0a60942f 100644 --- a/docs/CONTAINER.md +++ b/docs/CONTAINER.md @@ -49,10 +49,11 @@ Docker works the same with `docker build …`. Rootful Docker does **not** implement Podman's `--group-add keep-groups` token — omit that flag under Docker (see run section). -Daemon build inside the image matches the project default: +Daemon and CLI builds inside the image (Containerfile builder stage): ```text -cargo build --release --locked --features deltanet --example daemon -p hipfire-runtime +cargo build --release --locked -p hipfire-daemon +cargo build --release --locked -p hipfire-cli ``` ## Run the runtime image (GPU required) diff --git a/docs/VALIDATION.md b/docs/VALIDATION.md index 394e5ad1bc..6d9619c84f 100644 --- a/docs/VALIDATION.md +++ b/docs/VALIDATION.md @@ -170,6 +170,12 @@ comments first. No-GPU CI green never substitutes for hw-gate or for a required manual route. hw-gate green does not create an admission or skip claim-specific oracles named below. +Branch protection requires the no-GPU workflow's checks by exact CI job +name: `build (workspace, no GPU)`, `unit tests (lib, no GPU)`, and +`gates (ratchets, layering, registers)` (all in +[`.github/workflows/ci.yml`](../.github/workflows/ci.yml)). `hw-gate` is +the hardware rung — currently advisory, planned required. + ### Automatic entrypoints | Route | Path | Role | diff --git a/nix/kernels.nix b/nix/kernels.nix index da8560a24d..aeba5bd74e 100644 --- a/nix/kernels.nix +++ b/nix/kernels.nix @@ -43,7 +43,7 @@ stdenv.mkDerivation { meta = with lib; { description = "Pre-compiled GPU kernels for hipfire"; - license = licenses.mit; + license = [ licenses.asl20 licenses.mit ]; platforms = [ "x86_64-linux" ]; }; } diff --git a/nix/package.nix b/nix/package.nix index 9882677fe7..ed89218509 100644 --- a/nix/package.nix +++ b/nix/package.nix @@ -18,12 +18,10 @@ rustPlatform.buildRustPackage { cargoLock.lockFile = cargoLockFile; doCheck = false; # tests require GPU - # The main binaries are cargo [[example]] targets, not [[bin]]. + # The deliverables are standalone binary crates (mirrors Containerfile). buildPhase = '' runHook preBuild - cargo build --release --features deltanet \ - --example daemon --example infer --example infer_hfq \ - -p hipfire-runtime + cargo build --release -p hipfire-daemon cargo build --release -p hipfire-cli runHook postBuild ''; @@ -37,8 +35,10 @@ rustPlatform.buildRustPackage { mkdir -p $out/bin - # Install and wrap daemon binary with LD_LIBRARY_PATH for libamdhip64.so dlopen - cp target/release/examples/daemon $out/bin/hipfire-daemon-unwrapped + # Install and wrap daemon binary with LD_LIBRARY_PATH for libamdhip64.so dlopen. + # `hipfire-daemon`'s [[bin]] name is `daemon`, so the artifact is + # target/release/daemon (mirrors Containerfile's COPY to /opt/hipfire/bin/daemon). + cp target/release/daemon $out/bin/hipfire-daemon-unwrapped makeWrapper $out/bin/hipfire-daemon-unwrapped $out/bin/hipfire-daemon \ ${lib.optionalString rocmSupport "--prefix LD_LIBRARY_PATH : ${lib.makeLibraryPath [ @@ -48,10 +48,6 @@ rustPlatform.buildRustPackage { rocmPackages.rocprofiler-register ]}"} - # Install other binaries - cp target/release/examples/infer $out/bin/hipfire-infer 2>/dev/null || true - cp target/release/examples/infer_hfq $out/bin/hipfire-infer-hfq 2>/dev/null || true - # Install the native Rust control plane. HIPFIRE_DAEMON_BIN points it at # the ROCm-wrapped daemon rather than relying on a source-tree layout. cp target/release/hipfire $out/bin/hipfire-unwrapped @@ -71,7 +67,7 @@ rustPlatform.buildRustPackage { meta = with lib; { description = "LLM inference for AMD RDNA GPUs"; homepage = "https://github.com/warpfront/hipfire"; - license = licenses.mit; + license = [ licenses.asl20 licenses.mit ]; platforms = [ "x86_64-linux" ]; mainProgram = "hipfire"; }; diff --git a/scripts/reap/README.md b/scripts/reap/README.md index 3fb586ddc8..8a9440a9db 100644 --- a/scripts/reap/README.md +++ b/scripts/reap/README.md @@ -6,8 +6,8 @@ experts out of an existing full quant (`deepseek-v4-flash.mq2lloyd`). The keep-map loader is now **arch-generic** (crate `hipfire-reap`), wired into `deepseek4`, `qwen35`, `lfm2moe`, `minimax`. Activate on any of them with -`HIPFIRE_REAP_PLAN=` (a `reap_plan.json`). `cohere2moe` gets the same wiring -once it merges to master. See `docs/superpowers/specs/2026-06-11-generic-moe-reap-design.md`. +`HIPFIRE_REAP_PLAN=` (a `reap_plan.json`). `cohere2moe` is not wired — +no REAP hook exists in `crates/hipfire-arch-cohere2moe`. See `docs/superpowers/specs/2026-06-11-generic-moe-reap-design.md`. A REAP prune is a *pure expert selection*: the kept experts (and the router rows for them) are byte-identical to the full model; only the hash-router `tid2eid` From dc324b9933370b62202bd9654e7e58ef8e5be754 Mon Sep 17 00:00:00 2001 From: Kaden Schutt Date: Fri, 4 Sep 2026 10:12:02 +0000 Subject: [PATCH 7/8] chore(deps): pin shared crate versions once in [workspace.dependencies] anyhow, clap, memmap2, minijinja, minijinja-contrib, serde, serde_json, sha2, thiserror join half/libloading/proptest/safetensors at the root as version-only pins; 31 crate manifests inherit with `workspace = true` and keep exactly the feature sets they declared (derive, env, preserve_order, ...). Textual drift (sha2 0.10 vs 0.10.9, thiserror 2 vs 2.0.17) collapses to one requirement. Cargo.lock is byte-identical: no resolved version changed. cargo tree -d shows one version of each; the remaining duplicates (equator, getrandom, hashbrown, syn, winnow) are pre-existing transitive. --- Cargo.toml | 9 +++++++++ crates/hipfire-arch-cohere2moe/Cargo.toml | 4 ++-- crates/hipfire-arch-deepseek4/Cargo.toml | 4 ++-- crates/hipfire-arch-dots-ocr/Cargo.toml | 2 +- crates/hipfire-arch-gemma4/Cargo.toml | 2 +- crates/hipfire-arch-lfm2-vl/Cargo.toml | 2 +- crates/hipfire-arch-lfm2moe/Cargo.toml | 4 ++-- crates/hipfire-arch-maple/Cargo.toml | 4 ++-- crates/hipfire-arch-minimax/Cargo.toml | 4 ++-- crates/hipfire-arch-muse-glimmer/Cargo.toml | 2 +- crates/hipfire-arch-qwen2/Cargo.toml | 4 ++-- crates/hipfire-arch-qwen35-vl/Cargo.toml | 2 +- crates/hipfire-arch-qwen35/Cargo.toml | 4 ++-- crates/hipfire-atlas/Cargo.toml | 4 ++-- crates/hipfire-cli/Cargo.toml | 10 +++++----- crates/hipfire-client/Cargo.toml | 4 ++-- crates/hipfire-config/Cargo.toml | 6 +++--- crates/hipfire-daemon/Cargo.toml | 2 +- crates/hipfire-detect/Cargo.toml | 4 ++-- crates/hipfire-ds4-parent/Cargo.toml | 6 +++--- crates/hipfire-engine/Cargo.toml | 2 +- crates/hipfire-generate/Cargo.toml | 2 +- crates/hipfire-loader/Cargo.toml | 2 +- crates/hipfire-quantize/Cargo.toml | 8 ++++---- crates/hipfire-reap/Cargo.toml | 2 +- crates/hipfire-registry/Cargo.toml | 6 +++--- crates/hipfire-runtime/Cargo.toml | 10 +++++----- crates/hipfire-tui/Cargo.toml | 6 +++--- crates/radiowave/Cargo.toml | 8 ++++---- crates/redline-dispatch/Cargo.toml | 4 ++-- crates/saddle-lab/Cargo.toml | 4 ++-- crates/saddle-quant/Cargo.toml | 16 ++++++++-------- 32 files changed, 81 insertions(+), 72 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 2295f00545..c2afef8b12 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,7 +53,16 @@ edition = "2021" license = "Apache-2.0" [workspace.dependencies] +anyhow = "1" +clap = "4.6" half = "2.7" libloading = "0.9" +memmap2 = "0.9" +minijinja = "2" +minijinja-contrib = "2" proptest = { version = "1.11", default-features = false, features = ["std"] } safetensors = "0.8" +serde = "1" +serde_json = "1" +sha2 = "0.10" +thiserror = "2" diff --git a/crates/hipfire-arch-cohere2moe/Cargo.toml b/crates/hipfire-arch-cohere2moe/Cargo.toml index 22ebb79693..3f5e9817ee 100644 --- a/crates/hipfire-arch-cohere2moe/Cargo.toml +++ b/crates/hipfire-arch-cohere2moe/Cargo.toml @@ -22,8 +22,8 @@ hipfire-runtime = { path = "../hipfire-runtime" } hipfire-dispatch = { path = "../hipfire-dispatch", features = ["from-hip-error"] } hip-bridge = { path = "../hip-bridge" } rdna-compute = { path = "../rdna-compute" } -serde = { version = "1", features = ["derive"] } -serde_json = "1" +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true # --------------------------------------------------------------------------- # Archived research probes. diff --git a/crates/hipfire-arch-deepseek4/Cargo.toml b/crates/hipfire-arch-deepseek4/Cargo.toml index 9e0dd92ae1..27f3491e2f 100644 --- a/crates/hipfire-arch-deepseek4/Cargo.toml +++ b/crates/hipfire-arch-deepseek4/Cargo.toml @@ -16,8 +16,8 @@ hipfire-runtime = { path = "../hipfire-runtime" } hipfire-ds4-parent = { path = "../hipfire-ds4-parent" } hip-bridge = { path = "../hip-bridge" } rdna-compute = { path = "../rdna-compute" } -serde = { version = "1", features = ["derive"] } -serde_json = { version = "1", features = ["preserve_order"] } +serde = { workspace = true, features = ["derive"] } +serde_json = { workspace = true, features = ["preserve_order"] } hipfire-dispatch = { path = "../hipfire-dispatch", features = ["from-hip-error"] } hipfire-reap = { path = "../hipfire-reap", default-features = false } saddle-core = { path = "../saddle-core" } diff --git a/crates/hipfire-arch-dots-ocr/Cargo.toml b/crates/hipfire-arch-dots-ocr/Cargo.toml index 03aa31765c..994ea2d6ba 100644 --- a/crates/hipfire-arch-dots-ocr/Cargo.toml +++ b/crates/hipfire-arch-dots-ocr/Cargo.toml @@ -21,7 +21,7 @@ hipfire-runtime = { path = "../hipfire-runtime" } hipfire-arch-qwen2 = { path = "../hipfire-arch-qwen2" } hip-bridge = { path = "../hip-bridge" } rdna-compute = { path = "../rdna-compute" } -serde_json = "1" +serde_json.workspace = true # Used by `image.rs` for PNG/JPEG decode. Matches the version pin in # hipfire-arch-qwen35-vl/Cargo.toml; default-features off keeps the # build closure small (only PNG + JPEG are needed for dots.ocr's diff --git a/crates/hipfire-arch-gemma4/Cargo.toml b/crates/hipfire-arch-gemma4/Cargo.toml index 448e33df84..5295942cd5 100644 --- a/crates/hipfire-arch-gemma4/Cargo.toml +++ b/crates/hipfire-arch-gemma4/Cargo.toml @@ -21,7 +21,7 @@ hipfire-runtime = { path = "../hipfire-runtime" } hip-bridge = { path = "../hip-bridge" } rdna-compute = { path = "../rdna-compute" } hipfire-dispatch = { path = "../hipfire-dispatch" } -serde_json = "1" +serde_json.workspace = true # --------------------------------------------------------------------------- # Archived research probes. diff --git a/crates/hipfire-arch-lfm2-vl/Cargo.toml b/crates/hipfire-arch-lfm2-vl/Cargo.toml index 775a690771..1efcf659d2 100644 --- a/crates/hipfire-arch-lfm2-vl/Cargo.toml +++ b/crates/hipfire-arch-lfm2-vl/Cargo.toml @@ -16,6 +16,6 @@ deltanet = ["hipfire-runtime/deltanet", "rdna-compute/deltanet"] hipfire-runtime = { path = "../hipfire-runtime" } hip-bridge = { path = "../hip-bridge" } rdna-compute = { path = "../rdna-compute" } -serde_json = "1" +serde_json.workspace = true image = { version = "0.25", default-features = false, features = ["png", "jpeg"] } libm = "0.2" diff --git a/crates/hipfire-arch-lfm2moe/Cargo.toml b/crates/hipfire-arch-lfm2moe/Cargo.toml index ade9cda4e4..a36ed2a170 100644 --- a/crates/hipfire-arch-lfm2moe/Cargo.toml +++ b/crates/hipfire-arch-lfm2moe/Cargo.toml @@ -17,8 +17,8 @@ hipfire-reap = { path = "../hipfire-reap", default-features = false } # an lfm2_vl artifact was loaded with --include-vision. Acyclic — lfm2-vl # never depends back on this crate. hipfire-arch-lfm2-vl = { path = "../hipfire-arch-lfm2-vl" } -serde = { version = "1", features = ["derive"] } -serde_json = "1" +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true [features] # Archived research probes; see the note by the [[example]] blocks. diff --git a/crates/hipfire-arch-maple/Cargo.toml b/crates/hipfire-arch-maple/Cargo.toml index 1a16147c25..a7b594c31a 100644 --- a/crates/hipfire-arch-maple/Cargo.toml +++ b/crates/hipfire-arch-maple/Cargo.toml @@ -21,8 +21,8 @@ hipfire-runtime = { path = "../hipfire-runtime" } hipfire-dispatch = { path = "../hipfire-dispatch", features = ["from-hip-error"] } hip-bridge = { path = "../hip-bridge" } rdna-compute = { path = "../rdna-compute" } -serde = { version = "1", features = ["derive"] } -serde_json = "1" +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true # --------------------------------------------------------------------------- # Archived research probes. diff --git a/crates/hipfire-arch-minimax/Cargo.toml b/crates/hipfire-arch-minimax/Cargo.toml index 556e4afe0a..13b5569b05 100644 --- a/crates/hipfire-arch-minimax/Cargo.toml +++ b/crates/hipfire-arch-minimax/Cargo.toml @@ -22,8 +22,8 @@ hipfire-dispatch = { path = "../hipfire-dispatch", features = ["from-hip-error"] hip-bridge = { path = "../hip-bridge" } rdna-compute = { path = "../rdna-compute" } hipfire-reap = { path = "../hipfire-reap", default-features = false } -serde = { version = "1", features = ["derive"] } -serde_json = "1" +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true # --------------------------------------------------------------------------- # Archived research probes. diff --git a/crates/hipfire-arch-muse-glimmer/Cargo.toml b/crates/hipfire-arch-muse-glimmer/Cargo.toml index 612fbd5063..4bbb0ce542 100644 --- a/crates/hipfire-arch-muse-glimmer/Cargo.toml +++ b/crates/hipfire-arch-muse-glimmer/Cargo.toml @@ -19,7 +19,7 @@ hipfire-runtime = { path = "../hipfire-runtime" } hip-bridge = { path = "../hip-bridge" } rdna-compute = { path = "../rdna-compute" } hipfire-dispatch = { path = "../hipfire-dispatch" } -serde_json = "1" +serde_json.workspace = true # --------------------------------------------------------------------------- # Archived research probes. diff --git a/crates/hipfire-arch-qwen2/Cargo.toml b/crates/hipfire-arch-qwen2/Cargo.toml index 830048edc7..f26695f664 100644 --- a/crates/hipfire-arch-qwen2/Cargo.toml +++ b/crates/hipfire-arch-qwen2/Cargo.toml @@ -21,8 +21,8 @@ hipfire-runtime = { path = "../hipfire-runtime" } hipfire-dispatch = { path = "../hipfire-dispatch" } hip-bridge = { path = "../hip-bridge" } rdna-compute = { path = "../rdna-compute" } -serde = { version = "1", features = ["derive"] } -serde_json = "1" +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true # --------------------------------------------------------------------------- # Archived research probes. diff --git a/crates/hipfire-arch-qwen35-vl/Cargo.toml b/crates/hipfire-arch-qwen35-vl/Cargo.toml index 7cbba19b7f..a0bc79a47d 100644 --- a/crates/hipfire-arch-qwen35-vl/Cargo.toml +++ b/crates/hipfire-arch-qwen35-vl/Cargo.toml @@ -19,7 +19,7 @@ hipfire-config = { path = "../hipfire-config" } hipfire-runtime = { path = "../hipfire-runtime" } hip-bridge = { path = "../hip-bridge" } rdna-compute = { path = "../rdna-compute" } -serde_json = "1" +serde_json.workspace = true # image preprocessing (PNG/JPEG decode + resize) for the vision encoder # input pipeline lives in this crate (`crate::image`). Same default-feature # gating as runtime had pre-PR-9. diff --git a/crates/hipfire-arch-qwen35/Cargo.toml b/crates/hipfire-arch-qwen35/Cargo.toml index 0a2af2d076..4a91addd32 100644 --- a/crates/hipfire-arch-qwen35/Cargo.toml +++ b/crates/hipfire-arch-qwen35/Cargo.toml @@ -21,8 +21,8 @@ hip-bridge = { path = "../hip-bridge" } rdna-compute = { path = "../rdna-compute" } hipfire-reap = { path = "../hipfire-reap", default-features = false } saddle-core = { path = "../saddle-core" } -serde = { version = "1", features = ["derive"] } -serde_json = "1" +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true [[example]] name = "test_qwen35_load_multi" path = "examples/test_qwen35_load_multi.rs" diff --git a/crates/hipfire-atlas/Cargo.toml b/crates/hipfire-atlas/Cargo.toml index 34e4ca9b1a..b7c79caa92 100644 --- a/crates/hipfire-atlas/Cargo.toml +++ b/crates/hipfire-atlas/Cargo.toml @@ -7,8 +7,8 @@ description = "Kernel Atlas: typed measurement schema + JSONL writer for hipfire [dependencies] regex = "1" -serde = { version = "1", features = ["derive"] } -serde_json = "1" +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true [[bin]] name = "hipfire-atlas" diff --git a/crates/hipfire-cli/Cargo.toml b/crates/hipfire-cli/Cargo.toml index bbe77622f4..9249e4ad3c 100644 --- a/crates/hipfire-cli/Cargo.toml +++ b/crates/hipfire-cli/Cargo.toml @@ -11,9 +11,9 @@ path = "src/main.rs" [dependencies] -anyhow = "1" +anyhow.workspace = true bytes = "1" -clap = { version = "4.6", features = ["derive"] } +clap = { workspace = true, features = ["derive"] } ctrlc = { version = "3", features = ["termination"] } http-body-util = "0.1" hyper = { version = "1", features = ["http1", "server"] } @@ -25,9 +25,9 @@ hipfire-registry = { path = "../hipfire-registry" } hipfire-runtime = { path = "../hipfire-runtime", default-features = false, features = ["deltanet"] } saddle-core = { path = "../saddle-core" } -serde = { version = "1", features = ["derive"] } -serde_json = "1" -sha2 = "0.10" +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true +sha2.workspace = true tokio = { version = "1", features = ["macros", "rt-multi-thread", "net", "sync", "time"] } tokio-util = { version = "0.7", features = ["rt"] } ureq = "3" diff --git a/crates/hipfire-client/Cargo.toml b/crates/hipfire-client/Cargo.toml index 5805c422ae..bdc85ce95e 100644 --- a/crates/hipfire-client/Cargo.toml +++ b/crates/hipfire-client/Cargo.toml @@ -6,6 +6,6 @@ license.workspace = true [dependencies] hipfire-config = { path = "../hipfire-config" } -serde_json = "1" -thiserror = "2" +serde_json.workspace = true +thiserror.workspace = true ureq = "3" diff --git a/crates/hipfire-config/Cargo.toml b/crates/hipfire-config/Cargo.toml index 1f95c98250..f7f06554c5 100644 --- a/crates/hipfire-config/Cargo.toml +++ b/crates/hipfire-config/Cargo.toml @@ -5,7 +5,7 @@ edition.workspace = true license.workspace = true [dependencies] -serde = { version = "1", features = ["derive"] } -serde_json = "1" -thiserror = "2" +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true +thiserror.workspace = true toml = "0.9" diff --git a/crates/hipfire-daemon/Cargo.toml b/crates/hipfire-daemon/Cargo.toml index 82f8a883df..5a68d44ef9 100644 --- a/crates/hipfire-daemon/Cargo.toml +++ b/crates/hipfire-daemon/Cargo.toml @@ -40,7 +40,7 @@ hipfire-arch-qwen35 = { path = "../hipfire-arch-qwen35" } # Direct external deps used by daemon.rs base64 = "0.22" -serde_json = { version = "1", features = ["preserve_order"] } +serde_json = { workspace = true, features = ["preserve_order"] } tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter", "fmt", "json"] } libc = "0.2" diff --git a/crates/hipfire-detect/Cargo.toml b/crates/hipfire-detect/Cargo.toml index 6ff6f2b7dc..e0f3be2874 100644 --- a/crates/hipfire-detect/Cargo.toml +++ b/crates/hipfire-detect/Cargo.toml @@ -6,7 +6,7 @@ license.workspace = true description = "Observational coherence/behavior detectors — token attractors, special-token leaks, n-gram density, tool-call shape. GPU-independent. Consumed by coherence_probe and CI gate scripts." [dependencies] -serde = { version = "1", features = ["derive"] } -serde_json = "1" +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true regex = "1" md5 = "0.8" diff --git a/crates/hipfire-ds4-parent/Cargo.toml b/crates/hipfire-ds4-parent/Cargo.toml index fa31160352..5bdffde7e6 100644 --- a/crates/hipfire-ds4-parent/Cargo.toml +++ b/crates/hipfire-ds4-parent/Cargo.toml @@ -14,9 +14,9 @@ hipfire-config = { path = "../hipfire-config" } hipfire-runtime = { path = "../hipfire-runtime" } rdna-compute = { path = "../rdna-compute" } hip-bridge = { path = "../hip-bridge" } -serde = { version = "1", features = ["derive"] } -serde_json = { version = "1", features = ["preserve_order"] } -memmap2 = "0.9" +serde = { workspace = true, features = ["derive"] } +serde_json = { workspace = true, features = ["preserve_order"] } +memmap2.workspace = true [dev-dependencies] libloading.workspace = true diff --git a/crates/hipfire-engine/Cargo.toml b/crates/hipfire-engine/Cargo.toml index 67ab49002e..a8144ebd33 100644 --- a/crates/hipfire-engine/Cargo.toml +++ b/crates/hipfire-engine/Cargo.toml @@ -11,4 +11,4 @@ hipfire-loader = { path = "../hipfire-loader" } hipfire-runtime = { path = "../hipfire-runtime" } rdna-compute = { path = "../rdna-compute" } saddle-core = { path = "../saddle-core" } -serde_json = "1" +serde_json.workspace = true diff --git a/crates/hipfire-generate/Cargo.toml b/crates/hipfire-generate/Cargo.toml index f0241f746b..18b72bff6f 100644 --- a/crates/hipfire-generate/Cargo.toml +++ b/crates/hipfire-generate/Cargo.toml @@ -43,7 +43,7 @@ hipfire-arch-maple = { path = "../hipfire-arch-maple" } hipfire-arch-gemma4 = { path = "../hipfire-arch-gemma4" } hipfire-arch-muse-glimmer = { path = "../hipfire-arch-muse-glimmer" } base64 = "0.22" -serde_json = { version = "1", features = ["preserve_order"] } +serde_json = { workspace = true, features = ["preserve_order"] } tracing = "0.1" [features] diff --git a/crates/hipfire-loader/Cargo.toml b/crates/hipfire-loader/Cargo.toml index 6e600544b7..5b0ae60f16 100644 --- a/crates/hipfire-loader/Cargo.toml +++ b/crates/hipfire-loader/Cargo.toml @@ -43,7 +43,7 @@ hipfire-arch-maple = { path = "../hipfire-arch-maple" } hipfire-arch-gemma4 = { path = "../hipfire-arch-gemma4" } hipfire-arch-muse-glimmer = { path = "../hipfire-arch-muse-glimmer" } hipfire-arch-dots-ocr = { path = "../hipfire-arch-dots-ocr" } -serde_json = "1" +serde_json.workspace = true # --------------------------------------------------------------------------- # Archived research probes. diff --git a/crates/hipfire-quantize/Cargo.toml b/crates/hipfire-quantize/Cargo.toml index 2b0b6d756e..3d30879710 100644 --- a/crates/hipfire-quantize/Cargo.toml +++ b/crates/hipfire-quantize/Cargo.toml @@ -12,12 +12,12 @@ lab = [] hipfire-config = { path = "../hipfire-config" } faer = { version = "0.24", default-features = false, features = ["rayon", "std"] } libloading = { workspace = true } -memmap2 = "0.9" +memmap2.workspace = true safetensors.workspace = true half.workspace = true -clap = { version = "4.6", features = ["derive", "env"] } -serde = { version = "1", features = ["derive"] } -serde_json = "1" +clap = { workspace = true, features = ["derive", "env"] } +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true byteorder = "1" rayon = "1" libc = "0.2" diff --git a/crates/hipfire-reap/Cargo.toml b/crates/hipfire-reap/Cargo.toml index 0e19e74c8a..2a2cdf35c6 100644 --- a/crates/hipfire-reap/Cargo.toml +++ b/crates/hipfire-reap/Cargo.toml @@ -7,7 +7,7 @@ license.workspace = true [dependencies] hipfire-config = { path = "../hipfire-config" } hipfire-runtime = { path = "../hipfire-runtime" } -serde_json = { version = "1", default-features = false, features = ["preserve_order"] } +serde_json = { workspace = true, features = ["preserve_order"] } [dev-dependencies] tempfile = "3" diff --git a/crates/hipfire-registry/Cargo.toml b/crates/hipfire-registry/Cargo.toml index 83aa31ee2d..38706175f7 100644 --- a/crates/hipfire-registry/Cargo.toml +++ b/crates/hipfire-registry/Cargo.toml @@ -6,7 +6,7 @@ license.workspace = true [dependencies] hipfire-config = { path = "../hipfire-config" } -serde = { version = "1", features = ["derive"] } -serde_json = "1" -thiserror = "2" +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true +thiserror.workspace = true ureq = "3" diff --git a/crates/hipfire-runtime/Cargo.toml b/crates/hipfire-runtime/Cargo.toml index 8e8488630c..ffa274fa1d 100644 --- a/crates/hipfire-runtime/Cargo.toml +++ b/crates/hipfire-runtime/Cargo.toml @@ -55,17 +55,17 @@ hipfire-config = { path = "../hipfire-config" } rdna-compute = { path = "../rdna-compute" } saddle-core = { path = "../saddle-core" } hipfire-dispatch = { path = "../hipfire-dispatch" } -memmap2 = "0.9" +memmap2.workspace = true safetensors.workspace = true half.workspace = true byteorder = "1" -serde = { version = "1", features = ["derive"] } +serde = { workspace = true, features = ["derive"] } # preserve_order: keep JSON object key insertion-order (IndexMap) instead of the # default BTreeMap alphabetic sort. Required so request tool-definition key order # survives parse → render → `| tojson`, byte-matching the model's trained # chat_template (HF apply_chat_template preserves insertion order). Feature- # unifies across the workspace build. -serde_json = { version = "1", features = ["preserve_order"] } +serde_json = { workspace = true, features = ["preserve_order"] } libc = "0.2" rayon = "1" # Inline-small token buffer for `spec::SpecStep::emit` — keeps the @@ -88,12 +88,12 @@ regex = "1" # branches use `{{ tool | tojson }}` to emit OpenAI-shape function specs # inside the system block; without it, tool-using turns die at render time # (caught by jinja_smoke scenario C, 2026-05-09). -minijinja = { version = "2", features = ["loop_controls", "json", "preserve_order"] } +minijinja = { workspace = true, features = ["loop_controls", "json", "preserve_order"] } # `pycompat` ships an unknown-method callback that makes Python # str/list/dict methods (e.g. `.startswith`, `.split`, `.rstrip`) # work on plain Jinja values — required by the Qwen3 family # template which uses these throughout. -minijinja-contrib = { version = "2", features = ["pycompat"] } +minijinja-contrib = { workspace = true, features = ["pycompat"] } tracing = "0.1" # Examples in this crate (bench_qwen35_mq4, dflash_spec_demo, etc.) diff --git a/crates/hipfire-tui/Cargo.toml b/crates/hipfire-tui/Cargo.toml index 4b58d6367a..b54250fd0c 100644 --- a/crates/hipfire-tui/Cargo.toml +++ b/crates/hipfire-tui/Cargo.toml @@ -5,13 +5,13 @@ edition.workspace = true license.workspace = true [dependencies] -anyhow = "1" +anyhow.workspace = true base64 = "0.22" crossterm = "0.29" hipfire-config = { path = "../hipfire-config" } hipfire-client = { path = "../hipfire-client" } hipfire-registry = { path = "../hipfire-registry" } ratatui = "0.30" -serde = { version = "1", features = ["derive"] } -serde_json = "1" +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true ureq = { version = "3", default-features = false } diff --git a/crates/radiowave/Cargo.toml b/crates/radiowave/Cargo.toml index 30927f1620..d465a1e467 100644 --- a/crates/radiowave/Cargo.toml +++ b/crates/radiowave/Cargo.toml @@ -28,10 +28,10 @@ default = [] experimental-fp8 = [] [dependencies] -serde = { version = "1", features = ["derive"] } -serde_json = "1" -sha2 = "0.10.9" -thiserror = "2.0.17" +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true +sha2.workspace = true +thiserror.workspace = true [[bin]] name = "radiowave" diff --git a/crates/redline-dispatch/Cargo.toml b/crates/redline-dispatch/Cargo.toml index 9d605eed14..566de22b07 100644 --- a/crates/redline-dispatch/Cargo.toml +++ b/crates/redline-dispatch/Cargo.toml @@ -9,8 +9,8 @@ description = "Hazard-checked HIP/public-AQL record and replay runtime" hipfire-config = { path = "../hipfire-config" } libloading.workspace = true redline-rocr = { path = "../redline-rocr" } -sha2 = "0.10.9" -thiserror = "2.0.17" +sha2.workspace = true +thiserror.workspace = true [dev-dependencies] proptest.workspace = true diff --git a/crates/saddle-lab/Cargo.toml b/crates/saddle-lab/Cargo.toml index 4709815768..a522f28473 100644 --- a/crates/saddle-lab/Cargo.toml +++ b/crates/saddle-lab/Cargo.toml @@ -36,8 +36,8 @@ hipfire-arch-gemma4 = { path = "../hipfire-arch-gemma4" } hipfire-arch-muse-glimmer = { path = "../hipfire-arch-muse-glimmer" } hipfire-detect = { path = "../hipfire-detect" } byteorder = "1" -serde = { version = "1", features = ["derive"] } -serde_json = { version = "1", features = ["preserve_order"] } +serde = { workspace = true, features = ["derive"] } +serde_json = { workspace = true, features = ["preserve_order"] } libc = "0.2" # ── Archived examples (relocated from hipfire-runtime) ─────────────────── diff --git a/crates/saddle-quant/Cargo.toml b/crates/saddle-quant/Cargo.toml index acc2a1b86c..452bad2d5b 100644 --- a/crates/saddle-quant/Cargo.toml +++ b/crates/saddle-quant/Cargo.toml @@ -16,19 +16,19 @@ license.workspace = true default = [] [dependencies] -memmap2 = "0.9" -serde = { version = "1", features = ["derive"] } -serde_json = "1" -sha2 = "0.10" -thiserror = "2" +memmap2.workspace = true +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true +sha2.workspace = true +thiserror.workspace = true # Chat-template rendering for calibration corpora. Matching the workspace # pin in hipfire-runtime so a template renders identically in both. -minijinja = { version = "2", features = ["loop_controls", "json", "preserve_order"] } -minijinja-contrib = { version = "2", features = ["pycompat"] } +minijinja = { workspace = true, features = ["loop_controls", "json", "preserve_order"] } +minijinja-contrib = { workspace = true, features = ["pycompat"] } # CLI only. The library never parses arguments. -clap = { version = "4.6", features = ["derive"] } +clap = { workspace = true, features = ["derive"] } [dev-dependencies] From de4675842591990cec2a012b387a4f37aae3871a Mon Sep 17 00:00:00 2001 From: Kaden Schutt <151092359+Kaden-Schutt@users.noreply.github.com> Date: Sat, 5 Sep 2026 01:40:50 +0000 Subject: [PATCH 8/8] chore(deps): re-add hipfire-config to hipfire-generate The S1 machete pass removed it as unused, which was true when this branch was written. #719 (S4 FeatureFlags) then introduced hipfire_config readers in hipfire-generate -- vision.rs, qwen.rs, dense.rs and 76 more sites -- so after rebasing onto that, the workspace failed with 79 E0433s. The finding expired; the dependency is real again. --- Cargo.lock | 1 + crates/hipfire-generate/Cargo.toml | 3 +++ 2 files changed, 4 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 17edf592fe..07ff9fcced 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1431,6 +1431,7 @@ dependencies = [ "hipfire-arch-qwen2", "hipfire-arch-qwen35", "hipfire-arch-qwen35-vl", + "hipfire-config", "hipfire-engine", "hipfire-loader", "hipfire-pflash", diff --git a/crates/hipfire-generate/Cargo.toml b/crates/hipfire-generate/Cargo.toml index 18b72bff6f..c970bc05e6 100644 --- a/crates/hipfire-generate/Cargo.toml +++ b/crates/hipfire-generate/Cargo.toml @@ -26,6 +26,9 @@ hip-bridge = { path = "../hip-bridge" } rdna-compute = { path = "../rdna-compute" } saddle-core = { path = "../saddle-core" } hipfire-runtime = { path = "../hipfire-runtime" } +# Re-added: S4 (#719) introduced hipfire_config readers in this crate after the +# machete pass that removed it, so the "unused" finding is no longer true. +hipfire-config = { path = "../hipfire-config" } hipfire-loader = { path = "../hipfire-loader" } hipfire-engine = { path = "../hipfire-engine" } hipfire-pflash = { path = "../hipfire-pflash" }