From 0bafdf141f6d2352099d9caa3493b8c6f5605bc4 Mon Sep 17 00:00:00 2001 From: richblack Date: Thu, 20 Aug 2026 22:34:10 +0800 Subject: [PATCH] =?UTF-8?q?WIP=EF=BC=88=E6=9C=AA=E5=AF=A6=E6=B8=AC?= =?UTF-8?q?=EF=BC=8C=E4=B8=8D=E8=A6=81=E4=BD=B5=EF=BC=89=EF=BC=9A=E5=BE=85?= =?UTF-8?q?=E9=A9=97=E5=96=AE=20dedup=20=E2=80=94=E2=80=94=20=E6=94=B9=20h?= =?UTF-8?q?ash=20=E5=AE=A3=E7=A8=B1=E5=85=A7=E5=AE=B9=E6=9C=AC=E8=BA=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 問題:檔名 hash 用 (transcript_path + session_id + agent_id) ⇒ 每個新 agent 拿到新檔名、但抽出的宣稱是同一批 ⇒ 2026-08-20 同兩條宣稱產了 6 張單,總管每回合重做一次已驗完的事。 改法:hash 宣稱內容本身 + 跳過 verified-claims/ 裡已存在的同 hash。 🔴 未實測:造不出會觸發抽取邏輯的測資,dedup 是否生效沒驗到。 失敗形式是『該產單時不產單』=驗證機制靜默停擺(fail-open) ⇒ 沒驗過不准併。明天先解決測資問題。 Refs inkstone/InkStoneCo#48 --- hooks/subagent-claim-worksheet.sh | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/hooks/subagent-claim-worksheet.sh b/hooks/subagent-claim-worksheet.sh index 0984d25..2f0c758 100755 --- a/hooks/subagent-claim-worksheet.sh +++ b/hooks/subagent-claim-worksheet.sh @@ -118,10 +118,24 @@ if not ok_hits and not ng_hits: print("SKIP:no-claims"); raise SystemExit sid = (d.get("session_id") or "nosid")[:8] -aid = (d.get("agent_id") or d.get("subagent_id") or "")[:10] -stamp = hashlib.sha1((tp + sid + aid).encode()).hexdigest()[:8] + +# 2026-08-20 修:檔名原本 hash (transcript_path + session_id + agent_id) +# => 每個新 agent 拿到新檔名,但抽出的宣稱是同一批(取 transcript 最後一個 +# ,那個可能是舊的——檔頭 08-18 註解已記過同源問題)。 +# 實害:同兩條宣稱一天內產了 6 張不同 hash 的單,總管每回合重做一次已驗完的事。 +# => InkStoneCo#48:「永遠在誤響的警報,等於訓練人忽略這個警報」。 +# 改成 hash 宣稱內容本身,且已驗歸檔的直接跳過。 +claims_sig = "\n".join(sorted(ok_hits + ng_hits)) +stamp = hashlib.sha1(claims_sig.encode()).hexdigest()[:8] path = os.path.join(os.environ["DIR"], "claims-%s-%s.md" % (sid, stamp)) +_vdir = os.path.join(os.path.dirname(os.environ["DIR"]), "verified-claims") +if os.path.isdir(_vdir): + for _f in os.listdir(_vdir): + if stamp in _f: + print("SKIP:already-verified:%s" % stamp) + raise SystemExit + def block(title, items, howto, cap): if not items: return ""