戳記要證明「看過」,不是「跑過」(inkstone/ISEP#72) #79

Merged
claude-code merged 1 commits from fix/stamp-proves-seen-not-run into main 2026-08-27 13:24:28 +00:00
Member

【身份】subagent/inkstone/ISEP/fix/stamp-proves-seen-not-run

closes inkstone/ISEP#72

這個 PR 修的那一格

ticket where … >/dev/null 之後 ticket new —— 戳記寫成功了,命中的 72 張一眼沒看。
戳記證明的是「這個程序被執行過」,不是「這個人看過結果」。

判準是 fstat 問得出來的事實(fd 1 是不是 /dev/null),不是對理由文字的判斷。
擋下來的訊息本身就是那份被丟掉的輸出——看完重下一模一樣的指令就會過,不必多打一個字。

實測

bash scripts/test-ticket-where-seen-guard.sh17/17(離線,不打真實 Gitea、不留測試票)
另有打真實 Gitea 的重演:where >/dev/nullnew --not-a-comment "…" → 擋下(rc=2),
訊息第二名點名 inkstone/arcrun-rag#104 並附上票頭摘要(leo 那句「這些庫都早就萃好了」)。

回歸:bash scripts/test-ticket-api-bypass-guard.sh → 24/24 照舊。

升版

plugin.json 0.7.0 → 0.8.0check-version-consistency.sh 現在故意是紅的——
它在等 v0.8.0 這顆 tag,不是本次漏了什麼。

【身份】subagent/inkstone/ISEP/fix/stamp-proves-seen-not-run closes inkstone/ISEP#72 ## 這個 PR 修的那一格 `ticket where … >/dev/null` 之後 `ticket new` —— 戳記寫成功了,命中的 72 張一眼沒看。 **戳記證明的是「這個程序被執行過」,不是「這個人看過結果」。** 判準是 `fstat` 問得出來的事實(fd 1 是不是 `/dev/null`),不是對理由文字的判斷。 擋下來的訊息**本身就是那份被丟掉的輸出**——看完重下一模一樣的指令就會過,不必多打一個字。 ## 實測 `bash scripts/test-ticket-where-seen-guard.sh` → **17/17**(離線,不打真實 Gitea、不留測試票) 另有打真實 Gitea 的重演:`where >/dev/null` → `new --not-a-comment "…"` → 擋下(rc=2), 訊息第二名點名 `inkstone/arcrun-rag#104` 並附上票頭摘要(leo 那句「這些庫都早就萃好了」)。 回歸:`bash scripts/test-ticket-api-bypass-guard.sh` → 24/24 照舊。 ## 升版 `plugin.json` 0.7.0 → **0.8.0**。`check-version-consistency.sh` 現在故意是紅的—— 它在等 `v0.8.0` 這顆 tag,不是本次漏了什麼。
claude-code added 1 commit 2026-08-27 13:18:13 +00:00
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>
claude-code merged commit a001b10947 into main 2026-08-27 13:24:28 +00:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: inkstone/ISEP#79