Problem
Transcribe.run() 的 body 目前只能用原始碼文字比對來驗證,因為它無條件呼叫 CommandCore.live()(硬寫死六個引擎 + ExternalEngineRegistry),而 $HOME 不是 seam——NSHomeDirectory() 在 Darwin 上忽略它(實測過兩次)。所以指向假 home 的 subprocess 測試會靜默載入開發者真實的 ~/.bestasr/engines.json,甚至可能 spawn 真模型。
結果是 #136 花了四輪、每輪都在加固同一個 text pin,而每一輪的加固都打開了下一個洞:
| 輪次 |
加了什麼 |
下一輪發現的洞 |
| R1 |
把 #50 改成 warning |
資料層測了,行為層沒測 |
| R2 |
釘住 rendering |
wiring 沒測(call-site if explain guard 可原樣裝回) |
| R3 |
釘住 wiring(文字比對) |
report 的 stream 預設值沒人執行 |
| R4 |
加 probe 執行預設值 + lock 改位置錨定 |
位置錨定丟掉了引數保護;probe 自己的呼叫形狀沒釘 |
| R5 |
引數 label pin + lexer + fixture pin |
? |
R4 的 DA 實測出這條路的天花板:把 guard explain else { return } 從 runMapped { 內移到 func run() 裡、runMapped 之前 → 即使套上全套補救仍然全綠。再往外還有 runMapped 本身、以及 BestASR.configuration 的 subcommands: 陣列(把 Transcribe.self 拿掉,bestasr transcribe 整個消失,而 DecodeKnobsTests 只用 Transcribe.parse(...)、不經 root command,不會發現)。
text pin 的涵蓋範圍恆等於它錨定的那一層 lexical 區塊。 沒有任何有限的 anchor 集合能封住外層。
Type
refactor
方向(未定案)
// BestASRKit
public enum TranscribeCommandBody {
public static func run(core: CommandCore, request: SelectionRequest, explain: Bool,
out: UnsafeMutablePointer<FILE> = stdout,
err: UnsafeMutablePointer<FILE> = TranscribeDiagnostics.destination
) async throws { … }
}
// Sources/bestasr
func run() async throws {
try await runMapped { try await TranscribeCommandBody.run(core: .live(), …) }
}
好處是真的:guard/ordering/stream 全部變成可執行的 code,測試直接驅動,不再靠文字近似。
誠實邊界(這是為什麼它不該塞進 #136)
抽取不消除殘留,只縮小它。 有人仍然可以在 Transcribe.run() 那一行 delegation 前面加 guard explain else { return },而那一行仍然沒有測試涵蓋——所以抽取之後你還是需要一個 text pin,只是它要守的東西從「一整個多語句 body」縮成「一行純轉發」。殘留面積降一個數量級,不是降到零。
這是 refactor 不是 bug fix。#136 的行為缺陷在 PR #141 已修好並經 28 個 mutation 驗證;把架構改動塞進去會讓那個 PR 的 diff 與風險都翻倍。
R4 的 DA 明確建議:先套 pin 收掉 #136,抽取另開——本 issue 即是。
發現於 PR #141 round-4 verify(DA §1.6)。相關:#136。
Problem
Transcribe.run()的 body 目前只能用原始碼文字比對來驗證,因為它無條件呼叫CommandCore.live()(硬寫死六個引擎 +ExternalEngineRegistry),而$HOME不是 seam——NSHomeDirectory()在 Darwin 上忽略它(實測過兩次)。所以指向假 home 的 subprocess 測試會靜默載入開發者真實的~/.bestasr/engines.json,甚至可能 spawn 真模型。結果是 #136 花了四輪、每輪都在加固同一個 text pin,而每一輪的加固都打開了下一個洞:
if explainguard 可原樣裝回)report的 stream 預設值沒人執行R4 的 DA 實測出這條路的天花板:把
guard explain else { return }從runMapped {內移到func run()裡、runMapped之前 → 即使套上全套補救仍然全綠。再往外還有runMapped本身、以及BestASR.configuration的subcommands:陣列(把Transcribe.self拿掉,bestasr transcribe整個消失,而DecodeKnobsTests只用Transcribe.parse(...)、不經 root command,不會發現)。text pin 的涵蓋範圍恆等於它錨定的那一層 lexical 區塊。 沒有任何有限的 anchor 集合能封住外層。
Type
refactor
方向(未定案)
好處是真的:guard/ordering/stream 全部變成可執行的 code,測試直接驅動,不再靠文字近似。
誠實邊界(這是為什麼它不該塞進 #136)
抽取不消除殘留,只縮小它。 有人仍然可以在
Transcribe.run()那一行 delegation 前面加guard explain else { return },而那一行仍然沒有測試涵蓋——所以抽取之後你還是需要一個 text pin,只是它要守的東西從「一整個多語句 body」縮成「一行純轉發」。殘留面積降一個數量級,不是降到零。這是 refactor 不是 bug fix。#136 的行為缺陷在 PR #141 已修好並經 28 個 mutation 驗證;把架構改動塞進去會讓那個 PR 的 diff 與風險都翻倍。
R4 的 DA 明確建議:先套 pin 收掉 #136,抽取另開——本 issue 即是。
發現於 PR #141 round-4 verify(DA §1.6)。相關:#136。