+
    lHàj° ã                   ó,  a € R¾ t‰0 t R t^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIt^ RI	H
t
 ^ RIHtHt ^ RIHt ^ RIHt ^ RIHtHtHtHtHtHtHtHtHt ^ RIHtHtHtH t  ^ R	I!H"t"H#t#H$t$H%t%H&t& ^ R
I'H(t( ^ RI)H*t*H+t+H,t, ^ RI-H.t. ]P^                  ! ]04      t1]! ]Pd                  ! RR4      4      t3] ^ k ]Ph                  ! 4       t5/ t6] ^k / t7] ^k ]8! 4       t9] ^k ]8! 4       t:] ^k ]8! 4       t;] ^k / t<] ^k / t=] ^k Rt>R R lt?R R lt@R R ltAR R ltB/ tC] ^k / tD] ^	k R R ltER R ltFR¿R R lltGR R  ltHR! R" ltIR# R$ ltJR% R& ltKR' R( ltLR) R* ltMR+ R, ltNR- R. ltOR/ R0 ltPR1 R2 ltQR3 R4 ltRR5 R6 ltSR7 R8 ltTR9 R: ltUR; R< ltVR= R> ltWR? R@ ltXRA RB ltYRC RD ltZRE RF lt[RG RH lt\RI RJ lt]RK RL lt^RM RN lt_RO RP lt`/ ta] ^
k RQ RR ltbRS RT ltcRU RV ltdRW RX lteRY RZ ltfR[ R\ ltg]h! 0 RÀm4      ti]h! 0 RÁm4      tjRÂR` Ra lltkRbR]/Rc Rd lltlRe Rf ltmRg Rh ltnRi Rj ltoRk Rl ltp]! RmRn7       ! Ro Rp4      4       tq]q! RqRrRsRtRu4      tr]q! RvRwRxRyRz4      tsR{ R| lttR} R~ ltu]! RmRn7       ! R R€4      4       tvR�twR‚tx]v! R]RmRmRRmRƒR„]w,           R…,           R†R‡]w,           Rˆ,           R‰]w,           RŠ,           R‹RŒ7      ty]v! R^RmRmRmRmR�RŽR�R�]x,           Rˆ,           R‘R’RŒ7      tz]v! R_RRRRRƒR“]x,           R”,           RR�]x,           R•,           R–RRŒ7      t{R— R˜ lt|R™RRšR/R› Rœ llt}RÃR� Rž llt~RŸRR RRbR¡R¢R£R¤RR¥RR¦RR§RR¨R/	R© Rª lltRÄR« R¬ llt€R­ R® lt�R¯R/R° R± llt‚RÅR² R³ lltƒR´RRŸR/Rµ R¶ llt„RÅR· R¸ llt…R¹t†Rº R» lt‡RÄR¼ R½ lltˆ]c! 4        R# )Æac  Dangerous command approval -- the gate flow and per-session state.

Owns the session state (approvals, yolo, gateway queues, denial breaker), the three guard
entry points (``check_all_command_guards``, ``check_execute_code_guard``,
``request_tool_approval`` / ``_run_approval_gate``) and the shared human-decision engine
behind them. Leaves: ``approval_detection`` (hardline/dangerous patterns), ``approval_context``
(contextvars, config readers), ``approval_floors`` (pre-gate blocks, allowlist match),
``approval_prompt`` (CLI prompt, plugin transports, MCP elicitation), ``approval_gateway_wait``
(blocking gateway round-trip), ``approval_smart`` (guardian LLM), ``approval_human_wait``.
Leaves read facade-owned state (``_lock``, queues, denial breaker) back through ``tools.approval`` at
call time; sibling-defined names are imported from their defining module.
)Ú	dataclassN)ÚOptional)Úenv_var_enabledÚis_truthy_value)Út)Úapproval_context)	Ú_get_session_platformÚ_is_cron_approval_contextÚ_is_gateway_approval_contextÚ_is_interactive_cliÚ!_is_single_query_approval_contextÚ(_is_unattended_platform_approval_contextÚ_resolve_cli_approval_callbackÚ$_should_fall_through_to_cli_approvalÚget_current_session_key)Ú_approval_key_aliasesÚ_check_sudo_stdin_guardÚdetect_dangerous_commandÚdetect_hardline_command)Ú$_command_matches_permanent_allowlistÚ_hardline_block_resultÚ_match_user_deny_ruleÚ_sudo_stdin_block_resultÚ_user_deny_block_result)Ú_await_gateway_decision)Ú _present_with_selected_transportÚ_transport_choiceÚprompt_dangerous_approval)Ú_smart_verdictÚHERMES_YOLO_MODEÚ é   c                ó$   € V ^8„  d   QhR\         /# ©é   Úreturn©Úint)Úformats   "Ú3/home/ubuntu/.hermes/hermes-agent/tools/approval.pyÚ__annotate__r*   H   s   € ÷ ñ ¤sñ ó    c                 ó�   €  \        \        P                  ! 4       P                  R^4      4      #   \        \
        3 d     ^# i ; i)zJ``approvals.denial_breaker_threshold``: default 3; 0 or negative disables.Údenial_breaker_threshold)r'   r   Ú_get_approval_configÚgetÚ
ValueErrorÚ	TypeError© r+   r)   Ú_get_denial_breaker_thresholdr3   H   sB   € ðÜÔ#×8Ò8Ó:×>Ñ>Ð?YÐ[\Ó]Ó^Ð^øÜœ	Ð"ô Úðús   ‚-0 °AÁAc                ó0   € V ^8„  d   QhR\         R\        /# ©r$   Úsession_keyr%   )Ústrr'   )r(   s   "r)   r*   r*   P   s   € ÷ ñ ¤ð ¬ñ r+   c           	     ó6  € \         ;_uu_ 4        \        P                  V ^ 4      ^,           pV\        V &   \        \        4      \        8”  d.   \        P                  \        \        \        4      4      4       KE  VuuRRR4       #   + '       g   i     R# ; i)zªIncrement and return the session's consecutive guardian-denial count. Pop-and-reinsert
keeps actively-denying sessions at the most-recent end so eviction drops idle keys.N)Ú_lockÚ_denial_tallyÚpopÚlenÚ_DENIAL_TALLY_MAX_SESSIONSÚnextÚiter)r6   Úcounts   & r)   Ú_record_denialrA   P   s_   € ÷ 
ŽÜ×!Ñ! +¨qÓ1°AÕ5ˆØ%*Œ�kÑ"Ü”-Ó Ô#=Ô=Ü×Ñœd¤4¬Ó#6Ó7Ö8Ø÷ 
��‹ús   �A-BÂB	c                ó(   € V ^8„  d   QhR\         RR/# ©r$   r6   r%   N©r7   )r(   s   "r)   r*   r*   [   s   € ÷ -ñ -¤ð -¨ñ -r+   c                óˆ   € \         ;_uu_ 4        \        P                  V R4       RRR4       R#   + '       g   i     R# ; i)zDClear the session's consecutive-denial tally (an approval happened).N)r9   r:   r;   ©r6   s   &r)   Ú_reset_denialsrG   [   s#   € ç	ŽÜ×Ñ˜+ tÔ,÷ 
��Šús	   �0°A	c                ó0   € V ^8„  d   QhR\         R\         /# r5   rD   )r(   s   "r)   r*   r*   a   s   € ÷ ñ ¬#ð ´#ñ r+   c                óð   € \         ;_uu_ 4        \        P                  V ^ 4      pRRR4       \        4       pV^ 8:  g   XV8  d   R# \        P                  RWV4       RV R2#   + '       g   i     LG; i)z«Escalated hard-stop text once the breaker has tripped, else ''. Read-only: callers
increment via :func:`_record_denial`; the text is appended verbatim to the deny message.Nr    z\Smart-approval circuit breaker tripped for session %s: %d consecutive denials (threshold %d)z CIRCUIT BREAKER: zË consecutive commands were blocked by the security reviewer. STOP attempting variations of this operation. Report the blocked operation to the user and either ask them to run it manually or use /approve.)r9   r:   r/   r3   ÚloggerÚwarning)r6   r@   Ú	thresholds   &  r)   Ú_denial_breaker_addendumrM   a   sq   € ÷ 
ŽÜ×!Ñ! +¨qÓ1ˆ÷ 
ä-Ó/€IØ�A„~˜ Ô*Ùô ‡N�NØfØ˜Iôð
 ˜U˜Gð $vð 	vð÷ 
