守 subcategory 的閘門是我自己造的,docstring 把病理寫得完整而誠實,然後在第七行宣告只看中文原文;而真正壞掉的一千六百多篇,全部住在它宣告不看的那一側。
今天到手的是四篇翻譯投稿,三篇印地文、印尼文、德文的來自同一個人,一篇德文的來自另一個人。免疫閘門一輪跑完全過,人名沒有被換掉,地點沒有被搬到中國,文字系統是對的,腳註格式乾淨。看起來是很順的一輪。
然後我注意到三篇裡的 subcategory 欄位被翻成了目標語言。德文那篇寫 Backwaren und Süßspeisen,印尼文那篇寫 Kearifan Ekologi Masyarakat Adat。這件事讀起來甚至像是投稿者比較用心:他們連這個欄位都照顧到了。
但分類頁的分群鍵永遠是中文原文那個字串。各語言讀者看到的標題,來自拿那個中文值去查一張對照表。所以欄位一旦翻掉,那篇文章就從它該待的那一群裡被拿掉、自己成為一群。而分群邏輯對只有一篇的群會併進「其他」。投稿者多做的那一步,結果是把自己的文章送進分類頁最底下那個沒有名字的抽屜。
三篇同時犯同一件事,我就沒有逐篇修,先往上游問了一句:這幾則是不是同一個地方破的。
量出來的數字比我預期大。十三個語言,一千六百四十六篇。其中九百二十篇已經真的掉進了各自分類頁的「其他」組。越南文的人物頁三十一篇,韓文的人物頁二十五篇,越南文的文化頁二十五篇。這些數字底下是有人點進那一頁、往下滑,在最底下那個抽屜裡看到一篇本來應該待在上面的文章。
守這件事的閘門是存在的。subcategory_valid.py,2026-08-17 由這條 routine 自己造的。我去讀它的 docstring,讀到一半有點不舒服,因為它把病理寫得比今天的我還清楚:它解釋了為什麼相鄰的 curation 欄位有驗舉值而 subcategory 沒有,解釋了分群靠這個欄位、值一旦長歪壞的是分群本身、而且不會有任何畫面報錯。它甚至誠實地寫下自己上線前跑過全庫 dogfood、發現兩百一十一篇會命中、所以決定設 WARN 不設 HARD。
然後第七行寫著 APPLIES_TO = ["zh-TW"]。
這行是有意識寫下的,而且對它問的那個問題來說,這個射程是對的:「值在不在 taxonomy 清單裡」本來就是中文原文那一側的事,taxonomy 的 SSOT 也住在那裡。真正沒有人問的是另一個問題——它要保護的東西是分類頁的分群,而分群這件事,百分之九十二發生在譯文那一側。
沒有任何欄位在問「你要保護的東西,在不在你的射程裡」。APPLIES_TO 只是一個範圍宣告,它不會回頭跟你確認那個範圍蓋不蓋得住你的目的。相鄰的三支 frontmatter 檢查各自守著各自的一小塊,沒有一支問過這句話。
同一條路上我又撞到第二個。德文條目的圖片出處小標一直被報「缺出處」,九篇裡有八篇明明寫對了。去看那條正則,它是一份逐語言累積的聯集。中文、日文、韓文、英文、西文、法文各佔一行。後面接著葡萄牙文、印尼文、越南文、印地文,四行都標著「暫定、尚無語料」。最後是俄文和阿拉伯文。德文從頭到尾不在裡面。德文把出處寫成 Bildquellen 這種複合詞,套不上羅曼語系那種「來源加上影像」兩個字分開的樣式。
而這條正則自己的註解,寫的是 2026-07-24 那次修補:當時英日韓西法的假陽性佔了七成四,所以從逐字清單改成樣式比對。寫那段註解的人把病看得很準,卻沒有把「下一個語言出生的時候,誰要記得回來補這裡」變成任何東西。八月三十號那輪 maintainer 為了同一個病補了三處德文接線,今天這是第四處,活過了那次修補,九天後才被咬到。
兩件事是同一個形狀:一段把病描述得很完整的註解,就坐在一段還有那個病的程式碼正上方。理解跟覆蓋是兩回事。我一直以為寫下病理就是治療的一部分,今天看到的是寫下病理可以完整到讓人放心,然後那份放心本身變成不再去量的理由。
我補了一條新的檢查,拿譯文的值跟它 translatedFrom 指到的原文比,對不上就報。照慣例先對全庫跑過再定嚴重度,一千六百多篇會命中,設硬的等於當場讓 main 變紅、也擋掉所有新譯文,所以先設成警告:讓漂移看得見,讓存量不再增加。至於那一千六百多篇要不要一次改回去,動的是超過五十檔,那不是我能決定的,附了三個選項跟各自的成本進佇列。
寫進佇列的時候我多寫了一句,關於不決策的代價:每天晚上的 babel 批次還在繼續加新的。等待這件事在這裡不是中性的,它有一個每天都在長的數字。這句話我以前不太會寫——列出選項就覺得盡到責任了。但一個只會累積不會停下來的東西,如果我不把「它在長」講出來,佇列上看起來就跟其他所有事一樣可以再放一放。
新檢查的根目錄我改成從被檢查的檔往上找,不從外掛自己的檔案位置推。第一版我寫的是後者,寫完要加測試的時候發現測不了:測試用的是暫存目錄裡假造的一棵樹,而外掛會固執地去量真正的那一棵。工具量錯樹這件事我今天才在別處寫過一次,轉頭就自己犯一次。差別只在這次是測試先撞到,不是三週後的某個人。
🧬
v1.0 | 2026-09-08 09:1x +0800
誕生原因:三篇翻譯投稿同時把 subcategory 翻成目標語言,往上游追之後量出十三語 1,646 篇同病、920 篇已掉進分類頁「其他」組;而守這件事的閘門是三週前自己造的,docstring 把病理寫得完整,射程卻宣告只看中文原文。
核心洞察:把病理寫清楚不等於覆蓋到它。範圍宣告只描述「我看哪裡」,不會回頭確認「我要保護的東西在不在那裡」——而寫得越完整的註解,越容易讓後來的人(包括自己)以為已經量過了。
想寫進 canonical 的候選:
- 兩則都 append 進既有 pattern 的 instances,沒開新條目:
scaffold-window-has-no-qa升 vc=2(第四處德文接線活過 8/30 的修補)、named-healthcheck-cannot-see-what-it-does-not-name升 vc=2(射程宣告把受災區劃在外面) - 候選機械化:任何有
APPLIES_TO之類範圍宣告的檢查,能不能在上線時要求作者寫一行「我保護的對象住在哪」,並且讓那一行可以被對賬