acb55a78ed
Per PM dispatch (4b75b0be, ef3dbc87): the 7c2d7c22 fix that adds the
SELECT COALESCE(model,'') + validateRegisteredModelForRuntime pre-flight on
the PATCH-runtime path is the right logic (closes #21, CR2 RC 11972 no
objection), but had two follow-ups to land before re-review:
(1) MECHANICAL SQLMOCK FIX: the new SELECT COALESCE query in workspace_crud.go
Update's runtime-PATCH branch is not programmed in 2 existing tests'
sqlmock setups:
- TestWorkspaceUpdate_RuntimeField (workspace_test.go:952)
- TestWorkspaceUpdate_RuntimeField_DBErrorReturnsServerError (workspace_test.go:991)
Both tests' mock setups now Expect the new SELECT COALESCE query and
return moonshot/kimi-k2.6 (registered for both claude-code and hermes in
the harness's provider registry per providers.yaml:919, so the
(newRuntime, currentModel) validation passes and the existing assertions
on the UPDATE result are unchanged). Test 1: 200 + needs_restart.
Test 2: 500 (the SELECT COALESCE succeeds; the UPDATE is what errors out
in the existing setup).
(2) 422-ALIGN: the new code returned 400 (StatusBadRequest) for an
unroutable (runtime, model) pair, but the create-boundary's
validateRegisteredModelForRuntime callers (secrets.go:942, 952 +
workspace_crud.go create) return 422 (StatusUnprocessableEntity). Both
reviewers flagged the 400 as inconsistent. Updated to 422 + matching
comment in the handler. The new reject-path test was renamed
TestUpdate_Runtime_UnroutableModel_Fails400 → Fails422 + assertion
updated to StatusUnprocessableEntity. 422 is the precise semantic:
"syntactically valid PATCH body, but the (runtime, model) pair is
unroutable per the registry SSOT."
VERIFICATION (all green on this commit):
- go test -count=1 -timeout 30s -run 'TestUpdate' ./internal/handlers/ — PASS
- go test -count=1 -timeout 30s -run 'TestUpdate_Runtime_|TestWorkspaceUpdate_RuntimeField' -v ./internal/handlers/ — 4/4 PASS
(TestUpdate_Runtime_RegisteredModelForRuntime_Passes, TestUpdate_Runtime_UnroutableModel_Fails422,
TestWorkspaceUpdate_RuntimeField, TestWorkspaceUpdate_RuntimeField_DBErrorReturnsServerError)
- gofmt -l clean
- go vet ./internal/handlers/ clean
CORE PATH UNCHANGED: the runtime-PATCH path still validates (newRuntime,
currentModel) via the SSOT, then updates runtime + sets needsRestart=true. The
migration flow (workspace_provision.go create) already uses the same SSOT.
A failed check is a preventive 422 — the user gets a clear pointer to the
registry-SSOT instead of wedging the agent at boot.
Closes the test-mock follow-up from CR2 RC 11972 + the 422-align ask from
the same review. #2926 ready for CR2 + Researcher re-review → 2-genuine.
Co-Authored-By: Claude <noreply@anthropic.com>