�ús   �A%Á%A5	c                ó(   € V ^8„  d   QhR\         RR/# rC   rD   )r(   s   "r)   r*   r*   ~   s   € ÷ .ñ .¬ð .°Tñ .r+   c                ón   € \         ;_uu_ 4        V\        V &   RRR4       R#   + '       g   i     R# ; i)u²   Register ``cb(approval_data: dict) -> None`` for sending approval requests. The callback
bridges syncâ†’async: it runs in the agent thread and must schedule the send on the loop.N)r9   Ú_gateway_notify_cbs)r6   Úcbs   &&r)   Úregister_gateway_notifyrR   ~   s    € ÷ 
ŽØ+-Ô˜KÑ(÷ 
��Šúó   �
#£4	c                ó(   € V ^8„  d   QhR\         RR/# rC   rD   )r(   s   "r)   r*   r*   …   s   € ÷ ñ ¬3ð °4ñ r+   c                óö   € \         ;_uu_ 4        \        P                  V R4       \        P                  V . 4       F  pVP                  P                  4        K  	  RRR4       R#   + '       g   i     R# ; i)z…Unregister the callback and wake ALL blocked threads for this session so
they don't hang forever (agent run finished or interrupted).N)r9   rP   r;   Ú_gateway_queuesÚeventÚset©r6   Úentrys   & r)   Úunregister_gateway_notifyr[   …   sJ   € ÷ 
ŽÜ×Ñ ¨TÔ2Ü$×(Ñ(¨°bÖ9ˆEØ�K‰K�O‰OÖñ :÷ 
��Šús   �AA'Á'A8	Fc                óŒ   € V ^8„  d   QhR\         R\         R\        R\        \         ,          R\        \         ,          R\        /# )r$   r6   ÚchoiceÚresolve_allÚreasonÚ
request_idr%   )r7   Úboolr   r'   )r(   s   "r)   r*   r*   Ž   sH   € ÷ "ñ "¬#ð "´sð "Ü*.ð"ä%-¬c¥]ð"ô *2´#­ð"ô CFñ"r+   c                ó¼  € \         ;_uu_ 4        \        P                  V 4      pV'       g    RRR4       ^ # V'       dd   V Uu. uF&  qfP                  P                  R4      V8X  g   K$  VNK(  	  ppV'       g    RRR4       ^ # V Uu. uF  qfV9  g   K  VNK  	  upVR&   M6V'       d   \	        V4      pVP                  4        MVP                  ^ 4      .pV'       g   \        P                  V R4       V F1  pWn        V'       d   W6n        VP                  P                  4        K3  	  RRR4       \        X4      # u upi u upi   + '       g   i     L%; i)aG  Unblock waiting agent thread(s) from the gateway's /approve or /deny handler.

*resolve_all* resolves every pending approval (``/approve all``); otherwise the oldest
(FIFO) or the one matching *request_id*. *reason* is the ``/deny <reason>`` free text,
relayed to the agent in the BLOCKED message. Returns the number resolved.
Nr`   :NNN)r9   rV   r/   ÚdataÚlistÚclearr;   Úresultr_   rW   rX   r<   )r6   r]   r^   r_   r`   ÚqueuerZ   Útargetss   &&&&&   r)   Úresolve_gateway_approvalri   Ž   s  € ÷ 
ŽÜ×#Ñ# KÓ0ˆßØ÷ 
‰÷ Ù*/Ó^©% ·:±:·>±>À,Ó3OÐS]Ñ3]—u�u©%ˆGÐ^ßØ÷ 
‰ñ ,1ÓI©5 %ÀÑ4HŸ˜©5ÑIˆE�!ŠHßÜ˜5“kˆGØ�K‰K�Mà—y‘y “|�nˆGßÜ×Ñ ¨TÔ2ó ˆEØ!ŒLßØ%”Ø�K‰K�O‰OÖñ	 ÷' 
ô0 ˆw‹<Ðùò' _ùò J÷ 
�úsS   �E¸EÁ EÁ!EÁ*EÁ0EÂEÂ	EÂEÂEÂ+5EÃ!AEÅ
EÅE	c                óH   € V ^8„  d   QhR\         R\         R\         R\        /# )r$   r6   r`   Úcauser%   ©r7   ra   )r(   s   "r)   r*   r*   ³   s)   € ÷ ñ ¬3ð ¼Cð Ìð ÔPTñ r+   c                ór  a€ \         ;_uu_ 4        \        P                  V . 4      p\        V3R lV 4       R4      pVf    RRR4       R# VP	                  V4       V'       g   \        P                  V R4       W$n        VP                  P                  4        RRR4       R#   + '       g   i     R# ; i)u  Withdraw one pending approval nobody can answer (the only attached client cannot render it).
The waiter wakes at once with ``cancelled=cause`` â€” a withdrawal, never a user deny â€” instead of
idling for the whole approvals.timeout (#112548). False when it is no longer pending.c              3   ój   <"  € T F(  qP                   P                  R 4      S8X  g   K$  Vx € K*  	  R# 5i)r`   N)rc   r/   )Ú.0Úer`   s   & €r)   Ú	<genexpr>Ú,withdraw_gateway_approval.<locals>.<genexpr>¹   s%   øé € ÐQ¡˜A¯&©&¯*©*°\Ó*BÀjÑ*P—a’a£ùs   ƒ!3©
3NFT)	r9   rV   r/   r>   Úremover;   Ú	cancelledrW   rX   )r6   r`   rk   rg   rZ   s   &f&  r)   Úwithdraw_gateway_approvalru   ³   s‰   ø€ ÷ 
ŽÜ×#Ñ# K°Ó4ˆÜÔQ¡ÓQÐSWÓXˆØŠ=Ø÷	 
‰ð
 	�‰�UÔßÜ×Ñ ¨TÔ2ØŒØ�‰�‰Ô÷ 
ñ ÷ 
Žñ ús   �2B%ÁB%Á%6B%Â%B6	c                óF   € V ^8„  d   QhR\         R\        \        ,          /# r5   )r7   rd   Údict)r(   s   "r)   r*   r*   Ä   s"   € ÷ Tñ T¬ð T´´Tµ
ñ Tr+   c                óØ   € \         ;_uu_ 4        \        P                  V . 4       Uu. uF  p\        VP                  4      NK  	  upuuRRR4       # u upi   + '       g   i     R# ; i)zEReturn replay-safe snapshots of unresolved approvals for one session.N©r9   rV   r/   rw   rc   rY   s   & r)   Úlist_gateway_approvalsrz   Ä   sE   € ç	ŽÜ.=×.AÑ.AÀ+ÈrÔ.RÓSÑ.R U”�U—Z‘ZÖ Ñ.RÑS÷ 
ŠùÚS÷ 
�ˆús   �A¨AÁAÁAÁA)	c                ó<   € V ^8„  d   QhR\         R\         R\        /# ©r$   r6   r`   r%   rl   )r(   s   "r)   r*   r*   Ê   s!   € ÷ ñ ¬ð ¼#ð Ì$ñ r+   c                óø   € \         ;_uu_ 4        \        P                  V . 4       F4  pVP                  P                  R4      V8X  g   K%  W#n         RRR4       R# 	  RRR4       R#   + '       g   i     R# ; i)z½Attach ``settle(reason)`` to one pending approval; it runs once when that wait ends by any path.
False when the request is no longer pending (the surface should withdraw its prompt itself).r`   NTF)r9   rV   r/   rc   Úsettle)r6   r`   r~   rZ   s   &&& r)   Úregister_gateway_settler   Ê   sY   € ÷ 
ŽÜ$×(Ñ(¨°bÖ9ˆEØ�z‰z�~‰~˜lÓ+¨zÖ9Ø%”Ø÷	 
‰Ù9÷ 
ñ
 ÷ 
Žñ
 ús   �7A(ÁA(ÁA(Á(A9	c                ó<   € V ^8„  d   QhR\         R\         R\        /# r|   rl   )r(   s   "r)   r*   r*   Õ   s!   € ÷ ñ ¤cð ´sð ¼tñ r+   c                óú   € \         ;_uu_ 4        \        P                  V . 4       F5  pVP                  P                  R4      V8X  g   K%  RVn         RRR4       R# 	  RRR4       R#   + '       g   i     R# ; i)zDRecord that a client received a particular pending approval request.r`   TNF)r9   rV   r/   rc   Úacknowledged)r6   r`   rZ   s   && r)   Úack_gateway_approvalrƒ   Õ   sZ   € ç	ŽÜ$×(Ñ(¨°bÖ9ˆEØ�z‰z�~‰~˜lÓ+¨zÖ9Ø%)�Ô"Ø÷	 
‰Ù9÷ 
ñ
 ÷ 
Žñ
 ús   �7A)ÁA)ÁA)Á)A:	c                ó0   € V ^8„  d   QhR\         R\        /# r5   rl   )r(   s   "r)   r*   r*   ß   s   € ÷ 6ñ 6¤sð 6¬tñ 6r+   c                ó˜   € \         ;_uu_ 4        \        \        P                  V 4      4      uuRRR4       #   + '       g   i     R# ; i)zFCheck if a session has one or more blocking gateway approvals waiting.N)r9   ra   rV   r/   rF   s   &r)   Úhas_blocking_approvalr†   ß   s&   € ç	ŽÜ”O×'Ñ'¨Ó4Ó5÷ 
��‹ús	   �8¸A		c                ó$   € V ^8„  d   QhR\         /# r#   r&   )r(   s   "r)   r*   r*   å   s   € ÷ Eñ E¬ñ Er+   c                 ó¤   € \         ;_uu_ 4        \        R \        P                  4        4       4      uuRRR4       #   + '       g   i     R# ; i)u[   Unresolved gateway approvals across every session â€” a backend blocked on one is not idle.c              3   ó8   "  € T F  p\        V4      x € K  	  R # 5i©N)r<   )ro   rg   s   & r)   rq   Ú1pending_gateway_approval_count.<locals>.<genexpr>è   s   é € ÐDÑ+C %”3�u—:�:Ó+Cùs   ‚N)r9   ÚsumrV   Úvaluesr2   r+   r)   Úpending_gateway_approval_countrŽ   å   s*   € ç	ŽÜÑD¬?×+AÑ+AÔ+CÓDÓD÷ 
��‹ús	   �$>¾A	c                ó>   € V ^8„  d   QhR\         R\        R,          /# rC   ©r7   rw   )r(   s   "r)   r*   r*   ë   s   € ÷ 	#ñ 	#¬cð 	#´d¸Tµkñ 	#r+   c                óø   € V '       g   R# \         ;_uu_ 4        \        P                  V 4      pV'       g    RRR4       R# \        V^ ,          P                  4      uuRRR4       #   + '       g   i     R# ; i)u“   Copy of the oldest unresolved gateway approval, for reconnecting clients
to restore a prompt. Read-only snapshot â€” the queue stays authoritative.Nry   )r6   rg   s   & r)   Úget_pending_gateway_approvalr’   ë   sJ   € ÷ Ùß	ŽÜ×#Ñ# KÓ0ˆßØ÷ 
‰ô �E˜!•H—M‘MÓ"÷	 
��‹ús   ™A(ÁA(Á(A9	c                ó0   € V ^8„  d   QhR\         R\        /# )r$   r6   Úapprovalr�   )r(   s   "r)   r*   r*   ÷   s   € ÷ )ñ )¤ð )¬tñ )r+   c                ón   € \         ;_uu_ 4        V\        V &   RRR4       R#   + '       g   i     R# ; i)z/Store a pending approval request for a session.N)r9   Ú_pending)r6   r”   s   &&r)   Úsubmit_pendingr—   ÷   s   € ç	ŽØ (Œ�Ñ÷ 
��ŠúrS   c                ó0   € V ^8„  d   QhR\         R\         /# )r$   r6   Úpattern_keyrD   )r(   s   "r)   r*   r*   ý   s   € ÷ Jñ J¤ð J´3ñ Jr+   c                ó¶   € \         ;_uu_ 4        \        P                  V \        4       4      P	                  V4       RRR4       R#   + '       g   i     R# ; i)z(Approve a pattern for this session only.N)r9   Ú_session_approvedÚ
setdefaultrX   Úadd)r6   r™   s   &&r)   Úapprove_sessionrž   ý   s0   € ç	ŽÜ×$Ñ$ [´#³%Ó8×<Ñ<¸[ÔI÷ 
��Šús   �.AÁA	c                ó(   € V ^8„  d   QhR\         RR/# rC   rD   )r(   s   "r)   r*   r*     s   € ÷ 	qñ 	q´Sð 	q¸Tñ 	qr+   c                óx   €  ^ RI Hp V! V 4       R#   \         d    \        P	                  RT RR7        R# i ; i)a  Drop resources whose immutable mode derives from Hermes YOLO. Lazy import so approval-only
sessions never load computer-use; releasing on BOTH edges makes enabling YOLO replace a
standard backend and disabling it revoke a private unrestricted daemon immediately.)Úrelease_computer_use_sessionz<Failed to release permission-mode dependent resources for %sT©Úexc_infoN)Útools.computer_use.toolr¡   Ú	ExceptionrJ   Údebug)r6   r¡   s   & r)   Ú#_release_permission_mode_dependentsr§     s9   € ðqÝHá$ [Ö1øÜô qÜ�‰ÐSÐU`Ðkoˆ×pðqús   ‚ ’#9¸9c                ó4   € V ^8„  d   QhR\         R\        RR/# )r$   r6   Úenabledr%   Nrl   )r(   s   "r)   r*   r*     s!   € ÷ 5ñ 5¤3ð 5´ð 5¸$ñ 5r+   c                 óà   € V '       g   R # \         ;_uu_ 4        V'       d   \        P                  M\        P                  ! V 4       R R R 4       \	        V 4       R #   + '       g   i     L; irŠ   )r9   Ú_session_yolor�   Údiscardr§   )r6   r©   s   &&r)   Ú_set_session_yolor­     s=   € ßÙß	Žß%Œ×	Ò	¬=×+@Ñ+@Ð	@À+ÔN÷ 
ä'¨Ö4÷ 
�ús   ™/AÁA-	c                ó(   € V ^8„  d   QhR\         RR/# rC   rD   )r(   s   "r)   r*   r*     s   € ÷ )ñ )¤Sð )¨Tñ )r+   c                ó   € \        V R4       R# )z,Enable YOLO bypass for a single session key.TN©r­   rF   s   &r)   Úenable_session_yolor±     s   € ä�k 4Ö(r+   c                ó(   € V ^8„  d   QhR\         RR/# rC   rD   )r(   s   "r)   r*   r*     s   € ÷ *ñ *¤cð *¨dñ *r+   c                ó   € \        V R4       R# )z-Disable YOLO bypass for a single session key.FNr°   rF   s   &r)   Údisable_session_yolor´     s   € ä�k 5Ö)r+   c                ó(   € V ^8„  d   QhR\         RR/# rC   rD   )r(   s   "r)   r*   r*   !  s   € ÷ ñ œsð  tñ r+   c                ó4  € V '       g   R# \         ;_uu_ 4        \        P                  V R4       \        P	                  V 4       \
        P	                  V 4       \        P                  V R4       \        P                  V . 4       F$  pRVn        VP                  P                  4        K&  	  RRR4       \        V 4       R F,  w  r# \        \        P                  ! V4      V4      ! V 4       K.  	  R#   + '       g   i     LO; i  \         d     KS  i ; i)z7Remove all approval and yolo state for a given session.Nz0the session ended before the prompt was answered))ztools.code_kernelÚshutdown_kernels_for_owner)ztools.code_kernel_remoteÚ!shutdown_remote_kernels_for_owner)r9   r›   r;   r«   r¬   Ú_launch_yolo_appliedr–   rV   rt   rW   rX   r§   ÚgetattrÚ	importlibÚimport_moduler¥   )r6   rZ   ÚmoduleÚshutdowns   &   r)   Úclear_sessionr¿   !  sÐ   € çÙß	ŽÜ×Ñ˜k¨4Ô0Ü×Ñ˜kÔ*Ü×$Ñ$ [Ô1Ü�‰�[ $Ô'Ü$×(Ñ(¨°bÖ9ˆEð QˆEŒOØ�K‰K�O‰OÖñ	 :÷ 
ô (¨Ô4ó`Ñˆð	Ü”I×+Ò+¨FÓ3°XÔ>¸{ÖKó`÷ 
�ûô" ô 	Úð	ús   ™BC5Ã	&DÃ5D	ÄDÄDc                ó0   € V ^8„  d   QhR\         R\        /# r5   rl   )r(   s   "r)   r*   r*   :  s   € ÷ ,ñ ,¬ð ,´ñ ,r+   c                ó‚   € V '       g   R# \         ;_uu_ 4        V \        9   uuRRR4       #   + '       g   i     R# ; i)z?Return True when YOLO bypass is enabled for a specific session.FN)r9   r«   rF   s   &r)   Úis_session_yolo_enabledrÂ   :  s!   € çÙß	ŽØœmÑ+÷ 
��‹ús   ™	-­>	c                ó$   € V ^8„  d   QhR\         /# r#   ©ra   )r(   s   "r)   r*   r*   B  s   € ÷ Hñ H¬ñ Hr+   c                 ó,   € \        \        RR7      4      # )zEReturn True when the active approval session has YOLO bypass enabled.r    ©Údefault)rÂ   r   r2   r+   r)   Úis_current_session_yolo_enabledrÈ   B  s   € ä"Ô#:À2Ô#FÓGÐGr+   c                ó$   € V ^8„  d   QhR\         /# r#   rÄ   )r(   s   "r)   r*   r*   G  s   € ÷ ñ ”dñ r+   c                 óX   € \         '       g   \        4       '       d   R# ^ RIHp  V ! 4       # )z�CLI ``--yolo`` (process-scoped, frozen at import) or gateway ``/yolo``
(session-scoped). Hardline / deny-rule floors run BEFORE this everywhere.T©Úunattended_turn)Ú_YOLO_MODE_FROZENrÈ   Úgateway.session_finiterÌ   rË   s    r)   Ú_yolo_activerÏ   G  s"   € ÷ ÓÔ;×=Ò=ÙÝ6ÙÓÐr+   c                ó$   € V ^8„  d   QhR\         /# r#   ©rX   )r(   s   "r)   r*   r*   P  s   € ÷ ñ œñ r+   c                 ó˜   € ^ RI Hp Hp V ! 4       f	   \        Rr2M%V! 4       p\        P                  V\        4       4      p\        W#4       V# )uã  The permanent allowlist that governs the ACTIVE profile. Unscoped (single-profile process,
or the multiplexer's own launch profile) â†’ the module-level set tests and the CLI seed. A routed
profile (HERMES_HOME override) â†’ its own set, lazily loaded from ITS ``command_allowlist``: the
launch profile's "always" approvals must not pre-approve commands for a secondary, nor may a
secondary's "always" choice be written back into the launch profile's config. Callers hold ``_lock``.
©Úget_hermes_home_overrideÚhermes_home_keyr    )Úhermes_constantsrÔ   rÕ   Ú_permanent_approvedÚ_permanent_approved_by_homerœ   rX   Ú_sync_permanent_from_disk)rÔ   rÕ   ÚapprovedÚkeys       r)   Ú_permanent_setrÜ   P  sA   € ÷ KÙÓ!Ò)Ü+¨R‘#áÓˆÜ.×9Ñ9¸#¼s»uÓEˆÜ˜hÔ,Ø€Or+   c                ó4   € V ^8„  d   QhR\         R\        RR/# )r$   rÚ   rÛ   r%   N)rX   r7   )r(   s   "r)   r*   r*   a  s!   € ÷ /ñ /¬ð /´#ð /¸$ñ /r+   c                ó8  €  \        4       p\        P                  T\        4       4      pY$8X  d   R# T P                  YB,
          4       T P                  Y$,
          4       T\        T&   R#   \         d$   p\        P                  RTRR7        Rp?R# Rp?ii ; i)ac  Apply hand edits to ``command_allowlist`` made since the last sync. The gateway daemon
outlives any one session, so an entry the operator removed must stop being honoured now, not
at restart. Only the on-disk delta is applied: approvals this process made but could not save
survive. The config read is cached on the file signature. Callers hold ``_lock``.ú&Failed to load permanent allowlist: %sTr¢   N)	Ú_read_permanent_allowlistr¥   rJ   rK   Ú_permanent_baseline_by_homer/   rX   Údifference_updateÚupdate)rÚ   rÛ   Úon_diskrp   Úbaselines   &&   r)   rÙ   rÙ   a  s�   € ð
Ü+Ó-ˆô +×.Ñ.¨s´C³EÓ:€HØÔÙØ×Ñ˜xÕ1Ô2Ø‡O�O�GÕ&Ô'Ø'.Ô Ó$øô ô Ü�‰Ð?ÀÈTˆÔRÝûðús   ‚
A+ Á+BÁ6BÂBc                ó<   € V ^8„  d   QhR\         R\         R\        /# )r$   r6   r™   r%   rl   )r(   s   "r)   r*   r*   s  s!   € ÷ 7ñ 7œSð 7¬sð 7´tñ 7r+   c                ó<  a€ \        V4      p\        ;_uu_ 4        \        4       \        P	                  V \        4       4      ,          oRRR4       \        ;QJ d    V3R lV 4       F  '       g   K   R# 	  R# ! V3R lV 4       4      #   + '       g   i     LJ; i)zžSession-scoped or permanent approval. Accepts the canonical key and the legacy
regex-derived key so existing command_allowlist entries survive key migrations.Nc              3   ó,   <"  € T F	  qS9   x € K  	  R # 5irŠ   r2   )ro   ÚaliasrÚ   s   & €r)   rq   Úis_approved.<locals>.<genexpr>y  s   øé € Ð6©g U˜Ö «gùs   ƒTF)r   r9   rÜ   r›   r/   rX   Úany)r6   r™   ÚaliasesrÚ   s   && @r)   Úis_approvedrí   s  sg   ø€ ô $ KÓ0€Gß	ŽÜ!Ó#Ô&7×&;Ñ&;¸KÌËÓ&OÕOˆ÷ 
ç‹3Ô6©gÓ6�3Œ3Ð6Š3Ð6ˆ3Ô6©gÓ6Ó6Ð6÷ 
�ús   ›.BÂB	c                ó0   € V ^8„  d   QhR\         R\        /# )r$   r™   r%   rl   )r(   s   "r)   r*   r*   |  s   € ÷ Cñ C¬#ð C´$ñ Cr+   c                óÚ   € \        V 4      p\        ;_uu_ 4        \        ;QJ d    R V 4       F  '       g   K   RM	  RM! R V 4       4      uuRRR4       #   + '       g   i     R# ; i)zFPermanent approval only, with compatibility for migrated pattern keys.c              3   ó:   "  € T F  q\        4       9   x € K  	  R # 5irŠ   )rÜ   )ro   ré   s   & r)   rq   Ú+_is_permanently_approved.<locals>.<genexpr>€  s   é € ÐB¹'°œNÓ,Ö,»'ùs   ‚TFN)r   r9   rë   )r™   rì   s   & r)   Ú_is_permanently_approvedrò   |  s;   € ä# KÓ0€Gß	Žß‹sÑB¹'ÓB�s�sŠsÑB¹'ÓBÓB÷ 
��‹ús   šAºAÁA*	c                ó$   € V ^8„  d   QhR\         /# )r$   r™   rD   )r(   s   "r)   r*   r*   ƒ  s   € ÷ *ñ *¤3ñ *r+   c                óŽ   € \         ;_uu_ 4        \        4       P                  V 4       RRR4       R#   + '       g   i     R# ; i)z)Add a pattern to the permanent allowlist.N)r9   rÜ   r�   )r™   s   &r)   Úapprove_permanentrõ   ƒ  s$   € ç	ŽÜÓ×Ñ˜[Ô)÷ 
��Šús	   �3³A	c                ó$   € V ^8„  d   QhR\         /# ©r$   ÚpatternsrÑ   )r(   s   "r)   r*   r*   ‰  s   € ÷ #ñ #œSñ #r+   c                ó²   € \         ;_uu_ 4        \        4       pVP                  4        VP                  V 4       RRR4       R#   + '       g   i     R# ; i)z2Bulk-load permanent allowlist entries from config.N)r9   rÜ   re   rã   )rø   Ú	governings   & r)   Úload_permanentrû   ‰  s3   € ç	ŽÜ"Ó$ˆ	Ø�‰ÔØ×Ñ˜Ô"÷ 
��Šús   �,AÁA	c                óV   € V ^8„  d   QhR\         R\         R\        \         ,          RR/# )r$   r6   r]   Úkeysr%   N)r7   rd   )r(   s   "r)   r*   r*   ‘  s,   € ÷ -ñ -¤ð -¬cð -¼¼c½ð -Àtñ -r+   c           	     ó<  € V F‚  pVR9  d   K  \        W4       VR8X  g   K   \        V4       \        ;_uu_ 4        \        4       \        P                  \        4       \        4       4      ,
          pRRR4       \        X4       K„  	  R#   + '       g   i     L!; i)z^Persist a human ``session``/``always`` choice for each pattern key. ``once`` persists nothing.ÚalwaysN)Úsessionrÿ   )	rž   rõ   r9   rÜ   rá   r/   Ú_baseline_keyrX   Úsave_permanent_allowlist)r6   r]   rý   rÛ   Úgrantss   &&&  r)   Ú_persist_choicer  ‘  sm   € ãˆØÐ.Ô.ÙÜ˜Ô)Ø�XÖÜ˜cÔ"÷ –Ü'Ó)Ô,G×,KÑ,KÌMËOÔ]`Ó]bÓ,cÕc�÷ ä$ VÖ,ó ÷ —ús   ¼6BÂBc                ó$   € V ^8„  d   QhR\         /# r#   rÑ   )r(   s   "r)   r*   r*   £  s   € ÷ ñ ¤3ñ r+   c                 ó  € ^ RI Hp  V ! 4       pVP                  R4      p\        V\        4      pV'       d   ^ RIp VP                  V4      pVf   V'       g   . p\        V\        4      '       d;   \        ;QJ d    R V 4       F  '       g   K   RM	  RM! R V 4       4      '       d    \        P                  R4       \        4       # V'       d   \        P                  R4       \        V4      #   TP                   d    Rp Lºi ; i)	zY``command_allowlist`` of the active profile's config as a set (empty on malformed input).)Úload_config_readonlyÚcommand_allowlistNFc              3   óL   "  € T F  p\        V\        4      '       * x € K  	  R # 5irŠ   )Ú
isinstancer7   )ro   Úitems   & r)   rq   Ú,_read_permanent_allowlist.<locals>.<genexpr>²  s   é € Ð'RÉcÀd¬J°t¼SÓ,A×(AÑ(AËcùs   ‚"$TzBIgnoring malformed command_allowlist; configure a list of strings.zKRecovered legacy string command_allowlist; re-save it as a list of strings.)Úhermes_cli.configr  r/   r
  r7   Úhermes_yamlÚ	safe_loadÚ	YAMLErrorrd   rë   rJ   rK   rX   )r  ÚconfigÚrawÚlegacyÚyamls        r)   rà   rà   £  sÃ   € å6Ù!Ó#€FØ
