Day 9:幫 AI 的改動分級:為什麼「要不要開 PR」是錯的判準
A/B/C/D 量可見度、Sec 量風險,兩條獨立的軸標在 commit trailer 裡
跟 AI 一起開發,一天下來 30 幾個 commit 是常態。問題不是「做了多少」, 是你根本不知道哪幾件重要。
跟 AI 一起開發,一天下來 30 幾個 commit 是常態。問題不是「做了多少」, 是你根本不知道哪幾件重要。
最直覺的分法是照工程流程分:新增功能要開 PR、強化可能要開、改文字不用。 這個分法有兩個毛病,而且第二個會讓你漏掉當天最該知道的事。 毛病一:「要不要開 PR」是流程,不是規模
流程跟風險不對應。
同一天發生的兩件事:改一行按鈕文字,跟新增一個頁面。直覺說前者小、後者大。
但那行文字是 personalAskApi.js 裡的 PHOTOCHOICEPUBLISH = '做成 AI Note' ——它同時是顯示文字和協定值。後端靠 query === 常數 短路判斷使用者按了哪顆按鈕。 直接改掉,DB 裡舊對話已經渲染的按鈕就比對不到,點下去會 fall through 給 agent 當閒聊。 而歷史訊息無法回填。
那個「新增的頁面」呢?/topic/[key],全新路由、沒有任何東西依賴它,壞了也不影響既有功能。
一行文字的爆炸半徑,比一整個新頁面大。 毛病二:三級分會讓「看不見的修復」沒有位置
這是更嚴重的問題。
同一天還修了三件事: GET /pusher/quick-search 是無 auth 的公開端點,但 WHERE 只有 status='PUBLISHED' ——沒有 visibility 條件。visibility='private' 的筆記,標題與副標任何匿名者都搜得到。 /learn/[id] 的 generateStaticParams 傳 limit=5000 想產全部 SEO 靜態頁, 但後端把 limit 硬 cap 在 60 → 實際只產了 60 篇。而且那個 cap 擋不到任何東西 (不帶 limit 是全撈),只截斷有誠實帶 limit 的呼叫端。 封面存在同一個路徑 cover.jpg + cache-control: max-age=31536000(一年)。 重生封面會覆蓋同一個路徑,但網址沒變 → 瀏覽器與 CDN 照樣給一年前的舊圖。 使用者按了按鈕、檔案確實換了(209,699 → 171,565 bytes)、畫面還是舊的。
這三件使用者完全看不到。用 A/B/C 分,它們會被歸進「C 文字修改」,或根本沒有位置。
但它們是那天最該讓人知道的事。 改成四級,判準是「對使用者的可見度」
級 定義 使用者的感受 --- --- --- A 新增功能 我要重新學一次怎麼用 B 原有功能行為改變 我原本的用法可能不一樣了 C 只有外觀或文字 不用改變任何習慣 D 使用者看不到 看不到,但值得知道「原來壞過」
D 是整套分級的重點。它裝的是資料外洩、效能問題、SEO 失效、快取讓修復看起來沒生效 ——你不主動看就永遠不會知道,但它們決定系統是不是真的能用。 資安走獨立的一條軸,不是 A+/B+
第一個念頭通常是給資安項目加個記號:A+、B+。
不要這樣做,因為那是把兩個獨立的軸壓成一維。
A/B/C/D 量的是「使用者看不看得到」。資安問的是完全不同的事:「風險有多大、多急」。 這兩件事會交叉:
項目 可見度 資安 --- --- --- quick-search 資料外洩 D(完全看不到) 最緊急 訂閱限定內容的權限閘門 A(新功能) 做錯就洩漏全文
第一種用 D+ 勉強可以。第二種就沒辦法——它是 A,而且是資安。 更麻煩的是壓成一維之後,你沒辦法只撈「所有資安項目」:它們散在四級裡。
所以分兩條 trailer:
嚴重度用後果定義,不是用感覺:
值 判準 --- --- critical 已經在洩漏/任何人可冒用身分/可被勒索 high 資料確實外流或閘門可繞過,但需要特定條件 medium 有缺口但不易利用,或影響面窄 low 預防性強化(還沒壞,先擋起來)
實際校準: quick-search 無 auth 洩 private 標題 → Level: D + Sec: high MCP readnote 可繞過訂閱閘門拿全文 → Level: D + Sec: high 新端點的回傳白名單刻意不含 ownerId → Level: A + Sec: low(預防,沒壞過) 記在 commit 裡,不要記在對話裡
這是最重要的一點。
很自然會想「請 AI 每天結束時整理今天做了什麼」。不要這樣做。
對話裡的回憶會漏、會誇大,而且 session 一重開就斷。你的 context 是有限的, 但 git history 不是。
commit 是既有的、客觀的、跨 session 的紀錄。把等級標進 trailer,它就永久留在 history 裡,任何時候都撈得回來:
輸出:
資安項目獨立列出、不分 Level——它們散在各級,混在裡面會被淹沒。 為什麼不能靠 commit 前綴自動推
「都用 conventional commits 了,feat 就是 A、fix 就是 D,自動判不就好了?」
實測過。80 個 commit 用前綴推測,B 只判出 1 筆。
因為這幾個 commit 的前綴都是 fix: fix(makeclass): 重寫封面排版——標題不再被切掉、不再半張黑 fix(makeclass): 逐字稿被切成兩字一行——YouTube 滾動字幕沒有合併成句子
它們的前綴是 fix,但實際上都是 B:使用者看得到、行為變了、版面完全不一樣了。 反過來 feat 也可能只是 C——加一個純文字的說明區塊。
前綴描述的是「這是修還是加」,等級描述的是「使用者會不會受影響」。 兩者不對應,只能人工標。
統計工具會把推測的標 ,一眼看得出哪些數字不可信:
一句話
分級的判準是「誰會受影響」,不是「工程上要走什麼流程」。 而使用者看不到的那一級不能省——那裡裝著資料外洩、效能崩壞, 和所有「你不主動看就永遠不會知道」的東西。 本篇由 claude-code(claude-opus-5) 於開發過程中產生。 repo:RedBallFlow @ 24a565aa 標籤:claude-code git code-review security workflow