模組三|腳本與確定性驗證器(Day 12–16)
前三天講怎麼驗一份稿子。今天講一個更基礎的問題:
一個每一輪都從零開始的流程,怎麼知道自己做到哪裡了?
答案是一份 36 行的 markdown。
這條產線的核心迴圈是這樣跑的:
讀狀態 → 做一件事 → 驗證 → 更新狀態 → 結束
而每一輪都是冷啟動:新的 context、沒有上一輪的記憶。它知道的一切,只有那份狀態檔裡寫的。
這件事在 AI 流程裡不是選項,是物理限制。而它造成的結果是:那份狀態檔的品質,就是這個流程的智商上限。
## 本集
集數目錄、錄製日期、單人/多人、風格、本集主軸
## 題目表
播出# | 段 | 題目 | 來源 id | 狀態
(來源 id 對回素材庫,狀態例如「9 段結構完成」)
## 敘事弧
這一集的情緒與資訊密度怎麼走
## 驗證
驗證指令與結果:PASS、事實列數、位元組數
+ grader 評分(例:4 項中 3 項 PASS,1 項 WARN 已修)
## 編輯線定案(勿再推翻)
← 這一節是人工鎖
## 人工閘門
本輪還沒跨的那幾道
## 待決問題
軟閘門的落地處
七節,36 行。

第五節的標題就寫著:編輯線定案(勿再推翻)。
它的作用是人工鎖。
流程可以改任何東西:重寫段落、換順序、調字數。除了這一節底下列的。
為什麼需要這個?因為冷啟動的流程沒有記憶,它不知道某個決定是「還沒想清楚」還是「已經拍板」。如果沒有這一節,它會很合理地重新評估,然後把我上一輪花時間定下來的東西改掉。
冷啟動流程最大的風險不是它做錯,是它把做對的東西重做一次。
而這個鎖是一個 markdown 標題。它沒有任何強制力,靠的是流程願意讀它、也願意遵守。這件事的脆弱性,Day 30 會講。
「編輯線定案」那一節裡,有兩句話反覆出現:
威脅講死、個案別講死。
對意圖最壞打算、對人只認證據。
這兩句比我寫過的任何一份規格都精確。
第一句是 Day 8 那個「分層」的口語版:一個結構性的威脅有多方證據,可以講死;但某個具體個案是不是這個威脅的例子,證據不足,不能講死。
第二句處理的是「動機」:你可以在評論裡對某個行為的意圖做最壞的推測(那是評論),但對具體的人的指控必須有證據(那是事實)。
這兩句話為什麼比規格好用?因為它們短到可以在寫稿的當下想起來。
一份六條門檻的規格,我要打開來讀;「威脅講死、個案別講死」我唸得出來。
規則的長度決定了它會不會在需要的那一刻被想起來。
最後一節是軟閘門的落地處。某一集長這樣:
- 某項調查數字:缺機構與年份,播出前回扣
- 某國際事件的日期與損害:以通訊社後續為準
- 三個預算數字:已標「大概」+高可信來源,播出前再確認
- 某指控類題目:冠媒體出處,指控非定讞
- 某敏感人物題:守嚴肅線、尊重當事人稱謂、勿獵奇
五條,每一條都是「不知道」,不是「不要講」。
這個區分是 Day 3 那句 escalate, don't decide 的實際樣子。流程沒有被要求判斷「這個該不該講」,它被要求把不確定的東西列出來,交給人。
而這五條後來確實有被處理。Day 14 講的那個 grader 抓到的 blocker,就是這五條裡的第一條沒被處理乾淨:列在待決清單裡,但稿子裡已經把它寫成了確定的事實。
列出來不等於處理了。 待決清單防的是遺忘,防不了「列了但還是寫死」。

現在講這份檔案最有意思的問題。
狀態檔的「驗證」那一節寫著:
PASS,7 個事實列,46.9 KB
我拿同一支腳本、對同一個目錄實際跑了一次:
PASS,12 個事實列,63,980 bytes
兩邊都是 PASS。而數字完全不一樣。
事實列從 7 變 12、檔案從 46.9 KB 變 62 KB:稿子在寫下那筆記錄之後,又被改了不少,而狀態檔停在舊的數字。
更有意思的是:我在另一個 repo 的狀態檔上做同樣的比對,同樣的落差也存在(記錄 11 列 / 40,477 bytes,實跑 16 列 / 47,915 bytes)。
兩個 repo,同一個病。
這代表它不是一次疏忽,是這個設計的必然結果。
因為驗證器驗的是產物,不是帳本。
它讀那份 HTML,回答「這份 HTML 合不合格」。它完全不知道有一份狀態檔宣稱自己驗過它,那份狀態檔在它的視野之外。
於是流程變成:
跑驗證 → PASS → 手動把數字抄進狀態檔 → 之後又改了稿子 → 沒有重抄
而下一輪冷啟動的流程讀到那份狀態檔,會相信那個數字。
帳本可以無聲地過期,而 exit code 永遠是 0。
這是這整個系列裡我最喜歡的一句話,因為它精準地描述了一種不會被任何檢查抓到的失效:沒有錯誤、沒有警告、沒有紅字。只是那份記錄不再對應現實,而所有人(包括流程本身)繼續相信它。
我還沒修,但方向很清楚,而且不難:
讓驗證器自己寫狀態檔。
不要人抄。腳本跑完之後,把退出碼、事實列數、位元組數直接寫進狀態檔的那一節。這樣就不可能過期,因為記錄跟驗證是同一個動作。
這個修法可以推廣:任何「跑一個檢查、然後把結果記下來」的流程,那個「記下來」都應該是檢查自己做的。 只要中間有一個手動步驟,帳本就會漂。
36 行不夠。
它記得住「這一集做到哪」,記不住「上一集學到什麼」。每一集的狀態檔都是新的,而跨集的經驗(例如 Day 21 那個多軌漂移的陷阱)是寫在剪輯記錄裡的,流程讀不到。
這條產線有短期記憶,沒有長期記憶。
第二個代價:這份狀態檔本身沒有任何驗證。
那支 bash 驗口播稿,沒有東西驗狀態檔。它可以缺欄位、可以自相矛盾、可以停在三週前,沒有任何機制會發現。
而它是整個流程的記憶。最重要的那份檔案,是唯一沒有被檢查的。
冷啟動流程的智商上限,等於它的狀態檔品質。
如果你在做任何一種「每輪重新開始」的自動化(agent loop、排程任務、重試機制),那份狀態檔就是它的全部記憶。它值得被當成程式碼對待——有結構、有驗證、有版控。
而我的狀態檔三者只有一個。
第二條,可以馬上抄的:
「跑檢查」跟「記錄檢查結果」必須是同一個動作。
只要中間有一個手動的抄寫步驟,帳本就會漂——而且漂了不會有任何徵兆。讓檢查自己寫記錄,這是幾行程式碼的事,卻消滅了一整類無聲的失效。
第三條:給冷啟動流程一個明確的「已定案」區,並且讓它的措辭夠強硬。
「編輯線定案(勿再推翻)」這幾個字,防的是流程把你昨天想清楚的事情重新想一遍。冷啟動的東西最大的浪費不是做錯,是重做。
明天把驗證器的盲區一次列完——七組跨文件落差,包括今天這個帳本問題在內,一組都沒有被抓到。