�*‰*Ð(Ó
)€CÜ˜œSÓ!€Fßã"ð	Ø—.‘. Ó%ˆCð ‚{Ÿ6ØˆÜ�cœ4× Ò §C£CÑ'RÉcÓ'R§C§C¢CÑ'RÉcÓ'R×$RÒ$RÜ�‰Ð[Ô\Ü‹uˆßÜ�‰ÐdÔeÜˆs‹8€Oøð �~‰~ô 	ØŠCð	ús   ¼C2 Ã2DÄDc                ó$   € V ^8„  d   QhR\         /# r#   rD   )r(   s   "r)   r*   r*   Ã  s   € ÷ Kñ K”sñ Kr+   c                  ó6   € ^ RI Hp Hp V ! 4       f   R# V! 4       # )é    rÓ   r    )rÖ   rÔ   rÕ   rÓ   s     r)   r  r  Ã  s   € ßJÙ)Ó+Ò3ˆ2ÐJ¹Ó9JÐJr+   c                ó$   € V ^8„  d   QhR\         /# r#   rÑ   )r(   s   "r)   r*   r*   È  s   € ÷ ñ ¤#ñ r+   c                 ó,  €  \        4       p \        V 4       \        ;_uu_ 4        \        V 4      \        \        4       &   RRR4       V #   + '       g   i     T # ; i  \         d+   p\        P                  RT4       \        4       u Rp?# Rp?ii ; i)z‹Load ``command_allowlist`` from config and sync it into the approval state
so is_approved() honors 'always' choices from previous sessions.Nrß   )	rà   rû   r9   rX   rá   r  r¥   rJ   rK   )rø   rp   s     r)   Úload_permanent_allowlistr  È  si   € ðÜ,Ó.ˆÜ�xÔ ßŽUÜ;>¸x»=Ô'¬«Ñ8÷ àˆ÷ ŽUàˆûÜô Ü�‰Ð?ÀÔCÜ‹u�ûðús:   ‚#A ¥A
Á 	A Á
A	ÁA ÁA ÁBÁ)BÂBÂBc                ó$   € V ^8„  d   QhR\         /# r÷   rÑ   )r(   s   "r)   r*   r*   Ö  s   € ÷ :ñ :¤sñ :r+   c                óL  €  ^ RI HpHp V! 4       p\        VP	                  R. 4      ;'       g    . 4      p\
        ;_uu_ 4        \        4       p\        P	                  V\        4       4      pV\        V 4      V,
          ,          p\        V4      VR&   V! V4       \        V4      \        V&   \        4       pVP                  4        VP                  V4       RRR4       R#   + '       g   i     R# ; i  \         d"   p	\        P                  RT	4        Rp	?	R# Rp	?	ii ; i)aˆ  Save permanently allowed command patterns to config, reconciling with the file.

``command_allowlist`` is a file an operator edits by hand; removing an entry
there is the documented way to withdraw a standing approval. This process read
it once at import and ``load_permanent`` only ever unions, so writing the
in-memory set straight back deleted entries added on disk since import and
resurrected the ones removed. The result written is ``what is on disk now``
plus ``what this process approved since its own baseline``; revoked entries are
also dropped from the governing permanent set so ``is_approved()`` stops
honouring them (``_sync_permanent_from_disk`` does the same on every check).

``patterns`` may only ADD: an entry left out of it is not removed, because the
on-disk list wins for anything this process did not approve itself. Remove
entries by editing ``command_allowlist`` in config.yaml.
)Úload_configÚsave_configr  NzCould not save allowlist: %s)r  r  r  rX   r/   r9   r  rá   ÚsortedrÜ   re   rã   r¥   rJ   rK   )
rø   r  r  r  rä   rÛ   rå   Úmergedrú   rp   s
   &         r)   r  r  Ö  s×   € ð :ß>Ù“ˆÜ�f—j‘jÐ!4°bÓ9×?Ð?¸RÓ@ˆßŽUÜ“/ˆCÜ2×6Ñ6°s¼C»EÓBˆHØ¤ H£°Õ 8Õ9ˆFÜ*0°«.ˆFÐ&Ñ'Ù˜ÔÜ/2°6«{Ô'¨Ñ,Ü&Ó(ˆIØ�O‰OÔØ×Ñ˜VÔ$÷ �U�UŠUûô ô :Ü�‰Ð5°q×9Ò9ûð:ús;   ‚,C7 ¯C7 ÁBC#ÃC7 Ã#C4	Ã.C7 Ã4C7 Ã7D#ÄDÄD#c                ó0   € V ^8„  d   QhR\         R\        /# r5   rl   )r(   s   "r)   r*   r*   ú  s   € ÷ yñ y´sð y¼tñ yr+   c                ót   € \         ;'       g,    \        V 4      ;'       g    \        P                  ! 4       R8H  # )uô   Canonical three-source bypass check: process ``--yolo`` (frozen at import), the
session-scoped gateway ``/yolo`` toggle, ``approvals.mode: off``. Pure bypass
sub-expression only â€” hardline blocklist / permanent allowlist are the caller's job.Úoff)rÍ   rÂ   r   Ú_get_approval_moderF   s   &r)   Ú%is_approval_bypass_active_for_sessionr%  ú  s0   € ô ×wÐwÔ!8¸Ó!E×wÐwÔIY×IlÒIlÓInÐrwÑIwÐxr+   c                ó$   € V ^8„  d   QhR\         /# r#   rÄ   )r(   s   "r)   r*   r*     s   € ÷ Vñ V¤4ñ Vr+   c                 ó,   € \        \        RR7      4      # )z?Return whether the current approval context has bypass enabled.r    rÆ   )r%  r   r2   r+   r)   Úis_approval_bypass_activer(    s   € ä0Ô1HÐQSÔ1TÓUÐUr+   c                ó$   € V ^8„  d   QhR\         /# r#   )rw   )r(   s   "r)   r*   r*     s   € ÷ /ñ /”4ñ /r+   c                  ó   € R RRR/# )rÚ   TÚmessageNr2   r2   r+   r)   Ú	_approvedr,    s   € Ø˜˜i¨Ð.Ð.r+   ÚcommandÚcodeÚactionc                ó<   € V ^8„  d   QhR\         R\         R\         /# )r$   ÚoutcomeÚnounr%   rD   )r(   s   "r)   r*   r*     s!   € ÷ 1ñ 1œ3ð 1¤cð 1¼#ñ 1r+   c                 ó    € ^ RI HpHp V! V! 4       4      pV \        9   d   RV  2MRpV\        9   d   \        RV 24      MTp\        WVVR7      # )r  )Ú_get_approval_timeoutÚformat_approval_windowzapproval.summary.zapproval.summary.defaultzapproval.noun.)r2  Úwindow)Útools.approval_contextr4  r5  Ú_USER_SUMMARY_OUTCOMESÚ_USER_SUMMARY_NOUNSr   )r1  r2  r4  r5  r6  rÛ   Ú	noun_texts   &&     r)   Ú_user_summaryr;    sS   € ßTÙ#Ñ$9Ó$;Ó<€FØ+2Ô6LÔ+LÐ˜g˜YÑ
'ÐRl€CØ.2Ô6IÔ.I”�N 4 &Ð)Ô*Èt€IÜˆS¨Ô0Ð0r+   r2  c                ó`   € V ^8„  d   QhR\         R\         R\         R\         R\         R\        /# )r$   r+  r™   Údescriptionr1  r2  r%   r�   )r(   s   "r)   r*   r*     s@   € ÷ Cñ C”Sð C¬#ð C¼Cð CÌ#ð CÔUXð CÜñCr+   c               ó8   € RRRV RVRVRVRRR\        W44      /VC# )	zžStandard non-consent result: the agent must not retry or rephrase. ``user_summary`` is the
one-line human reading of the same outcome (see ``_user_summary``).rÚ   Fr+  r™   r=  r1  Úuser_consentÚuser_summary)r;  )r+  r™   r=  r1  r2  Úextras   &$$$$,r)   Ú_deniedrB    s=   € ð ˜˜y¨'°=À+Ø˜;¨	°7¸NÈEØœM¨'Ó8ðCà<AðCð Cr+   c                óH   € V ^8„  d   QhR\         R\         R\         R\        /# )r$   r+  r™   r=  r%   r�   )r(   s   "r)   r*   r*   &  s.   € ÷ kñ k”cð k¬3ð k¼Sð kÄTñ kr+   c               ó   € RRRV RVRV/# )zKNon-interactive block (cron / -q / unattended / no-human): no consent keys.rÚ   Fr+  r™   r=  r2   )r+  r™   r=  s   &$$r)   Ú_blockedrE  &  s   € à˜˜y¨'°=À+È}Ð^iÐjÐjr+   c                ó<   € V ^8„  d   QhR\         R\         R\        /# )r$   r6   r=  r%   r�   )r(   s   "r)   r*   r*   +  s&   € ÷ bñ b¤ð b´#ð b¼$ñ br+   c                ó,   € \        V 4       RRRRRRRV/# )zrA human approval (incl. ESCALATE-then-approve or a smart-DENY owner
override) resets the consecutive-denial tally.rÚ   Tr+  NÚuser_approvedr=  )rG   )r6   r=  s   &&r)   Ú_user_approvedrI  +  s$   € ô �;ÔØ˜˜i¨¨ÀÀmÐU`ÐaÐar+   c                ó$   € V ^8„  d   QhR\         /# )r$   r6   rD   )r(   s   "r)   r*   r*   2  s   € ÷ 4ñ 4¤Cñ 4r+   c                 ó†   € \         ;_uu_ 4        \        P                  V 4      uuR R R 4       #   + '       g   i     R # ; irŠ   )r9   rP   r/   rF   s   &r)   Ú_gateway_notify_cbrL  2  s!   € ß	ŽÜ"×&Ñ& {Ó3÷ 
��‹ús	   �/¯A 	c                óœ   € V ^8„  d   QhR\         R\         R\         R\         R\        \         ,          R\         R,          R\        R	\        /# )
r$   r6   r-  r=  r™   Úpattern_keysÚbodyNÚsmart_deniedr%   )r7   rd   ra   rw   )r(   s   "r)   r*   r*   7  sQ   € ÷ !ñ !¤sð !¼ð !Ì#ð !Ü!$ð!Ü48¼µIð!ÜEHÈ4ÅZð!ä"&ð!ä+/ñ!r+   c               ó~  € RVRV/pV P                   '       d   WXR&   W8R&   V'       d   VP                  RRR7       \        W4       V P                   '       g   RRRVR	R
RVRVRRV RV R2/# T;'       g    RV R2pRRRVR	RRRRVRVRRV RV RV P                   R2/p	V'       d   V	P                  RRR7       V	# )a
  Queue an approval nobody can answer right now (no gateway notifier, no CLI panel) for
``/approve`` / ``/deny`` review. Command/code gates return the backward-compatible
``pending_approval`` shape (``pattern_keys`` + STOP text); the action gate ``approval_required``.r-  r™   rN  r=  TF)rP  Úallow_permanentrÚ   ÚstatusÚapproval_requiredr+  u-   âš ï¸� This action is potentially dangerous (z2). Asking the user for approval.

**Target:**
```
ú
```z**Command:**
```
Úpending_approvalÚapproval_pendingu   âš ï¸� z!. Asking the user for approval.

z2

