Skip to content

fix(provider): v0.7.1 — engine_v2 allowlist uses fleet catalog ids (drop HF repo ids)#504

Merged
Gajesh2007 merged 1 commit into
masterfrom
fix/engine-v2-allowlist
Jul 3, 2026
Merged

fix(provider): v0.7.1 — engine_v2 allowlist uses fleet catalog ids (drop HF repo ids)#504
Gajesh2007 merged 1 commit into
masterfrom
fix/engine-v2-allowlist

Conversation

@Gajesh2007

@Gajesh2007 Gajesh2007 commented Jul 3, 2026

Copy link
Copy Markdown
Member

fix(provider): v0.7.1 — engine_v2 allowlist uses fleet catalog ids

Root cause

v0.7.0 shipped Engine V2 (ContinuousBatchingV2) default-on, but gated
behind a per-model allowlist whose entries were HuggingFace repo ids:

mlx-community/gpt-oss-20b-MXFP4-Q8
mlx-community/gemma-4-26b-a4b-it-8bit

The production fleet does not advertise those ids. Verified against the prod
DB, online providers advertise the coordinator-catalog model ids:

Fleet catalog id Online providers
gpt-oss-20b 255
gemma-4-26b-8bit 179
gemma-4-26b-qat-4bit 66

EngineV2Config.modelAllowlisted matches case-insensitively on the full id
and the last / path component, on both sides. The catalog ids and the HF
repo ids share no matching component (e.g. last component
gpt-oss-20b-mxfp4-q8gpt-oss-20b), so selection() returned .legacy
for every real model
— Engine V2 never engaged anywhere. The whole fleet
silently ran the legacy BatchedEngine, exactly as if v2 had never shipped.

Fix

Replace the allowlist with the three coordinator-catalog ids the fleet
actually advertises, and drop the HF repo ids entirely:

public static let defaultModelAllowlist = [
    "gpt-oss-20b",
    "gemma-4-26b-8bit",
    "gemma-4-26b-qat-4bit",
]

All three were parity/soak-validated on real weights: gpt-oss-20b and
gemma-4-26b-8bit are the two 8-bit / GPT-OSS production models;
gemma-4-26b-qat-4bit passed strict batch-invariance and benchmarked faster.
Doc comments in EngineV2Config.swift (and the engine_v2 config-key doc in
ProviderConfig.swift) are re-framed: these are coordinator-catalog / fleet
model ids, not HuggingFace repo ids. Matching semantics are unchanged
(case-insensitive; exact or trailing-* prefix glob; full id and last path
component tried on both sides).

Version bumped to 0.7.1 (ProviderCore.version, coordinator
LatestProviderVersion).

Kill switch / rollback

Unchanged and still absolute:

  • Per-box kill switch: DARKBLOOM_ENGINE_V2=0 (or false/no/off)
    forces legacy for that provider, beats config, no release needed.
  • Widen scope: DARKBLOOM_ENGINE_V2_MODELS="gpt-oss*,gemma-4*"
    (comma-separated exact ids or trailing-* globs) overrides the default.
  • Release rollback: re-deploy the prior provider bundle; a v2 init failure
    already falls back to legacy with a WARN engine_v2_fallback telemetry event
    (model id + reason), so a bad engine can never take a box down silently.

Before / After

flowchart TB
  subgraph Before["Before (v0.7.0) — v2 inert fleet-wide"]
    A1[request: model gpt-oss-20b] --> B1[provider: EngineV2Config.selection]
    B1 --> C1{"allowlist =\nmlx-community/gpt-oss-20b-MXFP4-Q8,\nmlx-community/gemma-4-26b-a4b-it-8bit"}
    C1 -->|"no id/last-component match"| D1[selection = .legacy]
    D1 --> E1[legacy BatchedEngine]
  end
  subgraph After["After (v0.7.1) — v2 engages on prod models"]
    A2[request: model gpt-oss-20b] --> B2[provider: EngineV2Config.selection]
    B2 --> C2{"allowlist =\ngpt-oss-20b,\ngemma-4-26b-8bit,\ngemma-4-26b-qat-4bit"}
    C2 -->|"exact match"| D2[selection = .v2]
    D2 --> F2[EngineV2Factory.makeBridgeIfSelected]
    F2 -->|builds| G2[EngineV2Bridge / CBv2 engine]
    F2 -->|init throws| H2[legacy fallback + WARN engine_v2_fallback]
    C2 -->|"non-allowlisted (e.g. qwen3-8b)"| D2b[selection = .legacy]
    D2b --> E2[legacy BatchedEngine]
  end
Loading

Tests

EngineV2BridgeTests.swift:

  • defaultAllowlist() rewritten: positives now gpt-oss-20b,
    gemma-4-26b-8bit, gemma-4-26b-qat-4bit + a case-insensitive variant; the
    old HF repo ids are asserted rejected (the exact v0.7.0 miss), plus
    qwen3-8b, llama-3.3-70b, "", and a different gemma quant
    (gemma-4-27b-it-4bit).
  • selectionMatrix(), factoryInitFailureFallsBack(), factorySelectedBuilds()
    updated to use the real fleet ids as their allowlisted examples so they still
    exercise the .v2 path.

EngineV2ProductionWiringTests.swift:

  • initFailureFallsBackWithTelemetry() used the old HF id under the default
    allowlist to reach the makeEngine throw. Under the new allowlist that id
    gates out to legacy before makeEngine, so it was switched to gpt-oss-20b
    otherwise the fallback-telemetry assertion would silently stop being
    exercised.

swift test --filter EngineV2 is green; go build ./... compiles.


View with Codesmith Autofix with Codesmith
Need help on this PR? Tag /codesmith with what you need. Autofix is disabled.

…pt-oss-20b, gemma-4-26b-8bit, gemma-4-26b-qat-4bit), drop HF repo ids

v0.7.0 gated Engine V2 on HuggingFace repo ids (mlx-community/...) that no
production provider advertises — the fleet uses coordinator-catalog ids, so
v2 never engaged and every box silently ran the legacy engine (confirmed
against the prod provider registry). Allowlist now matches the real fleet
ids; QAT-4bit included (validated: strict batch-invariance + faster).
@vercel

vercel Bot commented Jul 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
d-inference Ready Ready Preview Jul 3, 2026 6:07am
d-inference-console-ui-dev Ready Ready Preview Jul 3, 2026 6:07am
d-inference-landing Ready Ready Preview Jul 3, 2026 6:07am

Request Review

@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

This PR contains only a version bump, a doc-comment clarification, and an engine-v2 model allowlist update; no security controls are added, removed, or structurally altered, but the allowlist change deserves one targeted look against T-007/T-012.


Trust boundaries touched

  • TB-002 (Coordinator → Provider WebSocket) — version floor bump in server.go affects which providers are admitted; allowlist change in EngineV2Config.swift affects which models run the v2 engine path.
  • TB-003 (Provider operator vs. process) — EngineV2Config.swift allowlist and ProviderConfig.swift comment touch inference engine selection, which is adjacent to weight-hash and model-identity controls.

Per-threat assessment

Threat File Assessment
T-007 (Provider serves manipulated outputs) EngineV2Config.swift ℹ️ Neutral — the allowlist now uses short coordinator-catalog IDs (gpt-oss-20b, gemma-4-26b-8bit, gemma-4-26b-qat-4bit) instead of HuggingFace org-qualified IDs. The matching logic (case-insensitive, full-id and last-component tried on both sides) is unchanged. Weight-hash enforcement remains fail-open (SEC-007) regardless of this change.
T-012 (Operator replaces model weights) EngineV2Config.swift ℹ️ Neutral — same root cause as T-007; this PR does not touch hash enforcement.
T-011 (X25519 key readable from config) ProviderConfig.swift ℹ️ Neutral — doc-comment reword only; no change to key storage or loading logic.
T-004 (Consumer key escalation to admin scope) server.go ℹ️ Neutral — version constant bump, no auth path change.
T-021 (Unauthenticated MDM webhook) server.go ℹ️ Neutral — no route or middleware change.
T-024 (Admin key compromise) server.go ℹ️ Neutral — no key validation change.
T-040 (Host-header URL injection) server.go ℹ️ Neutral — no URL generation change.

One item worth a second look (not a blocking finding)

EngineV2Config.defaultModelAllowlist now uses bare short IDs with a trailing-component match.

The matching rule tries both the full supplied modelId and its last /-component against both sides of the pattern. With short patterns like gpt-oss-20b, any org-qualified ID whose last path segment is gpt-oss-20b will match — e.g. evil-org/gpt-oss-20b. That was already true in the old code for the bare-id direction, but the old HuggingFace-qualified defaults (mlx-community/...) were longer and harder to collide with accidentally.

This matters for T-007/T-027 only if the coordinator's model catalog also validates the org prefix when a provider advertises a model ID; if catalog admission is purely on the short ID, there is no regression here. Recommend confirming that registry/registry.go model-catalog matching uses the same short-ID semantics and that a provider cannot register attacker-org/gpt-oss-20b and have it treated as an approved fleet model.

EngineV2Config.swift lines 48–70 (new allowlist + comment) and lines 105–113 (matching doc) are the specific location.


New attack surface not covered by an existing threat

None introduced by this diff.


SEC-* findings resolved

None — this PR does not close any open finding.


🔐 Threat model: docs/threat-model.yaml · Updates on each push to this PR

@Gajesh2007
Gajesh2007 merged commit 2ea1ba5 into master Jul 3, 2026
12 of 14 checks passed

@ethenotethan ethenotethan left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated Code Review — Layr-Labs/d-inference#

Verdict: COMMENT

Security — ✅ No issues found

Performance — ✅ No issues found

Type_diligence — ✅ No issues found

Additive_complexity — ✅ No issues found

✅ All four passes clean. No issues found.

🤖 Automated review by Centaur · DAR-186

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1fc36793e3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

"mlx-community/gemma-4-26b-a4b-it-8bit",
"gpt-oss-20b",
"gemma-4-26b-8bit",
"gemma-4-26b-qat-4bit",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Remove the VLM build from the v2 allowlist

For gemma-4-26b-qat-4bit in production, this allowlist entry is never honored: the load path computes slotIsVLM (ProviderLoop+ModelLoading.swift:330) and makeEngineV2BridgeForSlot returns nil for VLM slots before calling EngineV2Config.selection (ProviderLoop+EngineV2.swift:83-89). The live test comments identify the prod QAT build as shipping vision_config, so v0.7.1 still serves that model through the legacy engine while the new default allowlist and rollout messaging imply v2 coverage; either don't advertise QAT as default-v2 or update the VLM/CBv2 path so it can actually build a bridge.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants