fix(#2601): include 'inherit' in VALID_PROFILES and unify allowlists#2614
fix(#2601): include 'inherit' in VALID_PROFILES and unify allowlists#2614ssmulders wants to merge 3 commits intogsd-build:mainfrom
Conversation
…lowlists The 'inherit' meta-profile (bypass MODEL_PROFILES, use session model) was accepted by the runtime getter and health validator but rejected by the setter — the only path users actually invoke to change profiles. Root cause: three independent allowlists had drifted out of sync. VALID_PROFILES was derived solely from MODEL_PROFILES keys, which cannot include 'inherit' since it intentionally bypasses that map. The health validator had its own hardcoded list that included 'inherit' but omitted 'adaptive'. Fix: - Append 'inherit' to VALID_PROFILES after deriving from MODEL_PROFILES - Replace hardcoded list in validate.ts with shared VALID_PROFILES import - Add regression test for inherit acceptance in configSetModelProfile Closes gsd-build#2601 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughAppends Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@sdk/src/query/validate.ts`:
- Around line 468-469: The current guard `parsed.model_profile &&
!VALID_PROFILES.includes(parsed.model_profile as string)` skips empty-string
values and thus bypasses W004; change the check to explicitly detect presence
(e.g., ensure `parsed.model_profile` is not null/undefined and treat empty
string as invalid) before validating against `VALID_PROFILES`, then call
`addIssue('warning','W004',...)` when the value is present but not in
`VALID_PROFILES`; reference `parsed.model_profile`, `VALID_PROFILES`, and the
`addIssue` invocation so you update that conditional to reject empty strings (or
use a trimmed length check) rather than relying on truthiness.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 0704e03f-dabd-43ed-9dde-541645dd14f9
📒 Files selected for processing (5)
CHANGELOG.mdsdk/src/query/config-mutation.test.tssdk/src/query/config-query.test.tssdk/src/query/config-query.tssdk/src/query/validate.ts
Address CodeRabbit review: the truthiness guard on parsed.model_profile skipped empty-string values, allowing "" to bypass W004 validation. Switch to explicit undefined check with trim/lowercase normalization. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
trek-e
left a comment
There was a problem hiding this comment.
Review — one semantic defect, otherwise the fix is sound.
Finding — getAgentToModelMapForProfile does not handle inherit:
sdk/src/query/config-query.ts:59-67
export function getAgentToModelMapForProfile(normalizedProfile: string): Record<string, string> {
const profile = VALID_PROFILES.includes(normalizedProfile) ? normalizedProfile : 'balanced';
const agentToModelMap: Record<string, string> = {};
for (const [agent, profileToModelMap] of Object.entries(MODEL_PROFILES)) {
const mapped = profileToModelMap[profile] ?? profileToModelMap.balanced;
agentToModelMap[agent] = mapped ?? 'sonnet';
}
return agentToModelMap;
}After this PR, VALID_PROFILES.includes('inherit') is true, so profile = 'inherit', then profileToModelMap['inherit'] is always undefined (MODEL_PROFILES never had an inherit column), so every lookup falls through to profileToModelMap.balanced. Callers of configSetModelProfile with inherit get back agentToModelMap populated as if the user chose balanced.
This contradicts inherit semantics as implemented by resolveModel (sdk/src/query/config-query.ts:186-188), which correctly special-cases inherit and returns {model: 'inherit'}.
Callsite that exposes the defect: sdk/src/query/config-mutation.ts:329 — configSetModelProfile returns agentToModelMap in its response. A user running gsd-sdk query config-set-model-profile inherit --raw sees profile: 'inherit' but agentToModelMap: {gsd-planner: 'opus', ...}, which is misleading and would produce wrong behavior if any caller trusts that map instead of re-checking the profile.
Required fix: either
(a) early-return an empty map (or {agent: 'inherit' for each agent}) from getAgentToModelMapForProfile when normalizedProfile === 'inherit', mirroring the resolveModel special-case; or
(b) have configSetModelProfile omit agentToModelMap from the response payload when the profile is inherit.
(a) is safer — keeps the function shape consistent and lets every caller handle inherit uniformly. Add a regression test asserting the returned map is empty / sentinel when inherit is passed.
Rest of the diff (the VALID_PROFILES consolidation in config-query.ts, the validate.ts replacement of the hardcoded list, the CHANGELOG entry, the existing new test) all look correct.
getAgentToModelMapForProfile silently fell through to balanced when called with 'inherit' — MODEL_PROFILES has no inherit column, so every lookup hit the ?? fallback. Now early-returns a map with 'inherit' for all agents, consistent with resolveModel's special-case. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix PR
Linked Issue
Fixes #2601
What was broken
gsd-sdk query config-set-model-profile inheritfailed with "Invalid profile 'inherit'. Valid profiles: quality, balanced, budget, adaptive" — despiteinheritbeing a supported meta-profile that the runtime getter and health validator both accept.What this fix does
Adds
'inherit'to the sharedVALID_PROFILESconstant and replaces the hardcoded allowlist invalidate.tswith that same constant, so all three consumers (setter, getter, health validator) agree on valid profiles.Root cause
Three independent allowlists had drifted out of sync:
inherit?adaptive?VALID_PROFILESconfig-query.ts:54validate.ts:468config-query.ts:171VALID_PROFILESwas derived fromObject.keys(MODEL_PROFILES['gsd-planner']), andinheritcannot be a key there since its purpose is to bypass the map entirely. The health validator had a separate hardcoded list that includedinheritbut omittedadaptive.Testing
How I verified the fix
npx vitest runon config-query, config-mutation, and validate test files — 82 tests pass'accepts inherit profile'inconfig-mutation.test.tscallsconfigSetModelProfile(['inherit'], ...)and verifies it writes toconfig.jsonsuccessfullyRegression test added?
Platforms tested
Runtimes tested
Checklist
Fixes #NNN— PR will be auto-closed if missingconfirmed-buglabelnpm test)Breaking changes
None
Summary by CodeRabbit
Bug Fixes
inheritmodel profile is now accepted during configuration updates and validated consistently across health checks.Tests
inheritis recognized as valid, returned by queries, and persisted correctly.Documentation