STOP: do NOT re-run, rephrase, or re-issue this u�    â€” each variant sends the user ANOTHER approval card. Wait for the user's decision; if this turn must end, report that approval is pending.)Úpending_keysrã   r—   r2  )
Úspecr6   r-  r=  r™   rN  rO  rP  Úpendingrf   s
   &&$$$$$$  r)   Ú_pending_resultr[  7  s  € ð ˜' =°+Ð>€GØ××ÐØ".�ÑØ(ˆMÑßØ�‰ D¸%ˆÔ@Ü�;Ô(Ø××Ðà˜˜}¨k¸8ÐEXØ�w ¨{ØÐGÈÀ}ð UNØNUÈYÐV[ð]ð
ð 	
ð ×7Ð7Ð(¨¨	°Ð7€Dà�E˜=¨+°xÐASØ˜D )¨W°mÀ[ØØ�k�]Ð"EÀdÀVð L?Ø?C¿y¹y¸kð JWðWð		€F÷ Ø�‰ 4¸ˆÔ?Ø€Mr+   T)Úfrozenc                   óp   a € ] tR tRt o RtV 3R lR ltV 3R lR lt]V 3R lR l4       tV 3R	 lt	R
t
V tR# )Ú_Unattendedi]  zGOne non-interactive context and the text every gate uses to explain it.c                ó    <€ V ^8„  d   QhRS[ /# r#   rD   )r(   Ú__classdict__s   "€r)   r*   Ú_Unattended.__annotate__f  s   ø€ ÷ Nñ N‘cñ Nr+   c                óH   € \        \        R V P                   R24      ! 4       # )Ú_get_Ú_approval_mode)rº   r   Úname©Úselfs   &r)   ÚmodeÚ_Unattended.modef  s    € äÔ'¨5°·±°¸>Ð)JÔKÓMÐMr+   c                ó2   <€ V ^8„  d   QhRS[ RS[ RS[ RS[ /# )r$   Úsubjectr2  Úadvicer%   rD   )r(   r`  s   "€r)   r*   ra  j  s/   ø€ ÷ Fñ F¡Sð F±3ð FÁð FÉñ Fr+   c               óh   € R V RV P                    RV RV RV P                   RV P                   R2# )ú	BLOCKED: z but z. z
 To allow Ú z, set approvals.z: approve in config.yaml.)ÚclauseÚscopeÚcfg_key)rg  rk  r2  rl  s   &&$$r)   Úblock_messageÚ_Unattended.block_messagej  sL   € Ø˜G˜9 E¨$¯+©+¨°b¸¸À
È4È&ÐPQÐRV×R\ÑR\ÐQ]ð ^Ø!Ÿ\™\˜NÐ*CðEð 	Fr+   c                ó    <€ V ^8„  d   QhRS[ /# r#   rD   )r(   r`  s   "€r)   r*   ra  o  s   ø€ ÷ \ñ \™3ñ \r+   c                ó¤   € V P                   ^ ,          P                  4        V P                   R,           RV P                   RV P                   R2# )r  :é   NNz-. Use normal tools instead, or set approvals.z: approve only if Ú.)rp  Úupperrr  Útrustrf  s   &r)   Ú	exec_tailÚ_Unattended.exec_tailn  sN   € à—;‘;˜q•>×'Ñ'Ó)Ð*¨4¯;©;°r­?Ð*;ð <-Ø-1¯\©\¨NÐ:LÈTÏZÉZÈLÐXYð[ð 	\r+   c                óV   <€ V ^8„  d   Qh/ S[ ;R&   S[ ;R&   S[ ;R&   S[ ;R&   S[ ;R&   # )r$   re  rr  rp  rq  rz  rD   )r(   r`  s   "€r)   r*   ra  ]  sA   ø‡ ‚ ñ �Iñ ñ �Lñ	 ñ
 �Kñ ñ �Jñ ñ �Jò r+   r2   N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__rh  rs  Úpropertyr{  Ú__annotate_func__Ú__static_attributes__Ú__classdictcell__©r`  s   @r)   r^  r^  ]  s=   ø‡ € áQ÷Nð N÷Fð Fð ÷\ó ð\÷% ƒ r+   r^  Úsingle_queryÚsingle_query_modez@single-query mode (-q) runs without a user present to approve itzin single-query modez.this single-query run is intentionally trustedÚcronÚ	cron_modez2cron jobs run without a user present to approve itzin cron jobsz*this cron profile is intentionally trustedc                ó:   € V ^8„  d   QhR\         \        ,          /# r#   )rd   r^  )r(   s   "r)   r*   r*     s   € ÷ ñ œd¤;Õ/ñ r+   c            	     ó  € . p \        4       '       d   V P                  \        4       \        4       '       d   V P                  \        4       V # \        4       '       d+   V P                  \        RRR\        4        R2RR4      4       V # )zàActive unattended contexts in evaluation order: single-query first (``hermes chat -q``
exports HERMES_INTERACTIVE=1 but nobody answers); cron beats a platform marker because
cron binds the platform for delivery routing only.Ú
unattendedÚunattended_modez-this session runs on an unattended platform (z$) with no user present to approve itzon unattended platformsz2sessions on this surface are intentionally trusted)r   ÚappendÚ_SINGLE_QUERY_CTXr	   Ú	_CRON_CTXr   r^  r   )Úcontextss    r)   Ú_unattended_contextsr”    sƒ   € ð €HÜ(×*Ò*Ø�‰Ô)Ô*Ü ×"Ò"Ø�‰œ	Ô"ð €Oô 
2×	3Ò	3Ø�‰œØÐ+ðÜ%Ó'Ð(Ð(LðNà%Ð'[ó	
ô 	ð €Or+   c                óJ   € V ^8„  d   QhR\         R\        R\        R,          /# )r$   r-  Úctxr%   N)r7   r^  rw   )r(   s   "r)   r*   r*   ’  s%   € ÷ ñ œcð ¬ð ¼¸t½ñ r+   c                óø   a€ SP                  4       R8w  d   R# R V3R llp\        V 4      w  r4pV'       dC   \        V4      '       g2   V! RV R24      pSP                  R8X  d   VP	                  WER7       V# R# )	zRDeny-mode handling for one unattended context (cron / -q / webhook); None = allow.ÚdenyNc                ó0   € V ^8„  d   QhR\         R\        /# )r$   rk  r%   r�   )r(   s   "r)   r*   Ú&_unattended_deny.<locals>.__annotate__—  s   € ÷ Nñ N”sð Nœtñ Nr+   c           	      ó4   <€ R RRSP                  V RRR7      /# )rÚ   Fr+  údangerous commandsú6Find an alternative approach that avoids this command.©r2  rl  )rs  )rk  r–  s   &€r)   ÚblockÚ_unattended_deny.<locals>.block—  s3   ø€ Ø˜E 9¨c×.?Ñ.?ØÐ.ØKð /@ó /Mð Nð 	Nr+   úCommand flagged as dangerous (Ú)rˆ  ©r™   r=  )rh  r   rò   re  rã   )r-  r–  rŸ  Úis_dangerousr™   r=  rf   s   &f     r)   Ú_unattended_denyr¥  ’  sv   ø€ à
‡x�xƒz�VÔÙ÷Nð Nô
 .FÀgÓ-NÑ*€L˜{ßÔ4°[×AÒAÙÐ7¸°}ÀAÐFÓGˆØ�8‰8�~Ô%Ø�M‰M kˆMÔKØˆÙr+   c                   ó,   a € ] tR tRt o V 3R ltRtV tR# )Ú	_GateSpeci«  c                óž   <€ V ^8„  d   Qh/ S[ ;R&   S[;R&   S[;R&   S[;R&   S[;R&   S[ ;R&   S[ ;R&   S[ ;R&   S[ ;R	&   S[ ;R
&   S[ ;R&   # )r$   r2  Ú	transportrH  Ú
redact_clirX  Únotify_failedÚgateway_refusedÚtransport_deniedÚcli_timeoutÚ
cli_deniedÚ	smart_logrl   )r(   r`  s   "€r)   r*   Ú_GateSpec.__annotate__«  sŽ   ø‡ ‚ á
�Iñ ñ �Oñ ñ Ññ	 ñ
 Ññ ñ Ññ ñ Ññ ñ Ññ ñ Ññ ñ Ññ ñ �Oñ ñ �Nò r+   r2   N)r~  r  r€  r�  r„  r…  r†  r‡  s   @r)   r§  r§  «  s   ø‡ ‡ „ r+   r§  a   The user has NOT consented to this action. Do NOT retry this command, do NOT rephrase it, and do NOT attempt the same outcome via a different command. Stop the current workflow and wait for the user to respond before taking any further destructive or irreversible action.zŠ The user has NOT consented to this action. Do NOT retry it, do NOT rephrase it, and do NOT attempt the same outcome via a different path.z?BLOCKED: Failed to send approval request to user. Do NOT retry.z+BLOCKED: Command {reason}.{reason_addendum}z{timeout_addendum}{breaker}z¾BLOCKED: User denied this command through the selected approval transport. The user has NOT consented to this action. Do NOT retry or attempt the same outcome through another route.{breaker}z1BLOCKED: Command timed out without user response.z! Silence is not consent.{breaker}z"BLOCKED: User denied this command.ú	{breaker}z9Smart approval: auto-approved '{command}' ({description}))r2  r©  rH  rª  rX  r«  r¬  r­  r®  r¯  r°  zLBLOCKED: Failed to send execute_code approval request to user. Do NOT retry.zçBLOCKED: execute_code script {reason}.{reason_addendum} The user has NOT consented to running this code. Do NOT retry, do NOT rephrase the script, and do NOT attempt the same outcome via a different tool.{timeout_addendum}{breaker}zfBLOCKED: User denied execute_code through the selected approval transport. The user has NOT consented.z0BLOCKED: Action timed out without user response.uŒ   BLOCKED: User denied execute_code script execution (matched '{description}'). Do NOT retry â€” the user has explicitly rejected it.{breaker}zDSmart approval: auto-approved execute_code for session {session_key}z*BLOCKED: Action {reason}.{reason_addendum}z{timeout_addendum}ú Silence is not consent.u‡   BLOCKED: User denied this potentially dangerous action (matched '{description}'). Do NOT retry â€” the user has explicitly rejected it.c                ó¾   € V ^8„  d   QhR\         R\        R\        R\        R\        \        ,          R\        R\        R\        \
        R	,          \        3,          /# )
