Day 04 講過 README 的功能說明沒跟上程式碼——那是「這個套件能做什麼」的文件漂移。今天要看另一種完全不同面向的漂移:README 頂端那排徽章,連到的 CI/覆蓋率服務,跟現在真正在跑的工具鏈已經是兩回事。
[]
(https://travis-ci.org/omnipay-taiwan/omnipay-ecpay)
[]
(https://scrutinizer-ci.com/g/omnipay-taiwan/omnipay-ecpay/code-structure)
[]
(https://scrutinizer-ci.com/g/omnipay-taiwan/omnipay-ecpay)
三個徽章分別連到 Travis CI 跟 Scrutinizer CI 這兩個第三方服務。但真正在跑的 pipeline 是 .github/workflows/tests.yml——GitHub Actions。這兩者完全脫鉤:Travis CI/Scrutinizer 上不會再有任何新的建置紀錄,README 上的徽章畫面,反映的是這個套件很早期(很可能是套件剛建立、還在用 Omnipay 官方骨架產生器預設模板的那個階段)留下的設定,之後專案切換到 GitHub Actions,卻沒有人回頭把 README 的徽章也一併換掉。
Day 04 講的漂移是「README 的內容沒跟上程式碼」——寫了什麼、沒寫什麼、寫錯了什麼。今天講的漂移是「README 引用的外部服務沒跟上實際工具鏈」——連結指向的東西還存在,但已經不是真正在運作的那一套。
兩者的共通點是「文件被放著不管,程式碼/基礎設施持續在動」;差異在於第一種漂移讀者只要花時間讀程式碼就能自己補回來,第二種漂移讀者幾乎沒有辦法自己發現——徽章看起來就是徽章,圖示顯示著(可能是快取住的舊狀態、也可能顯示不出來),不會有任何跡象告訴你「這其實已經是死的連結」,除非你真的點進去看。
❌ 讀者看到的畫面
[Build Status: 圖示顯示某種狀態] → 點進去是 Travis CI 上一個很久沒有新建置紀錄的頁面
[Coverage Status: 圖示顯示某種狀態] → 點進去是 Scrutinizer 上同樣停滯的頁面
讀者的合理猜測:這個套件的 CI/覆蓋率追蹤看起來還活著
✅ 讀者如果去看 .github/workflows/tests.yml
matrix: php ['7.1' ... '8.3']
run: composer install && vendor/bin/phpunit --testdox --no-coverage
讀者能看到的事實:CI 其實活著,只是換了地方,且覆蓋率追蹤目前完全沒有在跑
徽章這種視覺元素的問題在於,它給人「這裡有在維護」的第一印象,卻可能連到一個早就沒人在看的地方——這比一段過時的文字說明更容易誤導人,因為讀者通常不會逐一去點開每個徽章驗證它是不是真的還活著。
這個系列的主題句是「AI 能幫你補程式碼,但補不出你自己都沒發現的測試缺口」。徽章脫鉤剛好示範了同一個道理放大到「品質防線的可見度」上——如果連維護者自己都不會回頭檢查徽章連到哪裡,會有更多沒被意識到的落差藏在看起來沒問題的地方。這也是為什麼這個系列從第一天開始就強調「先核實再下結論」:不是套件寫得不好,是很多這類細節,一旦沒有人主動回頭檢查,就會一直維持著看起來沒事、實際上已經脫節的狀態。
你維護的專案 README 上有沒有類似的徽章、連結、或引用的第三方服務?下次有空的時候,花五分鐘把每一個都點開來看看,它們現在還連得到真正活著的東西嗎?
明天換一個角度:這個套件沒有 PHPStan、沒有 Psalm,型別相關的錯誤目前完全沒有靜態分析工具把關,那到底是靠什麼在擋?順便看一個更嚴重的發現——依賴鏈裡累積的已知安全性風險。