refactor(hooks): tighten the hook-protocol contract surface

Implement the tighten-hook-protocol-contract RFC (moved to implemented/):

- HookDialect narrows to 'claude' | 'codex': the 'native' variant had zero
  producers (native plugins on the seams write no hook/* provenance), and the
  dialect is defined as the bridge that ran the hook.
- HookOutput.suppressOutput is gone: the codec parsed it and every path
  discarded it with no warn and no deferral — hook stdout never enters a
  transcript, so there is nothing to suppress.
- hook/result.durationMs is gone: durable timing telemetry with no reader
  that the snapshot normalizer had to scrub as replay noise. With no duration
  to measure, runHook loses its injected now clock and the single-field
  RunHookResult wrapper — it returns the HookOutput directly. The committed
  hook fixtures had the field stripped mechanically (field-only diff); the
  stdout goldens never carried it.
- The bridges' double-defaulted defaultTimeoutMs config knob is replaced by
  one reference-default constant, DEFAULT_HOOK_TIMEOUT_MS, exported from the
  lib's runner and applied inside runHook; per-hook timeoutSec stays the
  override surface.
- The hook/result semantics move into the lib that declares the event:
  HookResultRecord now carries the decoded HookOutput and appendHookResult
  derives the decision string (decision ?? stop-on-continue:false ?? pass)
  and the 500-char stderrSummary truncation; both bridges delete their
  byte-identical private copies. The snapshot suite passes against the
  existing goldens, proving the derived values are unchanged.
- Rider: BLOCKING_EXIT_CODE is codec-internal again (zero importers).

Amend the hook-protocol-lib and hook-snapshot-matrix RFCs to the new facts,
update the lib/bridge READMEs and the session.md event tables, and retarget
the affected unit tests (including new lib-level coverage of the derivation
rules).
This commit is contained in:
Tianyi Cui
2026-07-04 15:44:26 +08:00
parent 226a8b5e4c
commit cd49670f4e
36 changed files with 233 additions and 235 deletions

View File

@@ -59,7 +59,7 @@
{"type":"assistant/message","seq":57,"time":1783095423411,"data":{"turn":1,"step":1,"content":[{"type":"reasoning","text":"The user wants me to run `echo HELLO` using the bash tool and report the result verbatim."},{"type":"tool-call","id":"call_00_NN9uJWZQDPiUfGC6VAtF0696","name":"bash","arguments":"{\"command\": \"echo HELLO\", \"description\": \"Run echo HELLO\"}"}],"usage":{"inputTokens":72,"outputTokens":89,"cacheReadTokens":1664,"reasoningTokens":23}},"sourceEventSeqs":[3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56],"surfaceOp":"append"}
{"type":"tool/call","seq":58,"time":1783095423412,"data":{"turn":1,"step":1,"callId":"call_00_NN9uJWZQDPiUfGC6VAtF0696","name":"bash","arguments":"{\"command\": \"echo HELLO\", \"description\": \"Run echo HELLO\"}"}}
{"type":"hook/invoked","seq":59,"time":1783095423425,"data":{"turn":1,"point":"PostToolUse","dialect":"codex","handlerId":"codex:PostToolUse:1","matcher":"bash"}}
{"type":"hook/result","seq":60,"time":1783095423432,"data":{"turn":1,"point":"PostToolUse","handlerId":"codex:PostToolUse:1","decision":"block","exitCode":2,"stderrSummary":"tool output rejected by codex policy: summarize instead","durationMs":6.750618000000031}}
{"type":"hook/result","seq":60,"time":1783095423432,"data":{"turn":1,"point":"PostToolUse","handlerId":"codex:PostToolUse:1","decision":"block","exitCode":2,"stderrSummary":"tool output rejected by codex policy: summarize instead"}}
{"type":"tool/result","seq":61,"time":1783095423432,"data":{"turn":1,"step":1,"callId":"call_00_NN9uJWZQDPiUfGC6VAtF0696","content":[{"type":"text","text":"tool output rejected by codex policy: summarize instead"}],"isError":true},"sourceEventSeqs":[58],"surfaceOp":"append"}
{"type":"step/end","seq":62,"time":1783095423432,"data":{"turn":1,"step":1}}
{"type":"step/start","seq":63,"time":1783095423433,"data":{"turn":1,"step":2}}
@@ -117,7 +117,7 @@
{"type":"assistant/message","seq":115,"time":1783095424733,"data":{"turn":1,"step":2,"content":[{"type":"reasoning","text":"The output was rejected by codex policy. Let me try again with the exact command as specified."},{"type":"tool-call","id":"call_00_vYk35aagabBlYGHTvJqn7418","name":"bash","arguments":"{\"description\": \"Run echo HELLO\", \"command\": \"echo HELLO\"}"}],"usage":{"inputTokens":55,"outputTokens":86,"cacheReadTokens":1792,"reasoningTokens":20}},"sourceEventSeqs":[64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114],"surfaceOp":"append"}
{"type":"tool/call","seq":116,"time":1783095424733,"data":{"turn":1,"step":2,"callId":"call_00_vYk35aagabBlYGHTvJqn7418","name":"bash","arguments":"{\"description\": \"Run echo HELLO\", \"command\": \"echo HELLO\"}"}}
{"type":"hook/invoked","seq":117,"time":1783095424745,"data":{"turn":1,"point":"PostToolUse","dialect":"codex","handlerId":"codex:PostToolUse:2","matcher":"bash"}}
{"type":"hook/result","seq":118,"time":1783095424753,"data":{"turn":1,"point":"PostToolUse","handlerId":"codex:PostToolUse:2","decision":"block","exitCode":2,"stderrSummary":"tool output rejected by codex policy: summarize instead","durationMs":7.9194109999998545}}
{"type":"hook/result","seq":118,"time":1783095424753,"data":{"turn":1,"point":"PostToolUse","handlerId":"codex:PostToolUse:2","decision":"block","exitCode":2,"stderrSummary":"tool output rejected by codex policy: summarize instead"}}
{"type":"tool/result","seq":119,"time":1783095424753,"data":{"turn":1,"step":2,"callId":"call_00_vYk35aagabBlYGHTvJqn7418","content":[{"type":"text","text":"tool output rejected by codex policy: summarize instead"}],"isError":true},"sourceEventSeqs":[116],"surfaceOp":"append"}
{"type":"step/end","seq":120,"time":1783095424753,"data":{"turn":1,"step":2}}
{"type":"step/start","seq":121,"time":1783095424753,"data":{"turn":1,"step":3}}
@@ -175,7 +175,7 @@
{"type":"assistant/message","seq":173,"time":1783095426479,"data":{"turn":1,"step":3,"content":[{"type":"reasoning","text":"The tool output is being rejected by codex policy. Let me try a slightly different approach - maybe I need to be more careful with the description or command."},{"type":"tool-call","id":"call_00_XLxXjqVljRIC2KwFZCKX3369","name":"bash","arguments":"{\"command\": \"echo HELLO\"}"}],"usage":{"inputTokens":163,"outputTokens":78,"cacheReadTokens":1792,"reasoningTokens":32}},"sourceEventSeqs":[122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172],"surfaceOp":"append"}
{"type":"tool/call","seq":174,"time":1783095426479,"data":{"turn":1,"step":3,"callId":"call_00_XLxXjqVljRIC2KwFZCKX3369","name":"bash","arguments":"{\"command\": \"echo HELLO\"}"}}
{"type":"hook/invoked","seq":175,"time":1783095426479,"data":{"turn":1,"point":"PostToolUse","dialect":"codex","handlerId":"codex:PostToolUse:3","matcher":"bash"}}
{"type":"hook/result","seq":176,"time":1783095426488,"data":{"turn":1,"point":"PostToolUse","handlerId":"codex:PostToolUse:3","decision":"block","exitCode":2,"stderrSummary":"tool output rejected by codex policy: summarize instead","durationMs":8.644037999999455}}
{"type":"hook/result","seq":176,"time":1783095426488,"data":{"turn":1,"point":"PostToolUse","handlerId":"codex:PostToolUse:3","decision":"block","exitCode":2,"stderrSummary":"tool output rejected by codex policy: summarize instead"}}
{"type":"tool/result","seq":177,"time":1783095426488,"data":{"turn":1,"step":3,"callId":"call_00_XLxXjqVljRIC2KwFZCKX3369","content":[{"type":"text","text":"tool output rejected by codex policy: summarize instead"}],"isError":true},"sourceEventSeqs":[174],"surfaceOp":"append"}
{"type":"step/end","seq":178,"time":1783095426488,"data":{"turn":1,"step":3}}
{"type":"step/start","seq":179,"time":1783095426489,"data":{"turn":1,"step":4}}
@@ -222,7 +222,7 @@
{"type":"assistant/message","seq":220,"time":1783095427668,"data":{"turn":1,"step":4,"content":[{"type":"reasoning","text":"The tool is consistently rejecting the output. Let me try a different way to invoke it."},{"type":"tool-call","id":"call_00_twNfzWSJ9WJn8YeoGVIi1932","name":"bash","arguments":"{\"command\": \"printf 'HELLO\\\\n'\"}"}],"usage":{"inputTokens":135,"outputTokens":67,"cacheReadTokens":1920,"reasoningTokens":18}},"sourceEventSeqs":[180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219],"surfaceOp":"append"}
{"type":"tool/call","seq":221,"time":1783095427668,"data":{"turn":1,"step":4,"callId":"call_00_twNfzWSJ9WJn8YeoGVIi1932","name":"bash","arguments":"{\"command\": \"printf 'HELLO\\\\n'\"}"}}
{"type":"hook/invoked","seq":222,"time":1783095427668,"data":{"turn":1,"point":"PostToolUse","dialect":"codex","handlerId":"codex:PostToolUse:4","matcher":"bash"}}
{"type":"hook/result","seq":223,"time":1783095427677,"data":{"turn":1,"point":"PostToolUse","handlerId":"codex:PostToolUse:4","decision":"block","exitCode":2,"stderrSummary":"tool output rejected by codex policy: summarize instead","durationMs":8.75036799999998}}
{"type":"hook/result","seq":223,"time":1783095427677,"data":{"turn":1,"point":"PostToolUse","handlerId":"codex:PostToolUse:4","decision":"block","exitCode":2,"stderrSummary":"tool output rejected by codex policy: summarize instead"}}
{"type":"tool/result","seq":224,"time":1783095427677,"data":{"turn":1,"step":4,"callId":"call_00_twNfzWSJ9WJn8YeoGVIi1932","content":[{"type":"text","text":"tool output rejected by codex policy: summarize instead"}],"isError":true},"sourceEventSeqs":[221],"surfaceOp":"append"}
{"type":"step/end","seq":225,"time":1783095427678,"data":{"turn":1,"step":4}}
{"type":"step/start","seq":226,"time":1783095427678,"data":{"turn":1,"step":5}}
@@ -286,7 +286,7 @@
{"type":"assistant/message","seq":284,"time":1783095429025,"data":{"turn":1,"step":5,"content":[{"type":"reasoning","text":"Every attempt is being rejected. Let me try to see what's happening by running a different command first, to check if bash works at all."},{"type":"text","text":"Let me check if bash itself is working:"},{"type":"tool-call","id":"call_00_xOnTckie072jHuPhX0Mz5115","name":"bash","arguments":"{\"command\": \"pwd\"}"}],"usage":{"inputTokens":96,"outputTokens":81,"cacheReadTokens":2048,"reasoningTokens":29}},"sourceEventSeqs":[227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283],"surfaceOp":"append"}
{"type":"tool/call","seq":285,"time":1783095429025,"data":{"turn":1,"step":5,"callId":"call_00_xOnTckie072jHuPhX0Mz5115","name":"bash","arguments":"{\"command\": \"pwd\"}"}}
{"type":"hook/invoked","seq":286,"time":1783095429025,"data":{"turn":1,"point":"PostToolUse","dialect":"codex","handlerId":"codex:PostToolUse:5","matcher":"bash"}}
{"type":"hook/result","seq":287,"time":1783095429046,"data":{"turn":1,"point":"PostToolUse","handlerId":"codex:PostToolUse:5","decision":"block","exitCode":2,"stderrSummary":"tool output rejected by codex policy: summarize instead","durationMs":21.25910400000066}}
{"type":"hook/result","seq":287,"time":1783095429046,"data":{"turn":1,"point":"PostToolUse","handlerId":"codex:PostToolUse:5","decision":"block","exitCode":2,"stderrSummary":"tool output rejected by codex policy: summarize instead"}}
{"type":"tool/result","seq":288,"time":1783095429047,"data":{"turn":1,"step":5,"callId":"call_00_xOnTckie072jHuPhX0Mz5115","content":[{"type":"text","text":"tool output rejected by codex policy: summarize instead"}],"isError":true},"sourceEventSeqs":[285],"surfaceOp":"append"}
{"type":"step/end","seq":289,"time":1783095429047,"data":{"turn":1,"step":5}}
{"type":"step/start","seq":290,"time":1783095429047,"data":{"turn":1,"step":6}}