r$   rY  r-  r=  r™   rN  r6   Úhuman_presentr%   N)r§  r7   rd   ra   Útuplerw   )r(   s   "r)   r*   r*   ü  sZ   € ÷ ñ ”ið ¬#ð ¼Cð Ìcð Ü"¤3�iðÜ69ðä#ðä(-¬d°T­k¼4Ð.?Õ(@ñr+   c          	     ó4  € \        WW4V4      pVR8X  dO   \        V4       \        P                  V P                  P                  VR,          W%R7      4       RRRRRRR	V/R
3# VR8w  d   R# \        V4       V'       d   R# RR
RRV R\        V4       2RR/R3# )u  Guardian-LLM step -> ``(result, smart_denied_for_owner)``: a result ends the gate;
``smart_denied_for_owner`` means an interactive owner may still override the DENY for this
one operation (once/deny only, nothing persists).

APPROVE approves this command only â€” pattern-level persistence would let one benign
command suppress review of later commands in the same broad detector category. A DENY
counts toward the denial breaker even when an owner may override it. ESCALATE follows the
normal, potentially persistent manual behavior.
Úapprove:Né<   N)r-  r=  r6   rÚ   Tr+  NÚsmart_approvedr=  Fr˜  zBLOCKED by smart approval: z@. The command was assessed as genuinely dangerous. Do NOT retry.rP  ©NF)NT)r   rG   rJ   r¦   r°  r(   rA   rM   )rY  r-  r=  r™   rN  r6   rµ  Úverdicts   &&&&&&$ r)   Ú_smart_gater½  ü  sÄ   € ô ˜W°;ÈkÓZ€GØ�)ÔÜ�{Ô#Ü�‰�T—^‘^×*Ñ*°7¸3µ<È[Ð*ÓrÔsØ˜D )¨TÐ3CÀTÈ=ÐZeÐfÐhmÐmÐmØ�&ÔØÐÜ�;ÔßØÐð 	�EØÐ1°+°ð ?/Ü/GÈÓ/TÐ.UðWà˜ðð ðð r+   ÚsmartÚpending_bodyc                ó²   € V ^8„  d   QhR\         R\        R\        R\        R\        \        ,          R\        R\        R\        R	\        R
\        R\        /# )r$   rY  r-  r=  r™   rN  r6   Úis_cliÚ
is_gatewayÚis_askr¾  r%   )r§  r7   rd   ra   rw   )r(   s   "r)   r*   r*     sz   € ÷ Fñ Fœ)ð F´ð FÄ3ð FÜ!$ðFÜ48¼µIðFä!$ðFäAEðFäSWðFô !ðFô *.ðFô NRñFr+   c               ó  a aaaaa€ ^ RI Hp RoV
'       d0   \        S TSSSST;'       g    T;'       g    T	R7      w  poVe   V# V'       d   V! 4       MRpS'       * pR VVVV 3R llpR VVVVV 3R llpS P                  '       d†   \	        TSSSSS'       * TV'       g	   V	'       d   \
        P                  ! 4       MR	R
7      p\        VSSR7      w  ppVe   V# Ve.   VR8X  d   \        S4       V! S P                  R4      # V! V4      # V'       g
   V	'       Ed€   V! V4      pV! S4      p\        S4      pVEe$   RVRSRSRVRS'       * RS'       * /pS'       d   RVR&   \        SVVRR7      pVP                  R4      '       d%   \        S P                  SSRS P                  R7      # VR,          VP                  R4      ppVP                  R4      '       d$   V! S P                   RRVR,           R2RRRR 7      # VR!,          '       g   V! S P                   R"R#RR$VR 7      # Ve   VR8X  d'   T! S P                   RR%V'       d   R&V R'2MRRVR 7      # V! V4      # \#        WvVR(7      '       g*   S P$                  '       g   TSpp\'        S SVVSSVSR)7      # TSppS P(                  '       d   V! V4      pV! S4      p\+        VVS\-        S4      SR	R*7      p\
        P.                  ! R// VB  \1        VVVSVR+7      p\
        P.                  ! R0/ VBRV/B  VR"8X  d   V! S P2                  R"4      # VR8X  d(   V! S P                   RR,\5        VR-R.4       R2RR$RR 7      # VR8X  d   V! S P6                  R4      # V! V4      # )1aƒ  Ask a human (after the optional guardian-LLM step) and turn the answer into the gate result.

``pattern_keys`` are what :func:`_persist_choice` stores on session/always; a smart-DENY
owner override reduces every surface to once/deny and persists nothing. ``pending_body`` is a thunk, built only once a human is
actually asked, so a smart APPROVE never pays for redacting a large script.
©Úredact_sensitive_textF)rµ  Nc                ó<   € V ^8„  d   QhR\         R\         R\        /# )r$   Útemplater1  r%   r�   )r(   s   "r)   r*   Ú%_human_decision.<locals>.__annotate__1  s&   € ÷ Añ A”sð A¤Sð A´Dñ Ar+   c                 óÎ   <€ R pRV 9   d   \        S4      pVP                  RR4      pRV9   d   RV/M/ p\        V P                  ! R
RSRV/VB 3RSRSRVR	S	P                  /VB # )r    r²  Údeny_reasonNr_   r=  Úbreakerr™   r1  r2  r2   )rM   r;   rB  r(   r2  )
rÈ  r1  ÚfmtrÌ  rË  rA  r=  r™   r6   rY  s
   &&,   €€€€r)   r˜  Ú_human_decision.<locals>.deny1  s•   ø€ ØˆØ˜(Ô"Ü.¨{Ó;ˆGØ—g‘g˜m¨TÓ2ˆØ08¸C´� Ñ,ÀRˆÜ�x—’ÑW°;ÐWÈÐWÐSVÑWñ AØ#.ðAØ<GðAà&ðAà-1¯Y©YðAà:?ñAð 	Ar+   c                ó0   € V ^8„  d   QhR\         R\        /# )r$   r]   r%   r�   )r(   s   "r)   r*   rÉ  ;  s   € ÷ ñ ”cð œdñ r+   c                 ó~   <€ S'       g   \        SV S4       SP                  '       d   \        SS4      # \        4       # rŠ   )r  rH  rI  r,  )r]   r=  rN  r6   rP  rY  s   &€€€€€r)   ÚgrantÚ_human_decision.<locals>.grant;  s3   ø€ çÜ˜K¨°Ô>Ø××ÐÜ! +¨{Ó;Ð;Ü‹{Ðr+   Úcli)r-  r=  r™   rN  r6   Úallow_sessionrR  Úsurfacer£  r˜  Údeniedr-  r™   rN  r=  rR  rÔ  TrP  Úgateway)rÕ  r«  ©r™   r=  r1  r2  r]   r_   rt   z1approval was withdrawn before the user answered (r¢  r    )r_   Úreason_addendumÚtimeout_addendumrË  ÚresolvedÚtimeoutztimed out without user responser³  zdenied by userz Reason given by the user: "z".)rÁ  Úapproval_callbackÚ	notify_cb)r-  r=  r™   rN  rO  rP  )r-  r=  r™   rN  r6   rÕ  )rR  rP  rÝ  zRwas not approved: the approval prompt could not be delivered or was not answered (rk   z	no answer)Úpre_approval_request)Úpost_approval_response)Úagent.redactrÆ  r½  r©  r   r   Úgateway_approval_surfacer   rA   r­  rL  r   r/   rB  r«  r2  r¬  r   rX  r[  rª  rw   rd   Ú_fire_approval_hookr   r®  rº   r¯  )rY  r-  r=  r™   rN  r6   rÝ  rÁ  rÂ  rÃ  r¾  r¿  rÆ  rf   rR  r˜  rÑ  Úattemptr]   rÖ  Údisplay_commandÚdisplay_descriptionrÞ  rc   ÚdecisionrË  Úprompt_commandÚprompt_descriptionÚhook_kwargsrP  s   f$dddd$$$$$$                 @r)   Ú_human_decisionrë    sú  ý€ õ 3à€LßÜ*¨4°¸+À{ÐT`Ø+6Àf×FdÐFdÐPZ×FdÐFdÐ^dô fÑˆ�àÒØˆMß%1‘<”>°t€LØ&Ô&€O÷Aó A÷ô ð ‡~‡~€~Ü2Ø¨À+Ð\hØ#°|Ô3CÐUdßDN×RXÔ$×=Ò=Ô?Ð_dô
ˆô
 +¨7ÀÐYdÔe‰ˆ�ØÒØˆMØÒØ˜ÔÜ˜{Ô+Ù˜D×1Ñ1°8Ó<Ð<Ù˜“=Ð ÷ —V�Vñ 0°Ó8ˆÙ3°KÓ@ÐÜ& {Ó3ˆ	ØÓ ð ˜?¨M¸;Ø ¨mÐ=PØ! |Ô#3Ø \Ô!1ð	ˆD÷ Ø'+��^Ñ$Ü.¨{¸IÀtÐU^Ô_ˆHØ�|‰|˜O×,Ò,Ü˜t×1Ñ1¸{Ø+6ÀÐVZ×V_ÑV_ôað að
 #+¨8Õ"4°h·l±lÀ8Ó6L�KˆFØ�|‰|˜K×(Ò(ñ ˜D×0Ñ0°+Ø%VÐW_Ð`kÕWlÐVmÐmnÐ#oØ,.ÀÐQUôWð Wð ˜J×'Ô'Ù˜D×0Ñ0°)ÐDeØ,.ÐA[Ø(3ô5ð 5ð Š~ ¨6Ô!1Ù˜D×0Ñ0°(ÐCSß_jÐ/KÈKÈ=ÐXZÑ-[ÐprØ-/¸[ôJð Jñ ˜“=Ð ô
 4ØÈ)÷
ó 
ð ×$×$Ð$Ø7>ÀÐ!4�Ü"Ø�k¨?ÐH[ÐitØ)°È<ôð ð *1°+Ð&€NØ‡‡€Ù.¨wÓ7ˆÙ2°;Ó?ÐÜ˜~Ð;MÐ[fÜ$(¨Ó$6ÀKÐY^ô`€Kä×(Ò(ÑOÀ;ÒOÜ& ~Ð7IÐ[jØ4@ÐTeôg€Fä×(Ò(Ñ`À[Ñ`ÐY_Ó`Ø�ÔÙ�D×$Ñ$ iÓ0Ð0Ø�Ôñ �D×(Ñ(¨+ðÜ& v¨w¸ÓDÐEÀQðHà$&Ð9SÐaeôgð 	gð �Ôñ �D—O‘O XÓ.Ð.Ù�‹=Ðr+   c                ó$   € V ^8„  d   QhR\         /# r#   )r¶  )r(   s   "r)   r*   r*   ¥  s   € ÷  9ñ  9¬ñ  9r+   c                ó@  € \        V 4      p \        4       \        4       r!\        R4      p\	        4       '       g   \        4       '       d   R;p;r#MLV'       dE   \        4       '       d5   \        \        4       4      e   \        4       \        P                  9   d   RpWW#3# )uJ  ``(approval_callback, is_cli, is_gateway, is_ask)`` for the current context.

