把「送出前檢查一次」寫成檢查器:我盤點8條自檢規則,只有3條該自動化
直接回答
「送出前檢查一次」這類自檢規則,只有可機器判定的才值得寫成檢查器,判斷型的硬做會變成假保險。我實際盤點自己的8條自檢規則,只有3條(格式、字串、數量)能被腳本驗證,另外5條是判斷(這句話踩在哪個事實上、有沒有跑過三個螢幕尺寸、有沒有附回報格式),寫成腳本之後會永遠回報通過,比沒有檢查更糟,因為它會讓人以為驗過了。
同一個標點格式錯誤,我被指正三次。前兩次的處理都是把規則寫得更清楚。
第三次我終於承認:靠記得去掃這條路,已經實測失敗三次了。
—
為什麼「寫得更詳細」是最差的解法
反覆失效的規則有三種修法,優先順序是這樣:
第一,改結構,讓那個錯誤根本無從發生。 第二,改不動結構的話,在錯誤發生的當下用hook攔截。 第三,把規則寫得更詳細。
第三名通常沒用,而且它正是「反覆失效」的成因不是解法。因為一條規則要被套用,前提是每次都要主動想起來有這條規則。規則寫得再詳細,也不會改變「要先想起來」這個前提。
hook不一樣。hook是在錯誤發生時攔住它,不需要我想起來。
—
盤點結果:8條裡只有3條該自動化
動手之前我把所有寫著「送出前掃一次」「交件前逐條檢查」的規則全部抓出來,一共8條。
可機器判定的3條: 不用某些符號、貼文格式的字數與段落數、對外文案的標點與空格規則。
不可機器判定的5條: 這句話踩在哪個事實上、網頁要跑過三個螢幕尺寸、派工時有沒有附回報格式、引用規則前要標清楚適用範圍、動手前要先比對確認。
第二堆全部是判斷,不是字串。
自檢規則自動化的判準:寫成腳本之後如果它永遠會回報通過,那它比沒有更糟,因為它會讓人以為驗過了。8條實測只有3條可機器判定。
我沒有硬把那5條寫成腳本。寫了會得到一個永遠回報通過的東西,然後它會讓人以為驗過了。
這是整個盤點最重要的產出:知道哪些不該做,比知道哪些該做更省事。
—
硬擋還是警告,看有沒有正當例外
3條可自動化的裡面,有2條原本就已經掛了hook,是硬擋型的:訊息裡出現某些符號就直接讓動作執行不了。
第3條不能這樣做。
全形標點這條規則只適用於「代寫給別人看的文案」,日常對話用半形完全正常。如果照樣硬擋,會天天誤擋自己的正常訊息。
所以判準是:想得出一個合理的正當使用情境,就不准硬擋。
hook硬擋與警告的判準:零例外的硬規則用硬擋讓動作執行不了;有正當使用情境的只能警告。警告型必須設觸發門檻,並用自己的正常訊息做誤報測試。
警告型的門檻我設成「半形標點出現3處以上,或三類違規中同時中2類」。理由是聊天時偶爾漏一個半形逗號不該吵,整篇文案用錯才該叫。
測試我跑了4個案例。前三個是違規文案、修正後文案、hook模式餵違規文案。第四個才是關鍵:餵一則我自己平常會寫的普通訊息進去,看它會不會叫。
它沒叫。這個案例比前三個都重要,因為一個會亂叫的警告器,一週內就會被關掉。
—
我被自己寫的hook擋下來
做到一半我發現既有的攔截腳本有個洞:註解寫著會擋三種破折號,程式碼裡實際只有兩種。
然後我要把這件事說出來,就必須把那個漏掉的符號打出來。訊息一送出,被自己的hook擋下,發不出去。
繞法是改用編碼寫法描述那個符號。
但這揭露了一個真實的設計缺口:這類攔截型hook沒有「討論這個符號」的逃生口。要根治得加白名單,可是白名單本身又是一個可以被繞過的洞。
順帶也證明了一件事,那條hook是活的,不是裝飾品。
還有一個教訓:那個註解宣稱的範圍跟程式碼實際的範圍不一致,而且被它取代的舊版本反而擋得比較完整。改寫腳本時要逐條對舊版的判準,不要只讀註解。
—
判準只能有一份
檢查器和hook共用同一套判準,我把它做成一支檔案兩個模式,用參數切換。
後來寫第三支評分腳本時,直接引用這支檔案的判準函式,一樣沒有複製第二份出來。改判準的時候只有一個地方要改。
規則本身也跟著瘦身。原本751字的規則,把可機器判定的部分換成一行「交件前必跑檢查器」,剩下503字。原文沒有丟,逐字搬到觸發時才讀的全文檔,留下判斷型的部分繼續當文字規則。
自檢規則值不值得自動化,看的不是它重不重要,是它會不會失敗。永遠通過的檢查是零資訊,而寫得更詳細的規則,只是把同一個「要先想起來」的問題再說一次。