src/vt/metal/metal_mlx_provider.mm is compiled by nothing that runs before a merge, so a refactor of the vt::OpProvider seam it depends on breaks it silently and the breakage surfaces at release-cut time. #1584 is the first demonstration: its edit to MlxFallback landed unbuilt and unrun, and #1692 records that.
One correction to #1692 first, because it changes what is owed. #1692 states the file is "compiled by NO job in this repository". That is not accurate. .github/workflows/release.yml:347 mlx_arm64 runs on macos-15, pip install 'mlx==0.32.0', and calls scripts/build-macos-release.sh macos-arm64-metal-mlx preview ... "$mlx_root" 0.32.0 ..., which configures -DVLLM_CPP_MLX=ON and compiles the file for real, against real MLX, on real Apple hardware.
The defect is the trigger, not the absence:
on:
workflow_dispatch: {}
push:
tags: ['v*']
release.yml fires on a v* tag or a manual dispatch. It never runs on a pull request and never on a push to main. .github/workflows/ci.yml — the pre-merge lane — has no macOS runner at all: every one of its 20 runs-on lines is ubuntu-latest, ubuntu-24.04-arm or windows-2022. So the only build of this file happens after the change has landed, and only when somebody cuts a release. A broken .mm is discovered as a blocked release rather than as a red check.
What can be done cheaply, and what cannot.
metal_mlx_provider.mm is the one Metal TU that is plain C++ wearing an ObjC++ extension. It contains zero Objective-C constructs: no message send, no @-keyword, no id<...>, no NS/MTL type outside comments. Its two #imports are <Foundation/Foundation.h> and <Metal/Metal.h>, and it uses nothing from either — the Metal handles reach it as void*, because metal_buffers.h and metal_context.h are deliberately plain C++ (metal_context.h:22: "This header is deliberately PLAIN C++ (no Objective-C types)"). The other three (metal_ops.mm, metal_backend.mm, metal_context.mm) carry real ObjC and are not covered by this.
That makes a compile-only bit-rot guard possible on Linux, in the shape this tree already uses twice: vllm_rocm_platform_syntax_check (CMakeLists.txt:1665, an OBJECT library that is never linked, whose comment states this exact argument) and vllm_music3_depth_stage_ab_{before,after} (CMakeLists.txt:2546).
Scope, stated as a limit rather than a claim. Such a target must stub the two Apple framework headers (trivially — nothing is used from them) and the six MLX public headers. It therefore proves that the file compiles against the real vt:: seam headers, and proves nothing about the MLX API, which only mlx_arm64 can. That is the whole defect being closed and no more of it: the #1584 break was a change to our header, not to MLX.
Owed after such a change, and not discharged by it: the CUDA and Metal runtime arms of #1692 (a GPU and a Mac), and the MLX API surface (release-time only).
src/vt/metal/metal_mlx_provider.mmis compiled by nothing that runs before a merge, so a refactor of thevt::OpProviderseam it depends on breaks it silently and the breakage surfaces at release-cut time. #1584 is the first demonstration: its edit toMlxFallbacklanded unbuilt and unrun, and #1692 records that.One correction to #1692 first, because it changes what is owed. #1692 states the file is "compiled by NO job in this repository". That is not accurate.
.github/workflows/release.yml:347mlx_arm64runs onmacos-15,pip install 'mlx==0.32.0', and callsscripts/build-macos-release.sh macos-arm64-metal-mlx preview ... "$mlx_root" 0.32.0 ..., which configures-DVLLM_CPP_MLX=ONand compiles the file for real, against real MLX, on real Apple hardware.The defect is the trigger, not the absence:
release.ymlfires on av*tag or a manual dispatch. It never runs on a pull request and never on a push tomain..github/workflows/ci.yml— the pre-merge lane — has no macOS runner at all: every one of its 20runs-onlines isubuntu-latest,ubuntu-24.04-armorwindows-2022. So the only build of this file happens after the change has landed, and only when somebody cuts a release. A broken.mmis discovered as a blocked release rather than as a red check.What can be done cheaply, and what cannot.
metal_mlx_provider.mmis the one Metal TU that is plain C++ wearing an ObjC++ extension. It contains zero Objective-C constructs: no message send, no@-keyword, noid<...>, noNS/MTLtype outside comments. Its two#imports are<Foundation/Foundation.h>and<Metal/Metal.h>, and it uses nothing from either — the Metal handles reach it asvoid*, becausemetal_buffers.handmetal_context.hare deliberately plain C++ (metal_context.h:22: "This header is deliberately PLAIN C++ (no Objective-C types)"). The other three (metal_ops.mm,metal_backend.mm,metal_context.mm) carry real ObjC and are not covered by this.That makes a compile-only bit-rot guard possible on Linux, in the shape this tree already uses twice:
vllm_rocm_platform_syntax_check(CMakeLists.txt:1665, an OBJECT library that is never linked, whose comment states this exact argument) andvllm_music3_depth_stage_ab_{before,after}(CMakeLists.txt:2546).Scope, stated as a limit rather than a claim. Such a target must stub the two Apple framework headers (trivially — nothing is used from them) and the six MLX public headers. It therefore proves that the file compiles against the real
vt::seam headers, and proves nothing about the MLX API, which onlymlx_arm64can. That is the whole defect being closed and no more of it: the #1584 break was a change to our header, not to MLX.Owed after such a change, and not discharged by it: the CUDA and Metal runtime arms of #1692 (a GPU and a Mac), and the MLX API surface (release-time only).