文件行号
internal/config/config_vendor.go L452-455(构造全新 EndpointConfig{Protocol, BaseURL})+ L477(vc.Endpoints[endpointName] = ep 整体替换)对照 L434-435 注释承诺 "If the endpoint already exists it is updated"——既有 Models/DefaultModel/SelectedModel/ContextWindow/MaxTokens/DisplayName/AuthType/ModelLimits/APIKey(struct config.go:79-99)全部清零;config_keys.go L92-94(os.Setenv(envVarName, apiKey) + vc.APIKey = "${"+envVarName+"}" 只设进程 env 不写 keys.env)对照 SetEndpointAPIKey L55-59 有 writeKeysEnv + #1435 在 AddVendor L526/AddEndpoint L467 补的硬失败持久化;config_vendor.go L494/L544(delete 后直接返回不清理活动选择)+ commands_slash_admin.go:1250-1258(删后仅 saveConfig)+ webui server_handlers.go:367/:251 同样裸删
问题
案 A(Med-Low·数据丢失):AddEndpoint "更新"实为摧毁性替换
- 调用链穷尽:config_access.go:888(
config set vendors.X.endpoints.Y——L874 提示语即 "create/update")、commands_slash_admin.go:1216、provider_panel.go:1156、webui server_handlers.go:294、onboard.go:37——最痛路径:用户只想改 base_url 传 {"base_url":"..."} → 替换后 API key ref、已发现模型列表全丢且 SaveScoped 持久化;Y 为活动端点时 SelectedModel+DefaultModel 双清 → ResolveEndpointSelection(L39-46)报 "has no active model";apiKey 空跳过(L459)无法区分"不改 key"与"清 key"
修:存在即合并(仅更新非零字段)或 apiKey 空时保留既有。
案 B(Low-Med·#1435 漏修同类):SetVendorAPIKey 不写 keys.env——重启后 key 蒸发
案 C(Low·状态不一致):RemoveEndpoint/RemoveVendor 不清理悬空活动选择
- 删活动端点 → c.Endpoint 悬空 → ResolveActiveEndpoint 报 "endpoint not configured"(L31-36,无 fallback 分支)→ NeedsOnboard 视任何 resolve 错误为需重引导(onboard.go:44-46)→ 每次启动弹 onboarding 直到手动改选
修:删除时若是活动项则回退首个可用端点/vendor。
干净项
config_exposed:4 薄委托+A2ASecretEnvVar 拼接无注入面全对。config_plugin:注册去重/三态/patchConfigFile saveScope 感知+#1160 损坏中止在位全对。config_save:原子写/锁序/#1160 双处中止在位/#610/#284 三维守卫在位/双迁移/#1422-B2/#959 gateway 全对(仅注释瑕疵不报)。config_vendor:#1435 双处持久化在位/#1512 tombstone 在位(L350-362)/Upsert 清除 L289 在位/#1300 OAuth 分支在位。
排除
#1515 config 族(a2a_override/anthropic_bootstrap/api_keys/config.go);#1479-#1516 各案;#1422-B2/#959/#1160/#610/#284/#1300 已修项验在位。
严重程度
Med-Low + Low-Med + Low
独立复核确认:替换语义与注释矛盾+struct 字段清单+5 调用链穷尽、SetVendorAPIKey 2 生产调用方纠正(config_access.go:761 路由+webui:228)+重启蒸发推演、悬空→onboarding 循环链(无 fallback 分支验证)。
文件行号
internal/config/config_vendor.goL452-455(构造全新EndpointConfig{Protocol, BaseURL})+ L477(vc.Endpoints[endpointName] = ep整体替换)对照 L434-435 注释承诺 "If the endpoint already exists it is updated"——既有 Models/DefaultModel/SelectedModel/ContextWindow/MaxTokens/DisplayName/AuthType/ModelLimits/APIKey(struct config.go:79-99)全部清零;config_keys.go L92-94(os.Setenv(envVarName, apiKey)+vc.APIKey = "${"+envVarName+"}"只设进程 env 不写 keys.env)对照 SetEndpointAPIKey L55-59 有 writeKeysEnv + #1435 在 AddVendor L526/AddEndpoint L467 补的硬失败持久化;config_vendor.go L494/L544(delete 后直接返回不清理活动选择)+ commands_slash_admin.go:1250-1258(删后仅 saveConfig)+ webui server_handlers.go:367/:251 同样裸删问题
案 A(Med-Low·数据丢失):AddEndpoint "更新"实为摧毁性替换
config set vendors.X.endpoints.Y——L874 提示语即 "create/update")、commands_slash_admin.go:1216、provider_panel.go:1156、webui server_handlers.go:294、onboard.go:37——最痛路径:用户只想改 base_url 传 {"base_url":"..."} → 替换后 API key ref、已发现模型列表全丢且 SaveScoped 持久化;Y 为活动端点时 SelectedModel+DefaultModel 双清 → ResolveEndpointSelection(L39-46)报 "has no active model";apiKey 空跳过(L459)无法区分"不改 key"与"清 key"修:存在即合并(仅更新非零字段)或 apiKey 空时保留既有。
案 B(Low-Med·#1435 漏修同类):SetVendorAPIKey 不写 keys.env——重启后 key 蒸发
config set vendors.X.api_key路由,探测通过后提交)+ webui server_handlers.go:228——当场可用(进程 env)→ 重启 LookupEnv 落空 → NeedsOnboard→hasUsableAPIKey false → 重新 onboard 循环([code-review] onboard: custom-provider API key never persisted to keys.env (AddVendor only os.Setenv + ${VAR} reference, Save migrates plaintext only) - next-day fresh terminal fails NeedsOnboard and the wizard loops forever; syscall.Exec EWINDOWS stub makes first-run fail on Windows; mcp install sanitize strips --config past the -- separator; knight misconfig fatal to main CLI #1435 注释描述的 "onboarding loops on fresh terminals" 复现路径,AddVendor/AddEndpoint 修了此处漏)修:补 writeKeysEnv 硬失败持久化(对齐 SetEndpointAPIKey)。
案 C(Low·状态不一致):RemoveEndpoint/RemoveVendor 不清理悬空活动选择
修:删除时若是活动项则回退首个可用端点/vendor。
干净项
config_exposed:4 薄委托+A2ASecretEnvVar 拼接无注入面全对。config_plugin:注册去重/三态/patchConfigFile saveScope 感知+#1160 损坏中止在位全对。config_save:原子写/锁序/#1160 双处中止在位/#610/#284 三维守卫在位/双迁移/#1422-B2/#959 gateway 全对(仅注释瑕疵不报)。config_vendor:#1435 双处持久化在位/#1512 tombstone 在位(L350-362)/Upsert 清除 L289 在位/#1300 OAuth 分支在位。
排除
#1515 config 族(a2a_override/anthropic_bootstrap/api_keys/config.go);#1479-#1516 各案;#1422-B2/#959/#1160/#610/#284/#1300 已修项验在位。
严重程度
Med-Low + Low-Med + Low
独立复核确认:替换语义与注释矛盾+struct 字段清单+5 调用链穷尽、SetVendorAPIKey 2 生产调用方纠正(config_access.go:761 路由+webui:228)+重启蒸发推演、悬空→onboarding 循环链(无 fallback 分支验证)。