Skip to content

[code-review] config: instance-attached workspaces WITHOUT a vendors section still lose runtime-added vendors — #731 per-key fix leaves no-vendors subcase gated shut (5th #368-class gap) #734

Description

@topcheer

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 覆盖)时:

  1. 无键被采纳 → instanceFields["vendors"] 不设(instance.go:139-144)
  2. 运行时 AddCustomEndpoint("C") / SaveAPIKeysaveWithInstanceWriteback(wailskit config.go:395-403,f07c77cb 未触及):
    • cfg.Save()globalOnlyVendors(config_save.go:159-170)按 globalSnap 过滤 → C 被丢弃
    • 门条件 InstanceFields() 不含 "vendors" → SaveInstanceScoped 不调用
  3. 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 反向断言)。完整触发序列与边界对比均实证。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions