config/models.yaml is not read by the deployed service, and names two models that no longer exist #116
Closed
opened 2026-09-16 21:28:02 +00:00 by mathias
·
1 comment
No Branch/Tag Specified
main
fix/pipeline-writes-158
fix/edit-path-io-192
fix/create-regular-188
fix/guard-special-179
fix/linkcheck-keeps-write-178
fix/write-dir-redirect-173
fix/tunnel-detect-174
fix/pipeline-root-157
w3/154-mcp-auth-wiring
fix/tunnel-traversal
test/in-brain-targets-171
fix/brain-scan-root-157
fix/graph-wiki-root-157
fix/vectorstore-root-157
fix/notes-root-157
fix/search-root-157
fix/brainwide-root-157
fix/raw-symlinks-153
feat/symlink-tripwire-157
fix/rest-auth-149
fix/123-brain-edit-envelope-check
feat/106-page-aware-extraction
fix/105-source-drift-on-main
fix/104-surface-merge-conflicts-on-main
agent/b1-compile-on-ingest
agent/104-surface-merge-conflicts
agent/105-source-drift
agent/107-loud-unconfigured-alerting
feat/brain-read-edit
fix/capture-i1-refusal-names-target
renovate/configure
feat/consolidate-single-harness
icebox/cmd-routing
feat/brain-pending-promote
fix/close-session-classification-refresh
fix/capture-summarywriter
v0.24.0
v0.23.1
v0.23.0
v0.22.0
v0.21.1
v0.21.0
v0.20.1
v0.20.0
v0.19.1
v0.19.0
v0.18.4
v0.18.3
v0.18.2
v0.18.1
v0.18.0
v0.17.0
v0.16.1
v0.16.0
v0.15.0
v0.14.0
v0.13.2
v0.13.1
v0.13.0
v0.12.1
v0.12.0
v0.11.2
icebox/cmd-routing-2026-07-01
v0.11.1
v0.11.0
v0.10.0
v0.9.0
v0.8.0
v0.7.0
v0.6.0
v0.5.0
v0.4.1
v0.4.0
v0.3.0
v0.2.0
v0.1.0
Labels
Clear labels
agent/ready
blocked/client
blocked/supplier
blocked/upstream
risk/high
risk/low
risk/medium
size/l
size/m
size/s
size/xs
status:dispatch
status:dispatched
status:review
status:reviewing
type/chore
type/decision
type/docs
type/feat
type/fix
type/ops
type/research
type/test
Meets the agent-ready contract; authorizes unattended execution
Waiting on the client
Waiting on a supplier
Waiting on an upstream project or vendor
Irreversible, security-relevant, or control plane
Reversible, local, test-covered
Touches shared state, deploys or data
Too big - split it
Under two days
Under half a day
Under an hour
Maintenance, no behaviour change
Human decision required; never agent/ready
Documentation only
New capability
Corrects broken behaviour
Infrastructure, deploy, runtime
Investigate; output is a finding, not code
Test coverage only
Milestone
No items
No Milestone
Projects
Clear projects
No projects
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: mathias/hyperguild#116
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Found while retiring
iguana/qwen3-coder-nextestate-wide (infra#416) and sweeping every repo for references.config/models.yamldeclares:Two problems
1. The deployed service does not read this file. The live
ingestiondeployment in thesupervisornamespace names its models entirely by env:Not one name from
config/models.yamlappears. The file's own header says "first entry per skill is used" — nothing uses it. Editing it to change routing would change nothing, silently, which is worse than having no file: it reads as the place routing is configured.2. Two of the six models it names no longer exist, checked against
infrak3s/apps/ai-stack/litellm-config.yaml:iguana/qwen3-coder-nextkoala/qwen3-coder-30biguana/devstraliguana/deepseek-r1-14bkoala/phi4-14bkoala/qwen3-coder-30bwas already gone before today — infra'sllm-consumers.yamldocuments that exact name as the dead entry which broke agentsquad's LiteLLM grant. So thetddskill has pointed at a nonexistent model for some time, and the file being unread is the only reason nobody noticed.Why this is worth fixing rather than ignoring
This is the same defect class as three others found in the estate this week: a capability that exists, is correct-looking, and is connected to nothing (
resolve_label_idnever called,AGENTSQUAD_TIERSpointing at an unmounted path,agent/readylabels with no consumer). Each was invisible precisely because the artifact looked right.Options
A. Delete the file. If env is the real configuration surface, the file is a decoy. Cheapest and most honest.
B. Make it load-bearing. Have the service read it and fail on startup when a named model is absent from LiteLLM's
/v1/models. That turns the second problem into a boot-time error instead of a silent wrong answer.C. Keep it as documentation — but then it has to be accurate, and something has to keep it that way, which is how it got here.
A or B. C is what it already was.
If B, the check is cheap:
GET /v1/modelson the gateway and set-difference the chains. infra now has the analogous gate for its canary —tests/canary-tiers-vs-catalogue_test.sh— which asserts every probed model exists in the catalogue, after exactly this failure mode kept a 51 GB model resident for nothing.Created via git-mcp on behalf of @mathias
Resolved via Option A — PR #119 merged (squash).
Merge-gate evidence
The PR's case rested entirely on a negative claim ("nothing reads this file"), so I re-established it independently rather than re-running the author's grep.
Searches performed (all against
origin/main, i.e. pre-merge state):git grep -n -I -E 'models\.yaml|ModelsFile|SUPERVISOR_MODELS_FILE|LoadModels|ModelFor|ModelsConfig' origin/main— searches the committed tree, not the working dir, so a dirty or shared checkout cannot hide a reference.git ls-files | grep -v '^docs/'— catches every non-Go file type: shell, Taskfile, Procfile, Dockerfile, CI workflow, manifests.internal/config/scanned forreflect.,go:generate, andyaml:"/json:"struct tags.Configcarries no struct tags at all — so no YAML/JSON decoder could populateModelsFileby name. This is the failure mode a plain symbol grep misses.ModelFor,config.Models,Models{across all*.go. Zero hits outside the deleted files.ModelForwas a method on a concrete unexported-data struct satisfying no interface in the repo../go.modand./ingestion/go.mod, and nogo.work. Greppedingestion/separately: no references. (task checkgenuinely covers both —lint,testandveteach run once at root and once withcd ingestion. Verified by reading the Taskfile, not by trusting thedesc:string.)/home/mathias/dev/AI/infra), grepped forSUPERVISOR_MODELS_FILE|models\.yaml|MODELS_FILE: only two hits, both indocs/plans/prose describing this very issue. No ConfigMap, no env var, no volume mount.k3s/apps/supervisor/contains a Deployment foringestiononly — there is no supervisor Deployment to mount anything.ingestion/Dockerfile, andcd.ymlbuilds it with--local context=ingestion.config/is outside that build context, soconfig/models.yamlwas never baked into any deployed image. TheENV SUPERVISOR_MODELS_FILE=/app/config/models.yamlline indocs/superpowers/plans/2026-04-20-cd-pipeline.mdis a plan that was never implemented — a naive grep hit that reads alarming and is inert.Corroborating evidence for "superseded, not just unused":
internal/config/routing.goconfigures model selection entirely by env —HYPERGUILD_FAST_MODEL(defaultkoala/qwen35-9b-fast) andHYPERGUILD_THINKING_MODEL. That matches theINGEST_LLM_MODEL=koala/qwen35-9b-fastyou quoted from the live Deployment. The env surface is the real one; the YAML was the decoy, exactly as the issue argued.Gate
go build ./...— exit 0 (root) and exit 0 (ingestion)CI=1 task check— exit 0,grep -c FAIL= 0 (lint + test-race+ vet + govulncheck + gitleaks, both modules)pull_request, head_sha351b187, conclusion successCollateral damage check
Diff is
git diff --numstat0 additions / 131 deletions across all five files — a pure subtraction, so the line-filter edits to.env.exampleandconfig.gocould not have mangled anything. Confirmed anyway: the removed.env.exampleline was the last of its block, leaving the blank line and the# LiteLLM gatewayheading intact;config.gostill parses with the struct andLoad()intact.internal/config/config_test.gonever referencedModelsFile, so deletingmodels_test.goremoved coverage of the deleted code only.One finding the PR did not address (not a blocker)
Procfile:2still setsSUPERVISOR_MODELS_FILE=./config/models.yaml. I checked whether this is a live reference and it is not: that line's command isgo run ./cmd/supervisor/, andcmd/supervisorwas deleted inc117634("retire supervisor pod"). The line was already non-functional onmainbefore this PR, and setting an env var nothing reads breaks nothing. Pre-existing rot, not regression — filed separately along with the same class of staleness inTaskfile.ymlandscripts/smoke-routing.sh.Created via git-mcp on behalf of @mathias