Skip to content

measurement store 的降級是靜默的:warnings 無生產讀取者 + publishedKeys 用 try?,掉 row 會把舊值升為現值(follow-up from #130) #131

Description

@kiki830621

Problem

#118decode_deterministic 從封閉的 Bool? 換成 String-backed enum——wire domain 因此
從封閉變成開放(任意字串),而 decoding 仍是嚴格的。後果:

未來新增第 4 個 enum 值,對任何仍在讀同一份 store 的舊 client 是 breaking change,而且它
會靜默失敗。

為什麼是靜默的(#130 verify 的 DA-1,五個 leg 中只有 DA 抓到)

兩個消費端都把「大聲的 throw」轉成「安靜的 drop」:

路徑 行為
BenchmarkStore.load() 逐行 do/catch,壞 row → warnings.append("skipped malformed row")
SubmissionPackager.publishedKeys try?完全無聲

而關鍵在於:BenchmarkStore.Snapshot.warnings 有零個非測試讀取者
grep -rc warnings Sources/bestasr/ 在整個 CLI target 零命中;每個 load() 呼叫端都丟棄它
loadRecords() 直接串到 .projectedRecords()bench submit 只用 .measurements /
.machines)。唯一的讀者是 BenchmarkStoreTests 的四個斷言,註解還寫著 // still loud

所以「loud degradation」目前只存在於單元測試裡。使用者兩條路徑都看不到任何東西。

而且掉一筆 row 不會留下空缺(DA-2)

latestMeasurements 是 append-only 檔案上的 latest-wins。實測:231 個 key 裡有 30 個有
supersession 歷史
(其中一個有 18 筆)。掉掉最新那筆的效果是靜默把已被取代的舊值升為現值
——對 #118 這種「未來新值會寫在最新 row 上」的變更,這是最壞的形狀。

Type

bug

Expected

至少其一:

  1. identity-only decode struct(DA 判為正解,約 8 行):publishedKeys 只需要
    modelId|corpusId|machineId|measuredAt 就能算 dedupe key,不需要解出整個 MeasurementRow
    用一個只含這四個欄位的 Decodable struct 讀,未知的 provenance 值就不會讓整筆 row 消失。
  2. Snapshot.warnings 至少有一個生產讀取者(CLI 印出來),讓降級真的可見。
  3. 若要保留嚴格 decoding,明文記錄「加 enum 值 = breaking change,需要 migration」。cluster: decode_deterministic 三值 enum + honest gate 抽 helper + CLI 值域 (#118, #120) #130 已在
    DecodeDeterminism 的 doc comment 留下這個警告,但那只是文件、不是機制。

Impact

Sources/BestASRKit/Contribution/Sharing.swiftpublishedKeys)、
Sources/BestASRKit/Store/BenchmarkStore.swift(warnings 的可見性)、
Sources/bestasr/(若要印 warning)。

為什麼是 follow-up 而非 #130 的 in-scope fix

DA 的 scope 判準:「這個 PR 可以修它自己寫的文字、它自己弄假的文字、以及它自己建立的檔案裡的
測試——不修它只是讓人看見的東西。」

try? 與 warnings-無人讀 都是先前既有的缺陷(四張表都受影響),#130 只是讓它們更容易被
觸及。但 DA 也指出這個框架只對一半:publishedKeys 註解所記載的前提
(「CI-valid ⟹ locally decodable」)是#130 弄成假的——所以 #130 有責任在文件層標註,
機制層的修復則屬本 issue。

Source: surfaced during /idd-verify PR #130 — Devil's Advocate DA-1 + DA-2(五個 verify
leg 中唯一發現 warnings 無讀者的一個)。

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions