fix(newapi): rename qwenBankDhofar channel row name -> qwen (F1a — matches sandbox-controller default AllowedChannels)

NewAPI's channel-router matches a token's `allowed_channels` set against
rows by their `name` field. The sandbox-controller mints per-Sandbox
tokens with `allowed_channels = SANDBOX_DEFAULT_CHANNELS` and that
substitution defaults to `qwen` at
clusters/_template/bootstrap-kit/19a-bp-sandbox.yaml:197 (envsubst
`${SANDBOX_DEFAULT_CHANNELS:-qwen}`).

Pre-fix the qwenBankDhofar default row name was `qwen3.6-bankdhofar`, so
the per-Sandbox token mint succeeded but `/v1/chat/completions` returned
404 `channel not found` on every per-Sandbox call because the router
could not find a row whose `name` matched any entry in the token's
allowed_channels set. This is F1a per walk-plan agent a68cb099's findings
on TBD-V45 (#2115).

Rename the row to `qwen` — the short customer-canonical name that already
appears in the marketplace UI + sandbox UI selector. The internal Bank
Dhofar identifier `qwen3.6-bankdhofar` was an internal naming that leaked
into the wire.

Lockstep changes in this commit:
- clusters/_template/bootstrap-kit/80-newapi.yaml — overlay row name +
  chart pin 1.4.38 -> 1.4.39
- platform/newapi/chart/values.yaml — default name "qwen3.6-bankdhofar"
  -> "qwen"
- platform/newapi/chart/templates/_helpers.tpl — composed-dict default
- platform/newapi/chart/templates/channel-seed-job.yaml — audit-pointer
  ConfigMap dict default + `seed_channel` shell invocation default
- platform/newapi/chart/Chart.yaml — version 1.4.38 -> 1.4.39
- platform/newapi/blueprint.yaml — spec.version 1.4.38 -> 1.4.39
- products/catalyst/bootstrap/api/internal/handler/sme_tenant_gitops.go
  — generated tenant HelmRelease values
- products/catalyst/bootstrap/api/internal/handler/sme_tenant_test.go
  — test expectation lockstep
- clusters/_template/bootstrap-kit/19a-bp-sandbox.yaml — stale-comment
  hygiene (no behaviour change)
- platform/sandbox/chart/values.yaml — stale-comment hygiene

Verification:
- `helm template platform/newapi/chart` with qwenBankDhofar.enabled=true +
  masterKeySecret set renders BOTH the audit-pointer ConfigMap and the
  channel-seed Job's `seed_channel` shell invocation with `name: qwen`.
- `go test products/catalyst/bootstrap/api/internal/handler -run
  SMETenant` passes (test fixture now expects `name: qwen`).
- `go test platform/newapi/internal/handler -run Sandbox` passes (these
  tests use the literal as arbitrary token data, not as channel-router
  contract — no change required).

Refs #2115
This commit is contained in:
hatiyildiz 2026-05-20 22:13:41 +02:00
parent 6c1444b4c1
commit ebb413f2d0
10 changed files with 73 additions and 20 deletions

View File

@ -188,9 +188,10 @@ spec:
# NewAPI channel names the controller stamps as `allowed_channels`
# on every per-Sandbox token mint. Default `qwen` matches the
# only channel bp-newapi's channel-seed-job.yaml writes on a
# fresh Sovereign install (alias for `qwen3.6-bankdhofar`,
# products/sandbox/docs/newapi-proxy-contract.md §2). Per-
# Sovereign overlays MUST extend this list to mirror their
# fresh Sovereign install (the qwenBankDhofar row's customer-
# canonical name; F1a 2026-05-20 renamed the row from
# `qwen3.6-bankdhofar` to `qwen` so it matches this default).
# Per-Sovereign overlays MUST extend this list to mirror their
# channel rollout (e.g. `qwen,anthropic,openai`) — the chart's
# NoAllowedChannels guard fails every mint if this resolves to
# empty.

View File

@ -179,6 +179,13 @@ spec:
# Companion to bp-catalyst-platform 1.4.225 which adds the
# secretKeyRef itself + the corrected CATALYST_NEWAPI_ADDR
# literal (`http://newapi-bp-newapi.newapi.svc.cluster.local:3000`).
# 1.4.39 — F1a (TBD-V45 follow-up #2115, 2026-05-20): renamed the
# qwenBankDhofar default channel row from `qwen3.6-bankdhofar` to
# `qwen` so the row matches the sandbox-controller default
# AllowedChannels=["qwen"] (envsubst SANDBOX_DEFAULT_CHANNELS:-qwen
# at slot 19a:197). Pre-fix the per-Sandbox token mint succeeded
# but /v1/chat/completions returned 404 `channel not found`.
#
# 1.4.37 — TBD-V45 (#2115, 2026-05-20): channel-seed Job now
# also seeds the in-cluster vLLM channel when
# `defaultChannels.vllm.enabled=true`. The seed gate is now
@ -186,7 +193,7 @@ spec:
# so a fresh Sovereign with vllm-only enabled (no Bank Dhofar
# commercial contract) still seeds a working Qwen channel.
# Lockstep with the platform/newapi/chart bump in the same PR.
version: 1.4.38
version: 1.4.39
sourceRef:
kind: HelmRepository
name: bp-newapi
@ -324,7 +331,15 @@ spec:
defaultChannels:
qwenBankDhofar:
enabled: ${MARKETPLACE_ENABLED:-false}
name: qwen3.6-bankdhofar
# F1a fix (2026-05-20, TBD-V45 follow-up #2115): row name MUST be
# `qwen` so it matches the sandbox-controller default
# AllowedChannels=["qwen"] (envsubst SANDBOX_DEFAULT_CHANNELS:-qwen
# at clusters/_template/bootstrap-kit/19a-bp-sandbox.yaml:197).
# Pre-fix: row name `qwen3.6-bankdhofar` → per-Sandbox token mint
# succeeded but /v1/chat/completions returned 404 `channel not
# found` because the channel-router only matches rows whose `name`
# is in the token's allowed_channels set.
name: qwen
endpoint: ${LLM_BANK_DHOFAR_BASE_URL:-https://llm-api.omtd.bankdhofar.com}
models:
- qwen3.6

View File

@ -6,7 +6,7 @@ metadata:
catalyst.openova.io/category: ai-runtime
catalyst.openova.io/section: pts-4-6-llm-serving
spec:
version: 1.4.38
version: 1.4.39
card:
title: NewAPI
summary: |

View File

@ -1,5 +1,27 @@
apiVersion: v2
name: bp-newapi
# 1.4.39 — F1a (TBD-V45 follow-up #2115, 2026-05-20): rename the
# qwenBankDhofar channel row's default `name` from `qwen3.6-bankdhofar`
# to `qwen` — the short customer-canonical name. NewAPI's channel-
# router matches a token's `allowed_channels` set against rows by their
# `name` field; the sandbox-controller mints per-Sandbox tokens with
# `allowed_channels = SANDBOX_DEFAULT_CHANNELS` (bootstrap-kit slot 19a
# defaults to `qwen`), so the pre-fix row name `qwen3.6-bankdhofar`
# meant the row never matched → /v1/chat/completions returned 404
# `channel not found` for every per-Sandbox call.
#
# Lockstep changes in same PR:
# - platform/newapi/chart/values.yaml defaultChannels.qwenBankDhofar.name
# - platform/newapi/chart/templates/_helpers.tpl (default in composed dict)
# - platform/newapi/chart/templates/channel-seed-job.yaml (audit-pointer
# ConfigMap dict default + `seed_channel` shell invocation default)
# - clusters/_template/bootstrap-kit/80-newapi.yaml (overlay row name)
# - products/catalyst/bootstrap/api/internal/handler/sme_tenant_gitops.go
# (generated tenant HelmRelease values)
# - products/catalyst/bootstrap/api/internal/handler/sme_tenant_test.go
# (test expectation lockstep)
# - platform/newapi/blueprint.yaml spec.version + bootstrap-kit pin
#
# 1.4.37 — TBD-V45 / #2115 (2026-05-20): channel-seed Job now also
# seeds the in-cluster vLLM channel when
# `defaultChannels.vllm.enabled=true`. Paired with bootstrap-kit slot
@ -373,7 +395,7 @@ name: bp-newapi
# `lookup valkey.valkey.svc.cluster.local: no such host`). Same hostname
# already documented as canonical in products/catalyst/chart/values.yaml
# bp-cnpg-pair comments.
version: 1.4.38
version: 1.4.39
appVersion: "0.13.2"
description: |
Catalyst Blueprint scratch chart for NewAPI — multi-tenant LLM

View File

@ -108,7 +108,7 @@ channel-seed-job.yaml operate on the same materialised list.
{{- fail "defaultChannels.qwenBankDhofar.enabled=true but defaultChannels.qwenBankDhofar.endpoint is empty — supply the upstream relay URL in the per-Sovereign bootstrap-kit overlay (canonical: https://llm-api.omtd.bankdhofar.com)" -}}
{{- end -}}
{{- $composed := dict
"name" (default "qwen3.6-bankdhofar" $qbd.name)
"name" (default "qwen" $qbd.name)
"type" "openai-compatible"
"endpoint" $qbd.endpoint
"models" (default (list "qwen3.6" "qwen3-coder") $qbd.models)

View File

@ -182,7 +182,7 @@ data:
{{- $list := list }}
{{- if $qbdReady }}
{{- $list = append $list (dict
"name" (default "qwen3.6-bankdhofar" $qbd.name)
"name" (default "qwen" $qbd.name)
"type" "openai-compatible"
"endpoint" $qbd.endpoint
"models" (default (list "qwen3.6" "qwen3-coder") $qbd.models)) }}
@ -429,7 +429,7 @@ spec:
# pointer; the seed Job translates that to NewAPI's
# registry value here.
seed_channel \
{{ (default "qwen3.6-bankdhofar" $qbd.name) | quote }} \
{{ (default "qwen" $qbd.name) | quote }} \
"openai" \
{{ $qbd.endpoint | quote }} \
{{ join "," (default (list "qwen3.6" "qwen3-coder") $qbd.models) | quote }} \

View File

@ -455,7 +455,16 @@ defaultChannels:
# Customer-visible channel name. Channel name is the human-readable
# row label in NewAPI's admin UI AND is the idempotency key for
# the seed Job's existence-probe (GET /api/channel/?keyword=<name>).
name: "qwen3.6-bankdhofar"
#
# F1a (2026-05-20, TBD-V45 follow-up #2115): default is `qwen` — the
# short customer-canonical name — so the row matches the sandbox-
# controller default AllowedChannels=["qwen"] (envsubst
# SANDBOX_DEFAULT_CHANNELS:-qwen at bootstrap-kit slot 19a:197). Pre-
# fix the default was `qwen3.6-bankdhofar`, which caused per-Sandbox
# /v1/chat/completions to return 404 `channel not found` (NewAPI's
# channel-router matches a token's allowed_channels against rows by
# `name`).
name: "qwen"
# Upstream OpenAI-compatible endpoint URL. The chart leaves this
# empty so an unconfigured deploy never silently dials a third-
# party host. Per-Sovereign overlay sets it to

View File

@ -62,13 +62,14 @@ env:
# because this defaulted to "".
#
# Default `qwen` per products/sandbox/docs/newapi-proxy-contract.md
# §2 — the only channel name surfaced today is the alias `qwen`
# backed by the `qwen3.6-bankdhofar` seed entry that bp-newapi's
# channel-seed-job.yaml writes on every Sovereign install. Operators
# MUST override on per-Sovereign overlays the moment they wire
# additional channels (e.g. `qwen,anthropic,openai`) — bootstrap-kit
# slot 19a substitutes `${SANDBOX_DEFAULT_CHANNELS:-qwen}` so the
# canonical knob lives on the Sovereign overlay's substitute map.
# §2 — the only channel name surfaced today is `qwen`, the customer-
# canonical row name bp-newapi's qwenBankDhofar default channel
# writes on every Sovereign install (F1a 2026-05-20 renamed the row
# from `qwen3.6-bankdhofar` to `qwen` so the row matches this
# default). Operators MUST override on per-Sovereign overlays the
# moment they wire additional channels (e.g. `qwen,anthropic,openai`)
# — bootstrap-kit slot 19a substitutes `${SANDBOX_DEFAULT_CHANNELS:-qwen}`
# so the canonical knob lives on the Sovereign overlay's substitute map.
newapiDefaultChannels: "qwen"
# runtime — Wave 8 per-Sandbox pty-server / MCP / NEWAPI wiring.
# Surfaced as env on the controller; the controller renders these into

View File

@ -1048,7 +1048,12 @@ spec:
defaultChannels:
qwenBankDhofar:
enabled: true
name: qwen3.6-bankdhofar
# F1a (TBD-V45 follow-up #2115): row name MUST be 'qwen' so the
# row matches sandbox-controller default AllowedChannels=["qwen"]
# (bootstrap-kit slot 19a's SANDBOX_DEFAULT_CHANNELS:-qwen).
# Pre-fix the row name was 'qwen3.6-bankdhofar', which produced
# 404 channel-not-found on /v1/chat/completions.
name: qwen
endpoint: https://llm-api.omtd.bankdhofar.com
models:
- qwen3.6

View File

@ -708,7 +708,7 @@ func TestRenderSMETenantOverlay_NewAPIEmitted(t *testing.T) {
wantChannel := []string{
" qwenBankDhofar:",
" enabled: true",
" name: qwen3.6-bankdhofar",
" name: qwen",
" endpoint: https://llm-api.omtd.bankdhofar.com",
" - qwen3.6",
" - qwen3-coder",