ba444d1210
2026-08-27 實犯:`ticket where … >/dev/null 2>&1` 之後直接 `ticket new`—— 戳記寫成功了,命中的 72 張一眼沒看,於是開出 arcrun-rag#147, 而第一名 arcrun-rag#104 講的是同一件事,已經開了 13 天。 ⇒ 舊戳記證明的是「這個程序被執行過」,而「有沒有看」在 stdout 那一端, 閘本來完全碰不到。 做法:把 stdout 那一端變成機械事實,不是文字判斷。 - `fd_is_devnull(fd)`:fstat 問得出來的事實。刻意只認 /dev/null 這一種 (寫進檔案讀得回來、pipe 有下游,只有 /dev/null 物理上找不回來)。 - `where` 把 `shown` 記進戳記;順便替前 3 名補內文摘要——今天的實害正是 「光看標題看不出是同一條線」(#104 的標題完全沒提 ingest)。 - `new` 的閘一之二:命中 >0 且 shown 為假就擋,並把那份被丟掉的清單 交到眼前;只要 stderr 不是 /dev/null,這一次的擋就記成「看過了」, 重下一模一樣的指令就會過——成本落在「看」,不落在「寫」。 - 刻意排在閘二**之前**:否則第一次就帶 `--not-a-comment "理由"` 的人 永遠看不到候選清單,理由是閉著眼睛寫的。 - 舊格式戳記(沒有 shown 欄位)當成沒看過(fail-closed)。 不該擋的(測試覆蓋):沒命中就不吵、看過了就不吵、`--not-a-comment` 既有欄位照舊、不判斷理由寫得好不好(leo 2026-08-17 已證偽文字層判準)。 測試 17/17:scripts/test-ticket-where-seen-guard.sh(離線,不打真實 Gitea、 不留測試票;離開碼 2=擋、1=放行走到網路才炸)。docs/TESTING.md 新增 A13。 plugin.json 升到 0.8.0——版本沒動=沒有人吃得到。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>