Component
internal/config/instance.go(MergeInstance,f07c77cb 后)+ desktop/wailskit/config.go(saveWithInstanceWriteback,未修)——#368 家族第 5 缺口,#731 修复的残留子场景
Bug
#731 的 per-key 登记修复只覆盖「instance 采纳了 ≥1 个 vendor 键」的情形。instance 已 attach 但无 vendors 段 (或 vendors 完全被 global 覆盖)时:
无键被采纳 → instanceFields["vendors"] 不设(instance.go:139-144)
运行时 AddCustomEndpoint("C") / SaveAPIKey → saveWithInstanceWriteback(wailskit config.go:395-403,f07c77cb 未触及):
cfg.Save() → globalOnlyVendors(config_save.go:159-170)按 globalSnap 过滤 → C 被丢弃
门条件 InstanceFields() 不含 "vendors" → SaveInstanceScoped 不调用
C 只存在内存 → 重启丢失。与 [business-logic] config: partial-overlap vendor workspaces skip instance writeback — AddCustomEndpoint/SaveAPIKey silently lost on restart (4th #368-class gap) #731 同症状,但触发面更广 :instance.yaml 通常只为 language/mode 等存在,无 vendors 段。
边界:globalSnap.Vendors == nil(global 完全无 vendors)时不过滤,C 正常写全局。丢写仅当 global 有 ≥1 vendor + instance attached + 标志未设 。
触发序列(独立复核验证)
vendors.yaml={a}; workspace instance.yaml={language: go}(无 vendors 段)
加载: 无键采纳 → 标志不设
操作: AddCustomEndpoint("C") → Save() 过滤丢 C + 门关 → 双重丢弃
重启: C 丢失(静默,无任何错误)
预期 vs 实际
预期:会话新增 vendor 落入 instance 持久层,重启可见。
实际:内存态静默丢弃。
修复自带的测试锁死了 bug 状态(修复时需同步更新)
zz_issue731_test.go 的 "both nil" 用例断言 wantFlag=false(instance 无 vendors 时标志不设)——这正是门关的条件。修复本 bug 需反转该断言或改用其他门语义。
修复建议(两选一,推荐 b)
(a) MergeInstance:instance 无 vendors 但 global 有 ≥1 vendor 时也设标志——但会让所有此类工作区每次 SaveInstanceScoped,副作用大
(b) 门改为「runtime 新增的 vendor 不在 globalSnap」判定 :saveWithInstanceWriteback 不再依赖 InstanceFields() 标志,直接检查 vendor ∉ globalSnap.Vendors(或提供 cfg.VendorNotInSnapshot(vendor) helper)→ SaveInstanceScoped + SyncVendorToGlobalSnapshot。统一覆盖全部 5 个家族缺口(含本个),标志仅用于序列化语义
严重程度
high — 静默数据丢失;触发面比 #731 更广(任何无 vendors 段的 instance 工作区 + global 有任意 vendor 即命中)
独立复核
sa-21 五环验证:per-key 登记(139-144)/门未变(395-403)/过滤与 nil 边界(58-59,159-170)/diffVendors 含 C(213-219,唯一阻断点是门)/测试缺口(both-nil 反向断言)。完整触发序列与边界对比均实证。
Component
internal/config/instance.go(MergeInstance,f07c77cb 后)+desktop/wailskit/config.go(saveWithInstanceWriteback,未修)——#368 家族第 5 缺口,#731 修复的残留子场景Bug
#731 的 per-key 登记修复只覆盖「instance 采纳了 ≥1 个 vendor 键」的情形。instance 已 attach 但无 vendors 段(或 vendors 完全被 global 覆盖)时:
instanceFields["vendors"]不设(instance.go:139-144)AddCustomEndpoint("C")/SaveAPIKey→saveWithInstanceWriteback(wailskit config.go:395-403,f07c77cb 未触及):cfg.Save()→globalOnlyVendors(config_save.go:159-170)按 globalSnap 过滤 → C 被丢弃边界:globalSnap.Vendors == nil(global 完全无 vendors)时不过滤,C 正常写全局。丢写仅当 global 有 ≥1 vendor + instance attached + 标志未设。
触发序列(独立复核验证)
预期 vs 实际
修复自带的测试锁死了 bug 状态(修复时需同步更新)
zz_issue731_test.go 的 "both nil" 用例断言
wantFlag=false(instance 无 vendors 时标志不设)——这正是门关的条件。修复本 bug 需反转该断言或改用其他门语义。修复建议(两选一,推荐 b)
vendor ∉ globalSnap.Vendors(或提供 cfg.VendorNotInSnapshot(vendor) helper)→ SaveInstanceScoped + SyncVendorToGlobalSnapshot。统一覆盖全部 5 个家族缺口(含本个),标志仅用于序列化语义严重程度
high — 静默数据丢失;触发面比 #731 更广(任何无 vendors 段的 instance 工作区 + global 有任意 vendor 即命中)
独立复核
sa-21 五环验证:per-key 登记(139-144)/门未变(395-403)/过滤与 nil 边界(58-59,159-170)/diffVendors 含 C(213-219,唯一阻断点是门)/测试缺口(both-nil 反向断言)。完整触发序列与边界对比均实证。