Single-query ``-q`` and cron clear the presence trio: ``hermes chat -q`` exports
HERMES_INTERACTIVE=1 for sudo prompts, and a gateway sets HERMES_EXEC_ASK=1 at startup and
passes its environ to every external cron worker (#110932) â€” in neither can a human answer
the card, so the gate must resolve from ``approvals.<ctx>_mode`` instead of parking on a
pending approval. Unattended *platforms* keep ``is_ask`` only while a client on the session
could actually answer: ``/v1/runs`` and streaming chat completions bridge an approval
notifier (``approval.request`` â†’ ``POST /v1/runs/{id}/approval``), so on api_server a
registered notifier is the discriminator. webhook/msgraph_webhook turns run through the
generic TurnRunner lane, which registers a notifier for *every* turn â€” but those adapters
render no approval surface and the inbound lane has no reader, so there ``is_ask`` drops
regardless and the unattended branch resolves from ``approvals.unattended_mode`` instead of
parking an unanswerable card (#100532).ÚHERMES_EXEC_ASKF)r   r   r
   r   r   r	   r   rL  r   r   r   Ú"_NOTIFIER_BLIND_APPROVAL_PLATFORMS)rÝ  rÁ  rÂ  rÃ  s   &   r)   Ú	_presencerð  ¥  s‰   € ô 7Ð7HÓIÐÜ,Ó.Ô0LÓ0NˆJÜÐ.Ó/€FÜ(×*Ò*Ô.G×.IÒ.IØ',Ð,ˆÐ,�˜fß	Ô<×>Ò>Ü#Ô$;Ó$=Ó>ÒFÜ)Ó+Ô/?×/bÑ/bÔbð ˆØ jÐ8Ð8r+   rÝ  rk  úflagged actionsrl  ú5Find an alternative approach that avoids this action.Úcron_deny_messageÚsingle_query_deny_messageÚunattended_deny_messageÚfail_closed_when_no_humanÚno_human_block_messagec                ó´   € V ^8„  d   QhR\         R\         R\         R\         R\         R\         R\         R\         R	\         R
\         R\        R\         R\        /# )r$   r™   r=  Údisplay_targetrk  r2  rl  ró  rô  rõ  Úautoapprove_log_prefixrö  r÷  r%   ©r7   ra   rw   )r(   s   "r)   r*   r*   È  s™   € ÷ Fñ FÜðFÜ&)ðFÜ;>ðFäðFä ðFô ðFô ð	Fô =@ð	Fô `cð	Fô
  ðFô
 =AðFô
 cfðFô 
ñFr+   c                óž  € \        4       '       g   \        P                  ! 4       R8X  d   \        4       # \	        4       p\        WÐ4      '       d   \        4       # \        V4      w  r>ppV'       EgF   V'       Eg=   V'       Eg4   W V3pRVRVRV	/p\        4        F¼  pVP                  4       R8X  dp   VVP                  ,          pV'       g+   VP                  R8X  d   VP                  RV R2RR	R
7      pMV'       g   VP                  WEVR
7      p\        VWR7      u # VP                  R8X  d%   \        P                  ! R.VO5!   \        4       u #  M=	  V'       d4   \        P                  ! R.VO5!   \        T;'       g    RV R2WR7      # \        P                  ! R.VO5!   \        4       # \        \        W!V V .VW>VVR7
      # )uÁ  Shared human-approval gate for a flagged action (tool call or write): decision core for
:func:`request_tool_approval` and the file-tool write gates.

Order: yolo bypass â†’ session-cache short-circuit â†’ interactive/gateway/unattended branch â†’
prompt â†’ persistence. Input-shape checks (hardline, allowlist, pattern detection) are the
caller's job. ``fail_closed_when_no_human``: a non-interactive, non-gateway, non-cron
context without an ask bridge BLOCKS instead of auto-approving, so a plugin-flagged action
never runs ungated.
Unattended deny text is ``ctx.block_message(subject, noun, advice)`` unless the caller passes
an explicit ``*_deny_message`` (the file-tool write gates word their own).
r#  rˆ  rŠ  rŽ  r˜  zapproval required (r¢  rñ  rò  rž  r£  uZ   %s (pattern: %s): %s â€” single-query auto-approve (approvals.single_query_mode: approve).u›   %s (pattern: %s): %s â€” no interactive user/gateway present; BLOCKED (fail-closed). Set HERMES_INTERACTIVE or HERMES_GATEWAY_SESSION to answer the prompt.zBLOCKED: approval required (z>) but no interactive user or gateway is present to approve it.u^   %s (pattern: %s): %s â€” set HERMES_INTERACTIVE or HERMES_GATEWAY_SESSION to require approval.)	r-  r=  r™   rN  r6   rÝ  rÁ  rÂ  rÃ  )rÏ   r   r$  r,  r   rí   rð  r”  rh  re  rs  rE  rJ   rK   rë  Ú_ACTION_GATE)r™   r=  rù  rÝ  rk  r2  rl  ró  rô  rõ  rú  rö  r÷  r6   rÁ  rÂ  rÃ  Úlog_argsÚdeny_messagesr–  r+  s   $$$$$$$$$$$$$        r)   Ú_run_approval_gater   È  sá  € ô, ‡~‚~Ô)×<Ò<Ó>À%ÔGÜ‹{ÐÜ)Ó+€KÜ�;×,Ò,Ü‹{Ðä4=Ð>OÓ4PÑ1Ð˜z¨6ßˆ6Ÿ*˜*¯V¨VØ*¸ÐEˆð Ð5°vÐ?PØÐ1ð
ˆô (Ö)ˆCØ�x‰x‹z˜VÔ#Ø'¨¯©Õ1�ß 3§8¡8¨|Ô#;à!×/Ñ/Ð2EÀkÀ]ÐRSÐ0TÐ[lØ7nð 0ó p‘Gç Ø!×/Ñ/°È6Ð/ÓR�GÜ °[ÔZÒZØ�x‰x˜>Ô)ô —’ð  Ið UØKSôUä “{Ò"Ùñ! *÷$ )Ü—’ð  Nð ZàPXôZô  Ð 6÷ !Mð !MØ2°;°-ð @Lð Là +ôFð Fô 	�Šð Eð 	QØGOô	Qä‹{ÐäÜ˜nÐS^Ø!�]°Ø+ÀzÐZ`ôð r+   c                ó<   € V ^8„  d   QhR\         R\        R\        /# )r$   Úenv_typeÚhas_host_accessr%   rl   )r(   s   "r)   r*   r*     s"   € ÷ ñ ¬Cð Ä$ð ÔSWñ r+   c                óˆ   € V R8X  d   V'       * # V R9   d   R#  ^ RI Hp \        V! V RR4      4      #   \         d     R# i ; i)z´True when the backend is isolated enough to skip dangerous-command prompts. Docker is the
exception once host paths are bind-mounted: ``rm -rf /workspace`` then reaches host files.ÚdockerT)Úprovider_flagÚskip_container_guardsF)ÚmodalÚdaytonaÚvercel_sandbox)Úagent.terminal_env_registryr  ra   r¥   )r  r  r  s   && r)   Ú_should_skip_container_guardsr    sP   € ð �8ÔØ"Ô"Ð"ØÐ9Ô9ÙðÝ=Ü‘M (Ð,CÀUÓKÓLÐLøÜô Úðús   ™2 ²AÁ Ac                ó>   € V ^8„  d   QhR\         R\        R,          /# )r$   r-  r%   Nr�   )r(   s   "r)   r*   r*   "  s   € ÷ 1ñ 1œcð 1¤d¨T¥kñ 1r+   c                ót   € \        V 4      pVf   R# \        P                  RWR,          4       \        V4      # )u  The operator's ``approvals.deny`` rules are documented as never bypassable â€” not by yolo,
not by mode=off, and not by an isolated container either: they express intent about what the
agent may DO, not what it can reach, so they are evaluated before the container fast path.Nz%User deny rule %r blocked command: %sºNéÈ   N)r   rJ   rK   r   )r-  Údeny_patterns   & r)   Ú_user_deny_blockr  "  s6   € ô )¨Ó1€LØÒÙÜ
‡N�NÐ:¸LÐRVÍ-ÔXÜ" <Ó0Ð0r+   Ú
sudo_guardc                óJ   € V ^8„  d   QhR\         R\        R\        R,          /# )r$   r-  r  r%   Nrû  )r(   s   "r)   r*   r*   -  s%   € ÷ %ñ %œ#ð %¬dð %¼tÀd½{ñ %r+   c               ó   € ^ RI Hp \        V 4      w  r4V'       d)   \        P	                  RW@R,          4       \        W@4      # V! V 4      pV'       d-   \        P	                  RWPR,          4       \        RV 2V 4      # V'       d>   \        V 4      w  rgV'       d)   \        P	                  RWpR,          4       \        V4      # \        V 4      # )uÉ  Unconditional floors, BEFORE yolo / mode=off / cron approve-mode so no
session-level setting can bypass them: hardline catastrophic commands,
password-piping to ``sudo -S`` with no SUDO_PASSWORD configured (full guard
only), the user's own approvals.deny rules ("never, even under yolo"), and
deletion of the Python interpreter/venv this very runtime boots from (a
delete the agent cannot walk back â€” the next start fails before any tool
can run, #58748).)Úcommand_deletes_runtimez Hardline block: %s (command: %s)r  z+Runtime self-delete block: %s (command: %s)zrecursive/any delete of z(Sudo stdin guard block: %s (command: %s))	Úagent.runtime_self_protectionr  r   rJ   rK   r   r   r   r  )r-  r  r  Úis_hardlineÚhardline_descÚruntime_targetÚis_sudo_guessÚsudo_guess_descs   &$      r)   Ú_floor_blockr  -  s®   € õ Fä!8¸Ó!AÑ€KßÜ�‰Ð9¸=ÐRVÍ-ÔXÜ% mÓ=Ð=Ù,¨WÓ5€NßÜ�‰ÐDÀnÐ^bÕVcÔdÜ%Ð(@ÀÐ@PÐ&QÐSZÓ[Ð[ßÜ)@ÀÓ)IÑ&ˆßÜ�N‰NÐEÀÐ`dÕXeÔfÜ+¨OÓ<Ð<Ü˜GÓ$Ð$r+   c                óH   € V ^8„  d   QhR\         R\         R\        R\        /# ©r$   r-  r  r  r%   rû  )r(   s   "r)   r*   r*   G  s*   € ÷ ñ ¤Sð ´Cð ä-1ðä>Bñr+   c                óV  € \        WR7      '       d   \        V 4      ;'       g    \        4       # \        V 4      pVe   V# \	        4       '       d   \        4       # \        V 4      '       d   \        4       # \        V 4      w  rVpV'       g   \        4       # \        WgWRV R2RRRR7      # )záDetect a dangerous command and handle approval (pattern layer only). ``has_host_access``:
a Docker sandbox that bind-mounts host paths must not skip approval.
Returns ``{"approved": True/False, "message": str or None, ...}``.©r  r¡  r¢  rœ  r�  zFAUTO-APPROVED dangerous command in non-interactive non-gateway context)r™   r=  rù  rÝ  rk  r2  rl  rú  )r  r  r,  r  rÏ   r   r   r   )r-  r  rÝ  r  Úblockedr¤  r™   r=  s   &&&&    r)   Úcheck_dangerous_commandr#  G  sœ   € ô % X×OÓOÜ Ó(×7Ð7¬I«KÐ7Ü˜7Ó#€GØÒØˆÜ‡~‚~Ü‹{ÐÜ+¨G×4Ò4Ü‹{ÐÜ-EÀgÓ-NÑ*€L˜{ßÜ‹{ÐÜØÈØ0°°¸QÐ?ÐFZØGØgô	ð r+   Úrule_keyc                óH   € V ^8„  d   QhR\         R\         R\         R\        /# )r$   Ú	tool_namer_   r$  r%   r�   )r(   s   "r)   r*   r*   a  s)   € ÷ ñ ¤Sð ´#ð ÄCð Ôimñ r+   c               ó  € T;'       g    RV  2pV'       g@   V  R\         P                  ! VP                  R4      4      P                  4       R,           2pRV  RV R2p\	        RV 2VR	V  R
2VVRRV  R2RRV R2R7	      # )a¬  Escalate an arbitrary tool call to the human-approval gate.

