Repository navigation
Tensor inference, opt-in vocal separation, GPU runtime, and cross-platform CI - #9
Merged
Merged
Conversation
… roots defaultRoots() collected candidates in a std::set, so roots were searched in lexicographic order rather than priority order. AUTOMIX_ASSET_ROOT only acted as an override when its path happened to sort before the executable's tree; from a checkout under C:\2AHOLD the repo's own bundled binary won and "PhaseLimiter discovery supports AUTOMIX_ASSET_ROOT override" failed. Roots are now an ordered vector (override first), deduplicated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds a tensor-graph inference path alongside the scalar IModelInference one, and wires an MIT-licensed BS-RoFormer ONNX export into single-mix import as an opt-in separator. Off by default; with the flag off, separation output is byte-identical (tested). - TensorTypes / ITensorInference / OnnxTensorInference: float32 tensor I/O with graph spec probing; ORT 1.30.0, CPU provider only. Without the native SDK every load fails with a diagnostic, never an approximation. - SpectrogramFrontEnd: torch.stft-compatible STFT/iSTFT (golden fixture). - SeparationRunner: chunked overlap-add, mask/direct output modes, residual stems (instrumental = mix - vocals), all-or-nothing on failure. - ModelPack tensor_contract (optional, no schema bump) with load-time checks that name the tensor and both shapes on mismatch. - Catalog: xycld/BS-RoFormer-ONNX, pinned to the single-file quantized build (the alphabetically-first .onnx is an fp32 stub that needs a 640 MB sidecar). Install probes the graph and writes real tensor names. MIT: attribution in NOTICE and the licensing audit, no consent prompt. - RenderSettings::tensorSeparationEnabled (default false) -> ImportController -> StemSeparator. Any tensor failure falls back to the existing separator and says why in the log. - Latent fixes reached by the ON build: EP header glob for the flat release zip, EnableProfiling wchar_t path, corrupt model no longer recorded as a failed cpu provider. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ModelLicensePolicy::licenseUrl() and consentReason() return std::string_view, which juce::String cannot be constructed from. Since 549cf1d the GUI target (AutoMixMasterApp) failed to compile with C2440; the test and tool targets never include ModelBrowserPanel, so no suite caught it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- ControlDeck: "Vocal Model" toggle beside AI Stem Separation, enabled only while separation is on. Drives RenderSettings::tensorSeparationEnabled, synced on session load/save. - Session JSON persists tensorSeparationEnabled; sessions saved before the key existed load with it off (tested). - automix_dev_tools separate --mix --out [--pack] [--tensor] [--json] runs StemSeparator exactly as single-mix import does. Verified against the real xycld/BS-RoFormer-ONNX quantized build: hub install pinned the quantized file and probed names input/output; a 196 s track separated in 33 chunks, with the vocal stem ~97 dB below a full-level mix in instrumental sections. CPU-only run took 687 s (~3.5x real time). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The reader thread can load the meter atomics before the writer's first store, so it sees the initial -60 and the range check reported a torn read that never happened. Scheduling-dependent: it failed 4/5 runs on the CUDA build. Now 0/60 across all three build configurations. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The generic string-keyed AppendExecutionProvider() does not accept CUDA
or TensorRT ("Unknown provider name 'CUDA'"), so every CUDA request threw
and OnnxModelInference silently ran on CPU while recording cuda as failed.
CUDA has never actually been used by the app.
- Provider appending moves to a shared header (OrtSessionProviders.h);
CUDA and TensorRT use AppendExecutionProvider_*_V2.
- CUDA arena uses kSameAsRequested (needed for per-run shrinkage).
- A session that fails to open because of the model itself (ORT error
codes NO_SUCHFILE / NO_MODEL / INVALID_PROTOBUF / INVALID_GRAPH /
MODEL_LOADED) no longer marks the GPU provider as failed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Cancellation - RunnerConfig::cancelRequested is checked before every chunk, and ITensorInference::runCancellable lets the ORT backend abort an in-flight Run via RunOptions::SetTerminate from a watcher thread. A cancelled separation writes nothing and never falls back to another separator. - Import passes ThreadPoolJob cancellation through. Real model: cancel at 5.0 s returned at 5.7 s, mid-chunk (a CPU chunk takes ~20 s). GPU - Tensor sessions try GPU providers in order and fall back to CPU, reporting the provider actually used; a GPU run that fails mid-way is retried once on CPU. Import honours preferHardwareAcceleration and gpuExecutionProvider; a named provider missing from this runtime still means "use a GPU". - Per-run CUDA arena shrinkage: without it BS-RoFormer's second chunk overflowed 16 GB of VRAM into shared memory (42 s/chunk vs ~2.5 s). - Catalog installs the fp32 BS-RoFormer build where a GPU session really opens (in-memory probe), else the quantized build. Measured on an RTX 5060 Ti, 196 s track: fp32/CUDA 85-91 s, quantized/CPU 687 s, quantized/CUDA no faster than CPU, fp32/CPU ~45% slower than quantized. - ORT 1.30 cannot load the fp32 export (shape inference cannot read external initializers), so the installer folds "<model>.data" into the model in place with inlineExternalData(), a dependency-free protobuf rewrite that refuses locations outside the model directory. No weights are re-hosted. - CMake stages ORT (and optional AUTOMIX_CUDA_RUNTIME_DIR) DLLs beside each executable so a System32 onnxruntime.dll can no longer shadow it. - dev tools: separate --provider and --cancel-after-ms. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The fp32 BS-RoFormer build peaks at 9442 MiB of device memory per chunk (RTX 5060 Ti, CUDA 13, arena shrinkage). Below that it spills into shared system memory, which measured slower than running on CPU. - queryCudaDeviceMemory(): free/total of CUDA device 0 via cudaMemGetInfo from the CUDA runtime loaded at run time; nothing links against CUDA. - Install: fp32 is chosen only when the GPU probe opened a CUDA session and the device totals >= 10 GiB + 1.5 GiB headroom (12 GB cards qualify, 8 GB cards get the quantized build). - Run: packs declare gpu_memory_mb (10240 for fp32); when free memory is below it, separation runs on CPU and the log says why. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The CUDA execution provider needs NVIDIA's CUDA runtime, cuBLAS, cuFFT and cuDNN (~1.3 GB unpacked). Rather than ship them with every install, the app offers them once, to machines that can use them. - GpuRuntimePack: NVIDIA's redistributable wheels from PyPI, pinned by URL + SHA-256 (~1.02 GB download); only DLLs are extracted (entries escaping the archive are refused) into %LOCALAPPDATA%\AutoMixMaster\gpu-runtime\<version>\bin. A versioned marker is written last, so failed, cancelled or older installs are never trusted. No admin rights, no system CUDA, no PATH changes. - preload() loads the DLLs by full path before the GPU probe, tensor sessions and the device-memory query; the probe now caches only success so a pack installed mid-session takes effect. - Offer: when Vocal Model is switched on and an NVIDIA adapter with >= 11.5 GiB (read via DXGI) is present, the ORT build has CUDA and the pack is missing, a consent dialog names NVIDIA's licence; the download runs in the background with progress in the task history and stops if the window closes. Offered at most once per run. - automix_dev_tools gpu-runtime status|install. - NOTICE: GPU runtime section (not shipped or re-hosted; NVIDIA terms). Verified on an executable with the CUDA ORT build but no CUDA DLLs: before install no GPU session opens; after `gpu-runtime install` (84 s, 16 libraries) preload succeeds, a CUDA session opens and the fp32 vocal model separates the 196 s test track on CUDA in 66 s. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…time - Offer the GPU runtime only with an NVIDIA driver >= 580 (CUDA 13), read from the DXGI user-mode driver version (32.0.16.1074 -> 610.74). - After the runtime installs, a BS-RoFormer pack still on its quantized build is reinstalled as the fp32 GPU build and the old file removed (upgradeBsRoformerForGpu; verified 166 MB -> 645 MB, idempotent). - Settings gains a GPU acceleration row (status + Install/Remove). uninstall() drops the marker first and defers files locked by this process to completePendingRemoval() at the next start; it refuses folders that are not a runtime pack. - Skip the two libraries ONNX Runtime never loads (cufftw, nvblas). A BS-RoFormer run loads only cuBLAS/cuBLASLt and three cuDNN parts, but convolution, FFT and RNN graphs need the rest, so nothing else is cut. - OnnxModelInference now preloads the runtime pack too; without it scalar models could never use CUDA on a user's machine. - The GPU recovery tests load on CPU before pinning providers, so they no longer depend on whether CUDA libraries exist on the test machine. - dev tools: gpu-runtime remove|upgrade-models. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- install() + CPack produce a portable ZIP of the "application" component only (the fetched dependencies' headers and libraries stay out): the app, its assets, NOTICE/README and the ONNX Runtime DLLs. An install-time guard fails if any .onnx file or NVIDIA CUDA library lands in the package. - packaging/windows/build-release.ps1: fresh configure, build, tests, cpack. Verified end to end: 224/224 tests, 196 MB ZIP; the extracted app starts and loads its own onnxruntime.dll. - The post-build step copied all of assets/phaselimiter next to the app on every GUI build, including 13 GB of renderer scratch audio (tmp/) and 352 MB of stray downloaded models; it now stages only bin/, resource/, licenses/, LICENSE and README.md. - README: GPU acceleration and release-packaging sections. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PhaseLimiter never rendered: the renderer passed -mastering=true without -mastering_reference_file, so phase_limiter.exe read ./mastering_reference.json, failed with "auto mastering error: syntax error", and every export silently fell back to BuiltIn. Cleanup ran only on success, so each failure leaked its input WAV and work directory into installRoot/tmp (733 of each, 13 GB, on this machine). - Pass mastering_reference.json and sound_quality2_cache by absolute path; an install without the reference counts as unavailable. - Scratch lives in %TEMP%\automix_phaselimiter\<run> behind an RAII guard that removes it on every exit path. The process-wide working directory change (racy under parallel renders) is gone: absolute paths, including non-ASCII ones, work from any cwd. - First render per process sweeps only the leaked legacy patterns (input_*.wav, phase_output_*.wav, work_*) and our own runs >24 h old. Owner decision: PhaseLimiter is opt-in. - Default renderer and built-in profiles use BuiltIn; selecting PhaseLimiter (single mode, logical_all primary or a custom chain) is the opt-in. logical_all is otherwise unchanged and no longer adds PhaseLimiter as an automatic stage. - Session schema 3: sessions saved earlier that stored "PhaseLimiter" (the old default) load as BuiltIn - exactly what they always rendered. Golden files are unaffected (the regression harness renders with BuiltIn directly). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Downloaded models lived in "assets/modelhub" relative to the working
directory: it moved with the cwd and is not writable under Program
Files.
- defaultModelHubRoot(): %LOCALAPPDATA%\AutoMixMaster\modelhub (user
app data elsewhere), or AUTOMIX_MODEL_HUB_ROOT for portable installs.
Both hubs, ModelManager, ModelController, MainLayout and dev tools use
it; bundled read-only packs ("ModelPacks") are still scanned.
- migrateModelHub() moves the legacy hub once at startup: pack folders
(copy+delete across volumes), install_registry.json and
license_consents.json merged by modelId with the target winning,
registry installPaths rewritten, install log appended, MIGRATED.txt
left behind. Recorded licence consents therefore survive the move.
- Uninstall refuses a registry installPath outside the hub instead of
remove_all-ing whatever the file names.
- Tests run against a throwaway hub (TestMain.cpp listener), so suites
never write to the user's profile.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… claim - Uninstall refused any registry installPath outside the model hub, even when that directory no longer existed, so a stale entry (e.g. an unmigrated legacy assets/modelhub path) could never be removed. A missing directory is now just unregistered; an existing one outside the hub is still refused. - ControllerTests: hostile uninstall cases against the real ModelController (outside dir, ../.. traversal, NTFS junction to outside, stale entry, normal in-hub removal). - The quantized BS-RoFormer build is not "no faster than CPU" on CUDA: it takes 303-504 s vs 687 s on CPU for the 196 s track (the old figure was summed CPU time). fp32 on CUDA (73-91 s) is still 4-7x faster, so the GPU upgrade stands; comment and README corrected. - Remove model-hub metadata accidentally committed under assets/phaselimiter/assets (leaked there by the old cwd change). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The GUI upgrade replaced the quantized BS-RoFormer file with the fp32 build
but left the scanned pack pointing at the deleted quantized file, so every
separation until restart was rejected ('missing model file') and silently
fell back to the frequency splitter. Found by driving the GUI: after the
fix, the post-upgrade import ran tensor separation on the fp32 pack.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…mb gpu allow-lists Update priority chain to include webgpu (ANE, CoreML, CUDA, WebGPU, OpenVINO, DirectML, CPU) and deliberately update pinned-order tests. Map WebGpuExecutionProvider/webgpu/wgpu canonical names and set Windows platform-preferred provider to webgpu. Implement per-pack gpu_providers allow-list filtering for tensor candidates, plumb allow-list through ModelPackLoader -> StemSeparator -> OnnxTensorInference, and restrict BS-RoFormer to CUDA until measured. Update macOS version requirements in GpuCapabilityDetector.
…dened OrtRuntime and probe cache Phase A implementation: - A1: Distinguish tuned and untuned session options via gpu::sessionConfigPlan. Untuned sessions (tensor sessions and probes) leave ORT thread defaults intact, fixing CPU single-threading regression. - A2: Automatically default legacy BS-RoFormer pack manifests to [cuda] allow-list in ModelPackLoader. - A3: Harden OrtRuntime with #if AUTOMIX_HAS_EP_PLUGIN compile guards, std::call_once init order safety, intentionally leaked singleton static pointer, 32k wchar path resolution, device info in diagnostics, asynchronous warm-up, and diagnostics surfaced in OnnxTensorInference. - A4: Implement failure caching in tensorProviderUsable, add invalidateTensorProviderProbeCache(), and invoke it on GPU runtime install/uninstall in MainLayout.cpp and ModelCommands.cpp. - A5 spike result: WebGPU plugin registered successfully on Windows x64 with 2 WebGPU devices found (chosen: vendor=NVIDIA, deviceId=11524, type=1). Co-Authored-By: Muse Spark 1.3 <noreply@opencode>
…orkflows, and model bench
…in on every platform
…elease v0.2.0-native1
…t hashes, and stage assets offline Round 2 follow-up addressing R2-2, R2-3, R2-5, R2-6/P3, and R2-8: - Point linux-x64 back at upstream static release.tar.xz (0b382ba7...) to eliminate distro glibc/boost regressions - Remove unverified empty-hash pins from download table and reject empty-hash downloads before network fetch - Add cmake/FetchPhaseLimiter.cmake to fetch and stage bin/ and resource/ assets beside executables (AUTOMIX_FETCH_PHASELIMITER) - Add macOS Gatekeeper first-launch approval instructions in README.md - Add strict 64-hex SHA-256 assertions and empty-hash rejection test in PhaseLimiterDiscoveryTests
… and recurrence guards
…ed licenses, Windows ARM64 emulation)
…; missing ffmpeg is a render error
…a provider mismatch
…f timing the failures
… and a single CPU run for --provider cpu
…hen the vocal model would run on CPU there Measured on an 8 GiB MacBook Neo: CoreML and ANE were SIGKILLed during the first BS-RoFormer inference and the CPU path took over 5 minutes per chunk. AUTOMIX_ENABLE_COREML=1 opts in; naming the provider explicitly still works.
…mory machines Adds magnitude_channels input and ratio_mask output to the tensor runner (mix phase kept), a curated MIT pack (36 MB, CPU), NOTICE and licensing audit rows, and points the low-memory Mac warning at it. 60 s of audio separates in 0.9 s on an 8 GiB MacBook Neo, where BS-RoFormer needed over 5 minutes per chunk.
…mory warning when it is already active The curated Open-Unmix pack took its revision and sha256 from the live HF API, so a later push to the repo would change what installs. applyCuratedPin overrides both with pinned values, and the existing hash check rejects anything else. The low-memory Mac warning told users to install Open-Unmix even when it was already the active separation pack; it now stays quiet in that case. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tatus badge, Default Streaming as the default master
- The shortcuts dialog was never added to the desktop, so "?" and Ctrl+/ showed
nothing and swallowed the next click; it now opens as a DialogWindow. Key names
and the batch em dash were built with the integer String constructor ("8212").
- Closing with unsaved changes now asks Save / Don't Save / Cancel; the header shows
"*" while the session differs from the last save or load.
- Clear's confirmation no longer contradicts itself or shows an internal ticket id.
- The status badge uses dark text where white failed contrast; READY replaces IDLE.
- New sessions default to the Default Streaming master preset instead of Udio Optimized.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…age separation controls - Button variants (primary/secondary/quiet/danger): Import is the one primary action until stems exist, then Mix + Master; Save/Load/Models/Settings are quiet; Clear is styled as destructive. - Actions that need stems are disabled until stems are imported; transport too. - The empty waveform is a bordered drop zone that highlights on drag and opens Import on click. - Vocal Model and the model name appear only when AI Stem Separation is on; model names are plain language instead of Hugging Face repo ids. - Renderer and Active chain move into Advanced; combos widened; tooltips for Master, Platform, Renderer and Mode; accessibility titles for combos, sliders and transport. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…at the minimum window size - The batch strip shows only while a batch has items (nothing fed it before, so it only ever showed placeholders); the log is collapsible, collapsed by default, and opens on failure; dialog-open noise is no longer logged; idle progress is hidden. - Meters read "--" instead of -70.0 when there is no signal. - The header profile selector, which was never populated, is hidden; the deck's Profile combo is the single profile control. - Settings has Export / GPU acceleration / Audio output sections, and removing the GPU runtime asks first. The Model Browser opens at 760x560. - Disabled buttons are outlined instead of filled, so they no longer outshine enabled ones. - At 960x640 the settings row wraps instead of clipping Platform, and action buttons use a compact font instead of wrapping. - Tests: ControlDeck stem gating, separation visibility, meter formatting and layout at 940/1500 px; TaskCenterPanel batch strip, log and idle progress visibility. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… warm-up thread at shutdown A sidecar for a model in a repo subfolder was downloaded into that subfolder, but the inline step looked it up by bare file name and never found it. All hub assets now land directly in the install directory. The warm-up thread was detached, so quitting during ONNX Runtime start-up could race library teardown. It is now joined in shutdown(). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…, restore the single-file tip - Quitting while a task runs now asks first, then continues into the unsaved-changes prompt. - The empty state opens Import only on a left click released inside it, and only when the session has no stems; stems without a preview show "Preview unavailable" instead of the import prompt. - The empty state again points single-file users at AI Stem Separation. - Session files saved before the master preset field existed load as Udio Optimized again, as they were mastered; new sessions still default to Default Streaming. - Unit tests cover the quit decision, the click decision and the preset fallback. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…erified cached binaries The MP3 fallback downloaded an encoder and ran it with no integrity check beyond "--version prints something". - Each built-in source now carries the SHA-256 of the exact archive. A download that does not match is deleted before anything is extracted or run, and a source with no hash is refused. - Homebrew bottles are fetched directly by their pinned digest instead of resolving a mutable tag through two manifests. - AUTOMIX_LAME_DOWNLOAD_URL and AUTOMIX_LAME_VERSION now require AUTOMIX_LAME_DOWNLOAD_SHA256. - The cached binary is used only when a marker written by a verified install still matches it, so binaries cached before this change are downloaded again. - Windows on ARM uses the x64 build; its previous URL returns 404. Debian and Homebrew hashes come from their published indexes. rarewares.org publishes none, so the two Windows pins are the files as served on 2026-10-05. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…in list Fixed pins alone break the MP3 fallback when an upstream replaces a file (Debian stable has already moved to 3.100-6+b3 and Homebrew to LAME 4.0). - assets/lame-pins.json is the current pin list. The app reads it from master before downloading and tries those sources first; the built-in pins remain as the fallback when the list is unreachable, invalid, or names a build that does not run on the machine. - The list may only name files under the known rarewares.org and Debian locations, or a Homebrew bottle digest. One bad entry rejects the list. - tools/update_lame_pins.py regenerates the list from Debian's package index, the Homebrew bottle index and the rarewares.org files. - A weekly workflow runs it and opens a pull request when pins change. It is not merged automatically. - AUTOMIX_LAME_SKIP_PIN_UPDATE=1 keeps the app on the built-in pins. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…Linux bottle sources The app copies just bin/lame out of a Homebrew bottle. Checked against the real bottles and on an Apple-silicon Mac: - 3.100 macOS bottles link only system libraries and run. - 4.0 macOS bottles need Homebrew's libmpg123 and fail to launch, so publishing them only added a wasted download before the fallback. - Linux bottles of both versions use a Homebrew placeholder as their loader path and can never run, so the built-in Linux bottle sources were dead and are removed. Linux uses the Debian package. The updater now downloads each candidate bottle, checks it against its digest and skips it when the encoder still points at a Homebrew path. A platform with no usable bottle is left out of the published list and the app uses its built-in pin. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nus glyph and clipped meter captions README - Corrects the shortcuts (Ctrl+Shift+A is Auto Master; Ctrl+/ opens the shortcut list) and the inference notes, which still said no audio-tensor path exists. - Adds presets, the light vocal model, export formats and sessions. - Build steps and developer notes move into collapsed sections. UI - The zoom-out button showed "?": a \u escape in a narrow string is mangled by MSVC. It is now UTF-8 bytes. - The L/R captions were drawn above the meter panel and clipped. - The loudness bar was painted behind the first readout. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
UI/UX pass: working help, unsaved-changes prompt, clear hierarchy, Default Streaming default
…lame-hash-pin # Conflicts: # CMakeLists.txt
Pin LAME downloads to SHA-256, with a reviewed pin list that follows upstream
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds on-device tensor inference and opt-in AI vocal separation, an optional per-user GPU runtime, pinned PhaseLimiter acquisition, and cross-platform CI and release packaging. 60 commits; 98 files.
AI / tensor inference
AUTOMIX_ENABLE_COREML=1or by naming the provider). The app warns before the vocal model runs on the CPU there.e06097dand its sha256, so a later push to the HF repo cannot change what installs.Renderers
applyPlan()stage order is untouched.Tools
automix_dev_tools model bench: measures the requested provider and exits 4 on a provider mismatch, exits 5 when any inference call fails (instead of timing failures), adds--skip-cpu-baseline, and prints progress per run.Build / CI / release
.deband Flatpak packages; adry_runinput builds and verifies everything without publishing.Testing
ctest261/261 pass (two tensor probes skip without the hardware).3b034bf: Native ORT on Windows, macOS 15, Linux x64 and Linux arm64; TSan; golden eval; hygiene and gitleaks.3b034bf(run 37336088500): Windows x64/arm64, macOS x64/arm64, Linux x64/arm64 packages built and verified; publish skipped, no tag or release created.Known gaps
.debpackages.🤖 Generated with Claude Code