驗收一次過,不代表「完成」有定義;有時候只代表有一個人,早就知道客戶會點哪裡、皺哪種眉頭。
昨天說到,介面可以靠兩個人的交情撐著。今天來看一個更常被腦補的東西:怎樣算做完。案例一樣經過去識別化與合併改寫。
某個專案,功能全部開發完畢,看板上的 Ticket 一張張移進 Done。距離交付驗收還有一週,理論上是收尾喘息的時間。
資深工程師卻在這一週把主要功能拉出來,「再修一輪」。沒有人指派,Ticket 上也沒有這些項目:
報表的空值原本顯示 null
→ 改成「-」
金額的四捨五入位數不一致
→ 全部統一到小數第二位
匯出的檔名是系統預設的流水號
→ 改成客戶內部慣用的命名格式
有一頁查詢比較慢,畫面會空白幾秒
→ 加上 loading,免得被當成當機
年輕的工程師在旁邊看,忍不住問:這些需求裡都沒寫,為什麼要改?
他頭也沒抬:「驗收的時候會被點出來。」
驗收當天,客戶的操作路徑跟他預測的幾乎一模一樣:打開報表、掃過空值的欄位、拿手邊的報表對了幾個數字、按下匯出、打開檔案看了一眼檔名。一次過。
慶功的時候,PM 舉杯說:
「這次需求寫得不錯,驗收才這麼順。」
資深工程師笑笑沒說話。需求文件跟上一個案子一樣薄。順的原因不在文件裡,在他腦裡。
當時團隊的認知大概是:功能都做完了,Ticket 都關了,剩下的是「打磨」;驗收本來就會有些小地方要修,讓資深的人把關本來就合理;驗收條件很難事先寫,客戶自己也講不清楚,寫了也會變;而且結果證明一切——驗收一次過,還有什麼好挑的?
照例,每一句單獨看都有道理。合在一起,剛好繞開一件事:
整個團隊裡,除了他,沒有人知道「怎樣算好」。
大家說的「做完」,意思是「工程師覺得功能會動」。而真正決定驗收生死的「怎樣算好」——空值長什麼樣、位數幾位、檔名什麼格式、等多久要給回饋——這些判準從頭到尾沒有被寫在任何地方。
它們存在。只是存在一個人的直覺裡。
今天缺席的 Artifact 叫 Acceptance Criteria(驗收條件,以下簡稱 AC)。先講清楚它不是什麼:它不是一種文件格式,不是驗收前補交的表單。它是一個問題的答案:
這個東西交出去之前,誰、用什麼動作、看到什麼結果,會判定它通過?
這個問題瀑布要答,敏捷也要答。Day 02 講過瀑布邏輯鏈的最後一環:拿 Baseline 加上 Change 的總和來驗收——驗收依據在承諾成立的時候就該存在,而不是驗收當天才揭曉。敏捷則是把它切小,貼在每一個 Story 上,讓每一輪的「完成」都有可以檢查的判準。形式不同,底線相同:
「完成」的定義必須在動工之前存在於人腦之外。
沒有 AC 的時候,「完成」不會消失,它會分裂。同一個功能,至少同時存在三個版本的完成:
工程師的「完成」
→ 程式跑起來,沒有報錯
PM 的「完成」
→ 看板上的 Ticket 都移進了 Done
客戶的「完成」
→ 空值、位數、檔名、等待回饋,全部符合他每天的工作習慣
三個版本平常相安無事,因為沒有人把它們放在一起對過。它們終究會對齊——在驗收那天,用最貴的方式。
這個團隊沒有付到那筆錢。因為有人提前一週,自己一個人把三個版本對完了。
那一輪「再修一輪」,看起來像直覺,其實是查詢——查一個只存在他腦中的資料庫:
客戶驗收那天會點哪裡
→ 歷次驗收他都在場,操作路徑他看過太多次
哪種畫面會讓客戶皺眉頭
→ 空值、位數、檔名,每一項都是以前被點過的
驗收的人真正在意什麼
→ 他知道這份報表會被拿去跟財務對帳,數字對不上,其他做再好都沒用
哪些角落可以不用修
→ 他也知道客戶從來不會點進去的頁面在哪
看清楚最後一條。他不只知道「怎樣算好」,還知道「哪裡可以不用好」。這是一份非常精確的 Acceptance Criteria,精確到連 Non-goal 都有。
所以 AC 從來沒有缺席。每一次驗收它都在,寫得又準又完整——只是儲存位置是一個人的腦,讀取權限只有他自己,執行時間是驗收前一週。
於是每驗收一次過,組織就再確認一次:「你看,驗收條件不用寫。」其實是:驗收條件每次都有人寫,而且每次都是同一個人,在交付前一週,一個人默默預演了整場驗收。
最諷刺的是慶功那句「這次需求寫得不錯」。文件跟上次一樣薄。變的不是需求,是他這次剛好沒有被借調去救別的案子。
老規矩。Scope 一項沒少、時程如期、沒有加人,驗收一次過,品質看起來好極了。那「客戶怎樣算滿意」這個不確定性,是誰吸收掉的?
Scope □ 一項都沒少交
Time □ 如期驗收
Cost □ 沒有追加任何資源
Quality □ 看起來很好——因為有人先把標準整個跑過一遍
Risk □ 沒有人評估過「他那週剛好不在」會發生什麼
人 ■ ← 交付前一週那一輪,是他一個人的驗收預演
注意這次連 Quality 都沒被勾到。這正是第二部最危險的地方:大神把代價吸收得太乾淨,帳面上六格有五格是白的,任何指標都看不出這個專案的驗收其實靠通靈。
看不見的代價不是不存在。它只是掛在帳上,等他不在場的那一次驗收,一次付清。
答案不是把驗收文件寫厚,也不是背什麼標準句型。是在動工之前,把他腦中那份清單問出來、寫下來。
問法很樸素。想像驗收那一天:
操作的人是誰?他從哪個畫面開始?他會做什麼動作?他預期看到什麼——具體到可以指著螢幕說「就是這個」?出現什麼狀況,他會當場判定不通過?
這五個問題,客戶答得出來最好;客戶答不出來,團隊就一起猜,把猜的版本拿去跟客戶確認——這比驗收當天才發現猜錯便宜太多了。
AC 不是文件格式,是把「怎樣算好」從個人直覺變成團隊共識。寫的過程本身就在逼所有人動工前對齊:我們說的「完成」,到底是哪一個版本?
把上面五問收成今天的 Artifact。一個功能一份,五行,寫得出來比寫得標準重要——不必套用任何術語句型:
□ 操作者:驗收當天真正動手的人是____
□ 前提:在____的狀態下(資料、權限、環境)
□ 動作:他會做____
□ 可觀察結果:他應該看到____(畫面、數值、檔案,指得出來的那種)
□ 邊界與失敗:當____時,系統應該____,否則不通過
五行填不出來,不是 AC 太難,是你還不知道怎樣算完成。那麼現在正在動工的,到底是什麼?
沒有 Acceptance Criteria 的驗收不是驗收,是通靈;一次過的原因不是標準清楚,是通靈的人剛好在場。
完成的標準藏在他腦裡,被我們挖出來了。但再往前一層還有一個問題:這個系統當初為什麼這樣設計?哪一段看起來很怪的程式碼,其實不能動?
明天來看另一個藏在人腦裡的東西——沒有 Architecture Decision Record 也沒關係,反正,原作者還在。