preferences: wire service_tier through validation

validatePreferences() is a strict allow-list — it copies only explicitly
handled fields from input to output. service_tier was in
KNOWN_PREFERENCE_KEYS (no unknown-key warning) but was never copied into
the validated output, so users setting service_tier: priority or flex in
PREFERENCES.md silently got undefined.

This was a latent bug from before today's work: the new "off" value hit
it first because I verified end-to-end, but priority/flex had the same
issue. /sf fast on writes "priority" via writeGlobalServiceTier —
correctly — and then the next read drops it on the floor.

Now: service_tier is validated against {priority, flex, off} and copied
through. Invalid values raise an error rather than being silently lost.

Verified: dr-repo's service_tier: "off" in .sf/PREFERENCES.md now loads
correctly via loadEffectiveSFPreferences().preferences.service_tier.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Mikael Hugo 2026-04-19 08:05:26 +02:00
parent 5957d5c2b6
commit 63e87e8e86

View file

@ -295,6 +295,20 @@ export function validatePreferences(preferences: SFPreferences): {
}
}
// ─── Service Tier ───────────────────────────────────────────────────
// OpenAI service tier for gpt-5.4 models. "off" explicitly disables the
// whole feature (hooks, footer, command refuse enable). Undefined = not
// configured. Historical gap: this field wasn't wired through validation
// so even "priority" / "flex" were being silently dropped.
if (preferences.service_tier !== undefined) {
const validTiers = new Set(["priority", "flex", "off"]);
if (typeof preferences.service_tier === "string" && validTiers.has(preferences.service_tier)) {
validated.service_tier = preferences.service_tier as SFPreferences["service_tier"];
} else {
errors.push(`service_tier must be one of: priority, flex, off`);
}
}
// ─── Search Provider ─────────────────────────────────────────────
if (preferences.search_provider !== undefined) {
const validSearchProviders = new Set(["brave", "tavily", "ollama", "combosearch", "native", "auto"]);