feat: verify attack-chain nodes against real tool calls

A node claiming something ran must cite a tool_call_id the host issued in
the trajectory. A citation absent from the trajectory is invented, so the
node is dropped along with its edges; a missing citation counts as invented
only when every real ID survived budget fitting, so a trimmed payload cannot
silently empty a graph. Judging is skipped where the evidence cannot be
enumerated: the process-detail supplement dumps raw event JSON and the
messages-table fallback carries no call IDs. Verified citations land in node
metadata rather than tool_execution_id, which is foreign-keyed to
tool_executions.

Also close two smaller holes: fact text can no longer carry the host index
delimiters, which would close the block early and spill the remaining index
into the system prompt; and the console fact endpoints reject the reserved
note/context-* prefix, matching the MCP tool layer.
This commit is contained in:
Sycun committed 2026-10-13 00:10:33 +08:00
1 parent 16189e0b76
commit 3d2dfdac36
10 files changed
+341 -15

No files matched your search

+7
View File
@@ -49,6 +49,13 @@ func wrapFactIndexBlock(content string) string {
return FactIndexSectionStartMarker + "\n" + content + "\n" + FactIndexSectionEndMarker + "\n"
}
// factIndexSafeText 去掉事实文本里的宿主定界符。索引块按字面量定位起止,内容里
// 出现同名注释会提前闭合块,把其余索引内容甩到系统提示的块外。
func factIndexSafeText(s string) string {
s = strings.ReplaceAll(s, FactIndexSectionStartMarker, "")
return strings.ReplaceAll(s, FactIndexSectionEndMarker, "")
}
func factIndexSectionStart(content string) (int, bool) {
idx := strings.Index(content, FactIndexSectionStartMarker)
if idx < 0 {