@@ -203,25 +203,42 @@ def run(self, execution, body, wake, session_wake, stdout, stderr, timeout):
203203 raise subprocess .TimeoutExpired (command , timeout )
204204 if not select .select ([self .listener ], [], [], min (.1 , remaining ))[0 ]:
205205 continue
206- with held_quota_decision (self .listener , self .capture_root ,
207- goal_id = self .env ["LOOPX_GOAL_ID" ], agent_id = self .env ["LOOPX_AGENT_ID" ],
208- turn_instance_id = None , native_process = process ,
209- interrupt_timeout = min (10 , remaining ), interrupt_when = self ._first_replan ,
210- deadline = deadline ) as held :
211- if "native_process_return_code" not in held :
212- continue
213- stdout .flush ()
214- session_wake .observe (wake / "stdout.jsonl" )
215- event = {"obligation_id" : held ["intent" ]["obligation_id" ],
216- "decision_path" : str (held ["path" ]), "decision_sha256" : held ["sha256" ],
217- "captured" : False , "research_point_qualified" : False }
218- self .receipt .setdefault ("checkpoint_handoffs" , []).append (event )
206+ # Only a consumed request can be refused and retried.
207+ # Accept failures belong to the Host, not the packet.
208+ with self .listener .accept ()[0 ] as channel :
209+ entered = False
219210 try :
220- event .update (self ._capture (held , deadline ), captured = True )
211+ with held_quota_decision (self .listener , self .capture_root ,
212+ goal_id = self .env ["LOOPX_GOAL_ID" ], agent_id = self .env ["LOOPX_AGENT_ID" ],
213+ turn_instance_id = None , native_process = process ,
214+ interrupt_timeout = min (10 , remaining ), interrupt_when = self ._first_replan ,
215+ deadline = deadline , accepted_channel = channel ) as held :
216+ entered = True
217+ if "native_process_return_code" not in held :
218+ continue
219+ stdout .flush ()
220+ session_wake .observe (wake / "stdout.jsonl" )
221+ event = {"obligation_id" : held ["intent" ]["obligation_id" ],
222+ "decision_path" : str (held ["path" ]), "decision_sha256" : held ["sha256" ],
223+ "captured" : False , "research_point_qualified" : False }
224+ self .receipt .setdefault ("checkpoint_handoffs" , []).append (event )
225+ try :
226+ event .update (self ._capture (held , deadline ), captured = True )
227+ except Exception as error :
228+ # A missed optional point cannot discard the original
229+ # committed guard or turn a later retry into its capture.
230+ event .update (error_kind = type (error ).__name__ , error = str (error )[:500 ])
221231 except Exception as error :
222- # A missed optional point cannot discard the original
223- # committed guard or turn a later retry into its capture.
224- event .update (error_kind = type (error ).__name__ , error = str (error )[:500 ])
232+ # A refused handoff (unparseable, outside this wake's capture
233+ # root, or rejected by the typed selector) is neither released
234+ # nor captured; its caller already reports a typed transport
235+ # failure. The uninterrupted original wake keeps running.
236+ if entered or process .poll () is not None :
237+ raise
238+ self .receipt .setdefault ("checkpoint_handoffs" , []).append ({
239+ "captured" : False , "research_point_qualified" : False , "released" : False ,
240+ "error_kind" : type (error ).__name__ , "error" : str (error )[:500 ]})
241+ continue
225242 continuation = held .get ("continuation_body" )
226243 if continuation is not None :
227244 break
0 commit comments