fix(workspace_provision): preserve MODEL secret over MODEL_PROVIDER slug on restart #136

Merged
claude-ceo-assistant merged 1 commits from fix/preserve-model-secret-on-restart into main 2026-05-08 21:31:52 +00:00

Phase 4 follow-up to template-claude-code PR #9 (2026-05-08 dev-tree wedge).

Problem

applyRuntimeModelEnv unconditionally overwrote envVars["MODEL"] with the MODEL_PROVIDER slug whenever payload.Model was empty (the restart path). This silently wiped the operator's explicit per-persona MODEL secret on every restart.

Symptom: dev-tree workspaces booted correctly on first /org/import (the envVars map was populated direct from the persona env file with both MODEL=MiniMax-M2.7-highspeed and MODEL_PROVIDER=minimax), then on the next Restart the MODEL secret got clobbered to literal "minimax" — a provider slug, not a valid model id — and the workspace template's adapter failed to match any registry prefix, fell through to providers[0] (anthropic-oauth), and wedged at SDK initialize.

Fix

Resolution order in applyRuntimeModelEnv is now:

  1. payload.Model — caller passed the canvas-picked model id verbatim.
  2. envVars["MODEL"] — workspace_secret persisted from persona env (/org/import).
  3. envVars["MODEL_PROVIDER"] — legacy canvas Save+Restart shape.

Tests

  • New TestApplyRuntimeModelEnv_PersonaEnvMODELSecretPreserved — four cases locking in the precedence.
  • Existing TestApplyRuntimeModelEnv_SetsUniversalMODELForAllRuntimes continues to pass.
Phase 4 follow-up to [template-claude-code PR #9](https://git.moleculesai.app/molecule-ai/molecule-ai-workspace-template-claude-code/pulls/9) (2026-05-08 dev-tree wedge). ## Problem `applyRuntimeModelEnv` unconditionally overwrote `envVars["MODEL"]` with the `MODEL_PROVIDER` slug whenever `payload.Model` was empty (the restart path). This silently wiped the operator's explicit per-persona `MODEL` secret on every restart. Symptom: dev-tree workspaces booted correctly on first `/org/import` (the `envVars` map was populated direct from the persona env file with both `MODEL=MiniMax-M2.7-highspeed` and `MODEL_PROVIDER=minimax`), then on the next `Restart` the `MODEL` secret got clobbered to literal `"minimax"` — a provider slug, not a valid model id — and the workspace template's adapter failed to match any registry prefix, fell through to `providers[0]` (`anthropic-oauth`), and wedged at SDK initialize. ## Fix Resolution order in `applyRuntimeModelEnv` is now: 1. `payload.Model` — caller passed the canvas-picked model id verbatim. 2. `envVars["MODEL"]` — workspace_secret persisted from persona env (`/org/import`). 3. `envVars["MODEL_PROVIDER"]` — legacy canvas `Save+Restart` shape. ## Tests * New `TestApplyRuntimeModelEnv_PersonaEnvMODELSecretPreserved` — four cases locking in the precedence. * Existing `TestApplyRuntimeModelEnv_SetsUniversalMODELForAllRuntimes` continues to pass.
claude-ceo-assistant added 1 commit 2026-05-08 21:31:43 +00:00
fix(workspace_provision): preserve MODEL secret over MODEL_PROVIDER slug on restart
Some checks failed
CodeQL / Analyze (${{ matrix.language }}) (go) (pull_request) Successful in 4s
CodeQL / Analyze (${{ matrix.language }}) (python) (pull_request) Successful in 5s
CodeQL / Analyze (${{ matrix.language }}) (javascript-typescript) (pull_request) Successful in 5s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 12s
Check merge_group trigger on required workflows / Required workflows have merge_group trigger (pull_request) Successful in 13s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 26s
cascade-list-drift-gate / check (pull_request) Successful in 30s
CI / Detect changes (pull_request) Successful in 35s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 32s
Harness Replays / detect-changes (pull_request) Successful in 34s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 36s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 40s
branch-protection drift check / Branch protection drift (pull_request) Successful in 42s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 38s
E2E API Smoke Test / detect-changes (pull_request) Successful in 42s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 37s
Harness Replays / Harness Replays (pull_request) Failing after 40s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 1m46s
CI / Python Lint & Test (pull_request) Successful in 1m10s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 1m7s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 1m39s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 7m39s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 7m51s
CI / Canvas (Next.js) (pull_request) Successful in 9m16s
CI / Canvas Deploy Reminder (pull_request) Has been skipped
CI / Platform (Go) (pull_request) Successful in 10m17s
15c5f32491
Phase 4 follow-up to template-claude-code PR #9 (2026-05-08 dev-tree wedge).

Pre-fix: applyRuntimeModelEnv unconditionally overwrote envVars["MODEL"]
with the MODEL_PROVIDER slug whenever payload.Model was empty (the restart
path). This silently wiped the operator'\''s explicit per-persona MODEL
secret on every restart.

Symptom: dev-tree workspaces booted correctly on first /org/import (the
envVars map was populated direct from the persona env file with both
MODEL=MiniMax-M2.7-highspeed and MODEL_PROVIDER=minimax), then on the
next Restart the MODEL secret got clobbered to literal "minimax" — a
provider slug, not a valid model id — and the workspace template'\''s
adapter failed to match any registry prefix, fell through to providers[0]
(anthropic-oauth), and wedged at SDK initialize.

Fix: resolution order in applyRuntimeModelEnv is now:
  1. payload.Model (caller passed the canvas-picked model id verbatim)
  2. envVars["MODEL"] (workspace_secret persisted from persona env)
  3. envVars["MODEL_PROVIDER"] (legacy canvas Save+Restart shape)

Tests
-----
TestApplyRuntimeModelEnv_PersonaEnvMODELSecretPreserved — locks in
the new resolution order with four cases:
  - MODEL secret wins over MODEL_PROVIDER slug (persona-env shape)
  - MODEL secret wins even when same as MODEL_PROVIDER
  - MODEL absent → fall back to MODEL_PROVIDER (legacy shape)
  - Both absent → no MODEL set (no-op)

Existing TestApplyRuntimeModelEnv_SetsUniversalMODELForAllRuntimes
continues to pass — fix is strictly additive on the precedence chain.
claude-ceo-assistant merged commit 6f861926bd into main 2026-05-08 21:31:52 +00:00
Sign in to join this conversation.
No reviewers
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: molecule-ai/molecule-core#136
No description provided.