Entry point for a plugin ``pre_tool_call`` hook returning ``{"action": "approve", ...}``:
it asks the SAME human gate as Tier-2 dangerous shell patterns (session/permanent
allowlist, CLI prompt, gateway pending, once/session/always/deny, timeout fail-closed), so
the LLM cannot skip it. Cron honors ``approvals.cron_mode``; any OTHER non-interactive
context without an approval bridge fails CLOSED. ``rule_key`` controls the ``[a]lways``
allowlist grain; when empty it is ``tool_name`` + a hash of ``reason`` so DISTINCT reasons
on the same tool persist independently. Returns the ``check_dangerous_command`` result shape.
zPlugin requires approval for Ú:zutf-8:Né   NzTool 'z' requires approval (r¢  zplugin_rule:Ú<z> (plugin approval rule)zFind an alternative approach.zplugin-escalated tool call 'z(' in non-interactive non-gateway contextTrn  zr but no interactive user or gateway is present to approve it. A plugin flagged this action for human confirmation.)	r™   r=  rù  rÝ  rk  rl  rú  rö  r÷  )ÚhashlibÚsha256ÚencodeÚ	hexdigestr   )r&  r_   r$  rÝ  r=  rk  s   &&$$  r)   Úrequest_tool_approvalr/  a  s¹   € ð ×GÐGÐ;¸I¸;ÐG€KßØ�[ ¤'§.¢.°×1CÑ1CÀGÓ1LÓ"M×"WÑ"WÓ"YÐZ]Õ"^Ð!_Ð`ˆØ�y�kÐ!6°{°mÀ1ÐE€GÜð # 8 *Ð-¸;Ø˜9˜+Ð%=Ð>ÐRcØÐ ?Ø!=¸i¸[ÐHpÐqØ"&Ø"+¨G¨9ð 5fð !fô
ð 
r+   c                óH   € V ^8„  d   QhR\         R\         R\        R\        /# r  rû  )r(   s   "r)   r*   r*     s*   € ÷ +ñ +¤cð +´Sð +ä.2ð+ä?Cñ+r+   c                ó¦  € \        WR7      '       d   \        V 4      ;'       g    \        4       # \        V RR7      pVe   V# ^ RIHp V! WV4      pVe   V# \        P                  ! 4       p\        4       '       g   VR8X  d   \        4       # \        V 4      '       d   \        4       # \        V4      w  r(ršV'       g?   V	'       g7   V
'       g/   \        4        F  p\        W4      pVf   K  Vu # 	  \        4       # \        V 4      w  rÞp\        4       pV'       d   \        VV4      '       d   \        4       # \!        \"        WWî.VVW‰W§R8H  R7      # )zïRun all pre-exec security checks and return a single approval decision. Plugins that
want to veto or escalate a command do it from ``pre_tool_call``.
``has_host_access``: a Docker sandbox with bind-mounted host paths takes the normal flow.r!  T)r  )Úconsume_prepared_guardr#  r¾  )
r-  r=  r™   rN  r6   rÝ  rÁ  rÂ  rÃ  r¾  )r  r  r,  r  Úagent.terminal_approval_batchr2  r   r$  rÏ   r   rð  r”  r¥  r   r   rí   rë  Ú_COMMAND_GATE)r-  r  rÝ  r  r"  r2  ÚpreparedÚapproval_moderÁ  rÂ  rÃ  r–  rf   r¤  r™   r=  r6   s   &&&&             r)   Úcheck_all_command_guardsr7    s(  € ô % X×OÓOÜ Ó(×7Ð7¬I«KÐ7ä˜7¨tÔ4€GØÒØˆåDÙ% g¸ÓI€HØÒØˆä$×7Ò7Ó9€MÜ‡~‚~˜¨%Ô/Ü‹{ÐÜ+¨G×4Ò4Ü‹{Ðä4=Ð>OÓ4PÑ1Ð˜z÷ Ÿ*¯VÜ'Ö)ˆCÜ% gÓ3ˆFØÔ!Ø’ñ *ô ‹{Ðä-EÀgÓ-NÑ*€L˜{Ü)Ó+€Kßœ; {°K×@Ò@Ü‹{ÐÜÜ˜wØ¨mØÐ3DØ°VÐT[ÑC[ô	ð r+   z¦execute_code script execution. The script can spawn subprocesses or mutate files without passing through terminal command approval; approval is one-shot for this run.c                ó$   € V ^8„  d   QhR\         /# r#   rÄ   )r(   s   "r)   r*   r*   ³  s   € ÷ 
Kñ 
Kœtñ 
Kr+   c                 óÔ   € ^ RI Hp  \        P                  ! 4       ;'       dG    \        P                  ! 4       ;'       d*    V ! 4       '       * ;'       d    \        \        4       4      RJ# )aW  A local session's turn its viewer submitted, with that viewer there to answer: its frozen launch policy is
local-interactive, the admission is the viewer's own prompt (not a plugin injection or another producer
admission) and a viewer holding ``session:approve`` is attached now, it is not a delegate_task child (sync or
async; they inherit the parent's policy), and the turn's approval notifier is registered under the bound
session key. The notifier is registered for every session turn, so it only tells side tasks (their own task
key, none registered) apart; it does not show anyone is attached.©Ú"is_delegated_child_process_contextN)Úagent.delegation_contextr;  r   Úis_local_interactive_sessionÚis_viewer_turn_with_approverrL  r   r:  s    r)   Ú_is_local_viewer_turnr?  ³  sd   € õ LÜ×9Ò9Ó;÷ Jð JÔ@P×@mÒ@mÓ@o÷ Jð JÙ6Ó8Ô8÷Jð Jä"Ô#:Ó#<Ó=ÀTÐIðKr+   c                óH   € V ^8„  d   QhR\         R\         R\        R\        /# )r$   r.  r  r  r%   rû  )r(   s   "r)   r*   r*   À  s/   € ÷ Fñ F¤3ð F´#ð FÌð FÔY]ñ Fr+   c                ó’  a a€ Rp\         pVR8X  d   \        4       # \        WR7      '       d   \        4       # \        P                  ! 4       p\        4       '       g   VR8X  d   \        4       # \        4       w  rgr‰\        4        FD  p
V
P                  4       R8X  d#   \        RV
P                  ,           W4RRR	7      u # \        4       u # 	  V'       g	   V	'       d   \        4       '       d   \        4       # \        4       pR
S  R2p\        W³4      '       d   \        4       # ^ RIHo \!        \"        WÄVV.VWgW‰VR8H  V V3R lR7      # )a8  Approve an execute_code script before its child process is spawned.

The script can call ``subprocess``/``os.system``/``ctypes`` directly, none of which pass
through ``terminal()`` / ``DANGEROUS_PATTERNS``; in gateway/ask contexts we fail closed by
approving the script as a whole. Same dict contract as ``check_all_command_guards``.
Documented limitation: a purely local non-interactive non-gateway session returns approved
(the terminal auto-approve contract); the hardline floor still blocks catastrophic
``terminal()`` commands the script issues.

See #30882.
The hardline floor still blocks catastrophic ``terminal()`` commands the script issues; running
arbitrary code headlessly without any approval surface is trusted-by-config (set a gateway/ask surface
or ``approvals.cron_mode`` to require approval). See #30882.
Úexecute_coder
  r!  r#  r˜  zyBLOCKED: execute_code runs arbitrary local Python (including subprocess calls that bypass shell-string approval checks). r"  r.  rØ  zexecute_code <<'PY'
z
PYrÅ  r¾  c                  ó   <€ R S! S 4       R2# )z**Code:**
```python
rU  r2   )r.  rÆ  s   €€r)   Ú<lambda>Ú*check_execute_code_guard.<locals>.<lambda>  s   ø€ Ð5Ñ6KÈDÓ6QÐ5RÐRWÑXr+   )r-  r=  r™   rN  r6   rÝ  rÁ  rÂ  rÃ  r¾  r¿  )Ú_EXECUTE_CODE_DESCRIPTIONr,  r  r   r$  rÏ   rð  r”  rh  rB  r{  r?  r   rí   rá  rÆ  rë  Ú_EXECUTE_CODE_GATE)r.  r  r  r™   r=  r6  rÝ  rÁ  rÂ  rÃ  r–  r6   r-  rÆ  s   f&&          @r)   Úcheck_execute_code_guardrH  À  s-  ù€ ð !€KÜ+€Kð Ð#Ô#Ü‹{ÐÜ$ X×OÓOÜ‹{ÐÜ$×7Ò7Ó9€MÜ‡~‚~˜¨%Ô/Ü‹{Ðô 5>³KÑ1Ð˜zô $Ö%ˆØ�8‰8‹:˜ÔÜðOØQT×Q^ÑQ^õ_à'È)ÐZ`ôò ô
 ‹{Òñ &÷" ŸvÔ*?×*AÒ*AÜ‹{Ðä)Ó+€Kà% d V¨4Ð0€Gô �;×,Ò,Ü‹{Ðõ
 3ÜÜ GÐR]Ø!�]°Ø+ÀzØ˜wÑ&ÝXôð r+   c                óê  € V ^8„  d   Qh/ ^ \         9   d
   \        ;R&   ^\         9   d   \        \        \        3,          ;R&   ^\         9   d   \        \        \        3,          ;R&   ^\         9   d   \        \        ,          ;R&   ^\         9   d   \        \        ,          ;R&   ^\         9   d
   \        ;R&   ^\         9   d   \        \        \        3,          ;R&   ^\         9   d   \        \        \
        3,          ;R&   ^\         9   d   \        \        \        3,          ;R	&   ^	\         9   d   \        \        \        3,          ;R
&   ^
\         9   d   \        \        \        3,          ;R&   # )r$   rÍ   r–   r›   r«   r¹   r×   rØ   r:   rV   rP   rá   )Ú__conditional_annotations__ra   rw   r7   rX   r'   rd   Úobject)r(   s   "r)   r*   r*      s*  € ÷ ñ ÷Z MÒ L”4Ñ Lñ[÷f Ò Œ$Œs”Dˆy�/Ñ ñg÷h 'Ò &”4œœS˜•>Ñ &ñi÷j  Ò Œs”3�xÑ ñk÷p 'Ò &”cœ#•hÑ &ñq÷r !Ò  ”SÑ  ñs÷v 1Ò 0œT¤#¤s (�^Ñ 0ñw÷F #Ò "Œt”Cœ�H�~Ñ "ñG÷r &Ò %””cœ4�i•Ñ %ñs÷t ,Ò +”Tœ#œv˜+Õ&Ñ +ñu÷~ 1Ò 0œT¤#¤s (�^Ñ 0òr+   )FNN>   rÖ  r"  rÜ  rt   r«  >   r.  r/  r-  )r-  rŠ   )Fr»  )ŠrJ  r‚  Údataclassesr   r+  r»   ÚloggingÚosÚ	threadingÚtypingr   Úutilsr   r   Ú
agent.i18nr   Útoolsr   r7  r   r	   r
   r   r   r   r   r   r   Útools.approval_detectionr   r   r   r   Útools.approval_floorsr   r   r   r   r   Útools.approval_gateway_waitr   Útools.approval_promptr   r   r   Útools.approval_smartr   Ú	getLoggerr~  rJ   ÚgetenvrÍ   ÚLockr9   r–   r›   rX   r«   r¹   r×   rØ   r:   r=   r3   rA   rG   rM   rV   rP   rR   r[   ri   ru   rz   r   rƒ   r†   rŽ   r’   r—   rž   r§   r­   r±   r´   r¿   rÂ   rÈ   rÏ   rÜ   rÙ   rí   rò   rõ   rû   r  rà   rá   r  r  r  r%  r(  r,  Ú	frozensetr8  r9  r;  rB  rE  rI  rL  r[  r^  r‘  r’  r”  r¥  r§  Ú_STOP_COMMANDÚ_STOP_ACTIONr4  rG  rý  r½  rë  rð  r   r  r  r  r#  r/  r7  rF  r?  rH  r*   )rJ  s   @r)   Ú<module>r_     sq  øðöõ "Û Û Û Û 	Û Ý ç 2Ý Ý "÷÷ õ ÷ó ÷õ õ @ß pÑ pÝ /à	×	Ò	˜8Ó	$€ñ *¨"¯)ª)Ð4FÈÓ*KÓLÐ Ó Lð
 	�ŠÓ€Ø€Ó Ø$&Ð Ó &Ù›%€Ó ñ "%£Ð Ó &Ù›5Ð Ó  à.0Ð Ó 0ð !#€Ó "Ø Ð õõõ-õð2 $&€Ó %Ø)+Ð Ó +õ.õ÷"õJõ"Tõõõ6õEõ	#õ)õJõ	qõ5õ)õ
*õ
õ2,õHõ
õõ"/õ$7õCõ*õ#õ-õ$ð: /1Ð Ó 0õKõ
õ:õHyõVõ/ñ #Ò#aÓbÐ áÒ =Ó>Ð ÷1ðCÐ[d÷ Cõkõ
bõ4õ
!ñL �$Ô÷\ð \ó ð\ñ,  ØÐ'ØFØÐLóÐ ñ
 Ø
ˆKÐMØÐ@ó€	õõ&ñ2 �$Ô÷ð ó ðð$=ð ðMð ñ
 Ø	˜d°$À5ÐW[ØSØAÀMÕQØ3õ4ð	Cð DÀmÕSØ5õ6à3°mÕCÀkÕQØIô€ñ Ø	˜4¨tÀÐSWØ`ð	gð
 	qàBÀ\ÕQØ5õ6ð	[ð Uô#Ð ñ* Ø	˜U°%ÀEÐX]ØSØ@À<ÕOØ*õ+àØBÀ\ÕQØ,õ-ð	Rð ô€õ ð@Fð 16ðFð EI÷F÷R 9ðFFØRVðFàðFà#4ðFð JðFð  ð	Fð CEð	Fð fhð	Fð
 DIðFð
 ik÷F÷Rõ"1ð%°U÷ %÷4ð4È"ð Ð`d÷ ÷<+ð^ið õ
K÷FñT Ö r+   