本卡屬 FR-092(母卡 CM-1703),第 8 棒盤點。只盤不修。
前幾棒都把 scripts/ 和 test/ 當「引用來源」,沒反過來看它們自己有沒有死掉。scripts/ 在 CM-1236(2026-08-16)盤過一次、有 archive 政策與 README 索引,所以這棒只補「8/16 之後新增的腳本」;test/ 從沒盤過,172 支測試檔裡可能有測著早已刪掉或退役功能的(用大量 mock 撐著所以還綠)、與已刪 fixture 對不上的、或 @skip 掛了半年的。
死測試比死程式更陰:它綠著,讓人以為那個功能有保護;實際上功能沒了它還在測 mock。FR-069 收整棒 B 把 94 紅歸零時是修不是刪,可能留下一批「修綠的死測試」。
pytest.mark.skip/xfail 且理由寫「等 X」而 X 早已發生的;④ 整檔只 assert mock 被呼叫、沒 assert 任何業務結果的;⑤ test/fixtures/、test/cloud_integration/ 下沒被任何測試引用的檔。git log --since=2026-08-16 --name-only -- scripts/ | sort -u 列新增檔,每支查呼叫端(skill、docs、其他腳本、CI、Makefile);零呼叫端且非 README 列為現役的,比照 CM-1236 政策建議搬 archive/。scripts/sql/、scripts/build/、notion_case.py 不動區照舊。scripts/archive/ 內已存 5 支,CM-1236 政策是「只搬不刪、刪由 user 決定」——本棒列出它們的最後 commit 日期,給決策者裁要不要真刪。scripts/ 上次盤點:scripts/README.md(CM-1236,2026-08-16),分類原則與不動區寫在檔頭。test/ 上次大動:FR-069 收整 B 棒 CM-1505(94 紅 23 error → 0,產品碼零異動)與 A 棒退役 tests/ 整合套件 25,015 行。CM-1510 記帳「test_audit 併跑汙染」未處理。
第一步(test/):
# 每支測試檔 import 的專案模組
for f in test/*.py; do grep -hoE '^(from|import) (api|app|domain|infra|common|core|config|di_containers)[\w.]*' "$f" | sed "s|^|$f\t|"; done > imports.tsv
# skip / xfail
grep -rn 'mark.skip\|mark.xfail\|pytest.skip' test/ | grep -v __pycache__
# 只有 mock 斷言的檔(粗篩:assert_called 多、assert == 少)
for f in test/*.py; do echo "$f $(grep -c 'assert_called\|assert_any_call' $f) $(grep -c 'assert .*==' $f)"; done | awk '$2>0 && $3==0'
第二步(scripts/):8/16 後新增檔逐支 grep -rn "<檔名>" .claude docs scripts Makefile .gitlab-ci.yml 2>/dev/null。
第三步:每條候選開檔看,判定寫理由。
scan-dead-tests-scripts.md:test/ 部分表格=檔案/測的模組/該模組現況(活/第 N 棒刪/已退役)/判定(活/隨第 N 棒刪/獨立可刪/疑似);scripts/ 部分比照 CM-1236 README 格式。test/ 的「隨第 N 棒刪」清單要回寫到 CM-1704~1706 各卡 append 一段,讓那三棒的 runner 直接拿。