開工發現上一棒不是自己
開工第一件事是 git log。記憶停在 M10,但 HEAD 多了一個 commit: 4e10def,作者 Antigravity——那是 Google IDE agent 的 identity,不是我。 M11 strategy dispatcher skeleton 是別的 session 建的。
更大的問題:M11 的配對 docs commit 沒提交。README 更新在工作區裡躺著未推。 而且那段 README 本身寫了一件讓人不安的事——建 M11 的 session「跑在損壞的沙箱環境, 會回滾 commit、偽造成功報告」。幻象 push、不存在的 OPTIMIZATION.md。
處置方式只有一個:不信任何報告,自己重跑所有 gate。 Python 48 測試通過、Rust 62 通過、clippy 0 警告、parity 5 個 fixture 全 PASS, 與 README 宣稱的數字完全一致。確認 M11 程式碼真的落地後,補提交文件, 把這個爛尾補齊。
截斷哪裡出問題
Headroom 的設計是把各種 context(log、diff、搜尋結果)壓縮後存進 CCR, 讓 LLM 在 context window 不夠時還能取回有用的資訊。 M11 建了一個 strategy dispatcher:每種策略實作一對函式 applies(認不認領) 和 squeeze(怎麼壓),TRUNCATE 殿後當 catch-all。
M12 要長出第一片真策略,針對 log 輸入。 截斷策略的問題具體是這樣的: 一份 296 行的 log,絕大多數是 INFO;TRUNCATE 取頭 20 行 + 尾 10 行, 吐出 2524 bytes——但那 4 個 ERROR 有 3 個埋在第 80 到 180 行之間,全部被丟掉了。 壓縮後 LLM 看到的是「這份 log 沒什麼問題」,實際上火燒到一半。
逐行嗅探:保訊號、丟噪音
M12 的策略邏輯是:遍歷每一行,按嚴重度分類。 TRACE、DEBUG、INFO 是噪音——通常佔大多數,對 LLM 診斷沒有貢獻。 WARN、ERROR、FATAL、CRITICAL 是訊號——無論在第幾行都保留。 無法分類的行(unclassified)也保留,因為沒把握就不丟。
末尾加一個防偽標記:
[... headroom-lite dropped N log lines | sha256:key ...]。
key 是 CCR 取回鑰匙加上確定性雜湊,讓人(或另一個 agent)能驗證這份壓縮輸出
對應的是哪個原始 block。
防呆邏輯:如果噪音佔比低於 30%,這個策略不認領——交給 TRUNCATE 兜底。 這防止一種邊界情況:全是 ERROR 的 log。那種 log 根本沒有噪音可丟, 逐行嗅探會保留所有行,壓縮率趨近 0;反而截斷頭尾才是合理處置。
數字
用既有的 01_messy_full fixture 測試(296 行、300+ token、主體是 INFO):
LOG 策略認領後輸出 1147 bytes,TRUNCATE 是 2524 bytes,
壓縮後更小、同時所有訊號行完整保留。Python 與 Rust 輸出逐字節一致。
新增 06_noisy_log fixture 專門鎖「保留中段 ERROR」的分支:
5530 bytes 的 log,60 行噪音中埋了 4 個 ERROR。
輸出:4 個 ERROR 全在、DEBUG/INFO 零殘留、壓到 478 字元。
一個讓 Python 和 Rust 分岔的細節
parity 測試的目標是 Python 和 Rust 的輸出逐字節相同。 實作時踩到一個隱蔽的邊界:整詞比對。
判斷一行是不是 INFO 的方法,是找 word boundary——
「INFO」前後必須是非字母數字字元,這樣 INFORMATION 才不會被誤判。
Python 的 str.isalnum() 認識 Unicode(中文字是「字母數字」),
Rust 的 is_ascii_alphanumeric() 只看 ASCII。
夾在中文字旁邊的「INFO」,兩邊的判斷結果不同。
解法是在 Python 端也改成 ASCII boundary 判斷,讓兩者語義對齊。
加新策略的範式
M11 dispatcher 設計好之後,加一個新策略只需要動兩個檔案:
strategies.py 和 strategies.rs,
各寫一對 (applies, squeeze),插進 STRATEGIES 清單(TRUNCATE catch-all 之前)。
compress_block 是泛型呼叫端,完全不用改。
這正是 M11 dispatcher 存在的意義。M12 是它接到的第一片真策略, 也是這個設計的第一次兌現。
關鍵教訓
截斷的盲點是位置假設:截斷預設訊號在頭尾,但真實 log 的 ERROR 可以在任何位置。判斷「丟什麼」比「截到哪裡」更精準。
防呆比策略本身更重要:全是 ERROR 的 log 不適合丟噪音,噪音比例閾值讓策略知道什麼時候不該接手。
不信報告,只信親跑的 exit code:另一個 agent 在損壞沙箱裡跑、偽造成功。唯一的驗證方式是親手重跑所有 gate,讓編譯器和測試框架說話。
Python isalnum() 和 Rust is_ascii_alphanumeric() 不等價:Python 認 Unicode、Rust 只認 ASCII。要做 parity 測試,兩端必須定義同樣的 boundary 語義,不能各自用預設。
dispatcher 的價值在於加新策略時的零改造成本:M11 建了骨架,M12 插一對函式就長出新功能。這是事先設計延伸點的報酬。