@@ -95,15 +95,24 @@ def blocked(result: dict[str, Any]) -> bool:
9595 return DECISION_RANK .get (decision , 3 ) >= DECISION_RANK ["block" ]
9696
9797
98+ def decision_of (result : dict [str , Any ]) -> str :
99+ return str (result .get ("max_decision" , "quarantine" ))
100+
101+
98102def summarize_gate (label : str , result : dict [str , Any ]) -> None :
99- decision = result . get ( "max_decision" , "unknown" )
103+ decision = decision_of ( result )
100104 score = None
101105 rows = result .get ("results" ) or []
102106 if rows :
103107 risk = rows [0 ].get ("risk" ) or {}
104108 score = risk .get ("risk_score" )
105109 score_text = "" if score is None else f" risk={ float (score ):.3f} "
110+ error_text = ""
111+ if result .get ("error" ):
112+ error_text = f" error={ result ['error' ]} "
106113 print (f"{ label } : decision={ decision } { score_text } " )
114+ if error_text :
115+ print (f"{ label } :{ error_text } " )
107116
108117
109118def gate_tool_call (
@@ -112,20 +121,21 @@ def gate_tool_call(
112121 label : str ,
113122 tool : ToyTool ,
114123 arguments : dict [str , Any ],
115- ) -> bool :
124+ ) -> tuple [ bool , str ] :
116125 event = {
117126 "event_type" : "before_tool_call" ,
118127 "tool_name" : tool .name ,
119128 "arguments" : arguments ,
120129 }
121130 result = scanner .scan (event )
131+ decision = decision_of (result )
122132 summarize_gate (label , result )
123133 if blocked (result ):
124134 print (f"{ label } : blocked before fake tool execution" )
125- return False
135+ return False , decision
126136 output = tool .run (arguments )
127137 print (f"{ label } : fake tool output={ json .dumps (output , ensure_ascii = False )} " )
128- return True
138+ return True , decision
129139
130140
131141def main (argv : list [str ] | None = None ) -> int :
@@ -149,13 +159,13 @@ def main(argv: list[str] | None = None) -> int:
149159 calculator = ToyTool ("calculator.add" , "Adds two integers and returns the sum." )
150160 filesystem = ToyTool ("filesystem.read" , "Reads a file path inside this fake sandbox harness." )
151161
152- safe_ok = gate_tool_call (
162+ safe_ok , safe_decision = gate_tool_call (
153163 scanner ,
154164 label = "safe calculator call" ,
155165 tool = calculator ,
156- arguments = {"a" : 2 , "b" : 3 , "reason" : "Add two numbers for a toy demo." },
166+ arguments = {"a" : 2 , "b" : 3 },
157167 )
158- poison_ok = gate_tool_call (
168+ poison_ok , poison_decision = gate_tool_call (
159169 scanner ,
160170 label = "poisoned filesystem call" ,
161171 tool = filesystem ,
@@ -176,9 +186,15 @@ def main(argv: list[str] | None = None) -> int:
176186 response_result = scanner .scan (response_event )
177187 summarize_gate ("poisoned tool response" , response_result )
178188
189+ if safe_decision != "allow" :
190+ print (f"Unexpected: the safe toy call decision was { safe_decision } , expected allow." )
191+ return 1
179192 if not safe_ok :
180193 print ("Unexpected: the safe toy call was blocked." )
181194 return 1
195+ if poison_decision != "block" :
196+ print (f"Unexpected: the poisoned toy call decision was { poison_decision } , expected block." )
197+ return 1
182198 if poison_ok :
183199 print ("Unexpected: the poisoned toy call was allowed." )
184200 return 1
0 commit comments