+
    iHàjŸ ã            
       ó  a € Rï t�0 t R t^ RIt^ RIt^ RIt^ RIt^ RIt^ RIHt ^ RI	H
t ]P                  ! ]4      tRtRt^@t/ t] ^ k ]P&                  ! 4       tR R ltR R	 ltR
 R ltR R lt]! 0 Rðm4      t]P6                  ! RR4      P9                  4       Rñ9   t/ t] ^k ]P&                  ! 4       tR R lt . RNRNRNRNRNRNRNRNRNRNRNRNRNRNR NR!NR"NR#NR$NR%NR&NR'NR(NR)NR*NR+NR,NR-NR.NR/NR0NR1NR2NR3NR4NR5NR6NR7NR8NR9NR:NR;NR<NR=NR>NR?NR@NRANRBNRCNRDNRENRFNRGNRHNRINt!RJt"]PF                  ! RK]" RL24      t$]PF                  ! RM]PJ                  4      t&RNt'ROt(RPt)]PF                  ! ]']PJ                  4      t*]PF                  ! RQ4      t+]PF                  ! RR]' RS]' RT]) 2]PJ                  4      t,]PF                  ! RU]( RV]' RW]) 2]PJ                  ]PZ                  ,          4      t.RXt/]PF                  ! RY]( RZ]/ R[2]PJ                  ]PZ                  ,          4      t0]PF                  ! R\]PJ                  4      t1]PF                  ! R]]PJ                  4      t2]PF                  ! R^]PJ                  4      t3R_t4]PF                  ! R`]4 Ra]4 Rb24      t5]PF                  ! Rc4      t6Rd Re lt7RfRg/Rh Ri llt8Rj Rk lt9Rl Rm lt:Rn Ro lt;Rp Rq lt<Rrt=]PF                  ! Rs]= Rt2]PJ                  4      t>]PF                  ! Ru]= Rv2]PJ                  4      t?]! 0 Ròm4      t@RótARôtB]PF                  ! Rw4      tC]PF                  ! Rx4      tD]PF                  ! Ry4      tE]PF                  ! Rz]PJ                  4      tFRõtGR{R|P‘                  ]G4       R}2tI]PF                  ! R~]I R2]PJ                  4      tJ]PF                  ! R€4      tK]PF                  ! R�4      tL]PF                  ! R‚]PJ                  4      tM]PF                  ! Rƒ]PJ                  4      tN]PF                  ! R„4      tO]PF                  ! R…4      tP]PF                  ! R†4      tQ]PF                  ! R‡4      tR]PF                  ! Rˆ4      tS]PF                  ! R‰4      tT]PF                  ! RŠ4      tU]PF                  ! R‹4      tV]! RŒ4      tWR� RŽ ltX]X! ]!4      sY]PF                  ! R�4      tZR� R‘ lt[]PF                  ! R’4      t\R“^R”^R•^R–R—R˜R™/Rš R› llt]Rœ R� lt^Rž RŸ lt_R  R¡ lt`R¢ R£ ltaR¤ R¥ ltbR¦ R§ ltcR¨ R© ltdRª R« lteR¬ R­ ltfR® R¯ ltgR° R± lthR² R³ ltiR´Rµ/R¶ R· lltjR¸ R¹ ltkRº tlR»RµR¼RµR½RµR¾RµR¿Rµ/RÀ RÁ lltm]! 0 Röm4      tn]! 0 R÷m4      to]! 0 Røm4      tp]! 0 Rùm4      tqRútrRûtsRÂ RÃ lttRÄ RÅ ltuRÆ RÇ ltvRÈ RÉ ltwRÊ RË ltxRÌty]PF                  ! RÍ]PJ                  4      tzRÎ RÏ lt{RüR»Rµ/RÐ RÑ lllt|RÒ RÓ lt}RÔ RÕ lt~RÖ R× ltRØ RÙ lt€RÚ RÛ lt�RÜ RÝ lt‚]ƒ;QJ d    . RÞ ]! 4       F  NK  	  5M! RÞ ]! 4       4      s„Rß Rà lt…/ t†] ^k ]P&                  ! 4       t‡Rá Râ ltˆRã Rä lt‰]�Rå3]‚Ræ3Rç Rè33tŠRýRé Rê llt‹Rë Rì ltŒ ! Rí Rî]EP                  4      tŽR# )þzªRegex-based secret redaction for logs and tool output.

Short tokens (< 18 chars) are fully masked; longer ones keep the first 6 and
last 4 characters for debuggability.
N)Úunquote_plus)Ú_BLOCKED_PROJECT_ENV_BASENAMESi@  z[redacted: nesting limit]c                ó$   € V ^8„  d   QhR\         /# ©é   Úreturn©Ústr)Úformats   "Ú1/home/ubuntu/.hermes/hermes-agent/agent/redact.pyÚ__annotate__r   )   s   € ÷ "ñ "”cñ "ó    c                  ó.   € ^ RI Hp  \        V ! 4       4      # )é    ©Úget_hermes_home)Úhermes_constantsr   r	   r   s    r   Ú_vault_scoper   )   s   € Ý0Ü‰Ó Ó!Ð!r   c                ó   € V ^8„  d   QhRR/# ©r   r   N© )r
   s   "r   r   r   .   s   € ÷ +ñ +¨Tñ +r   c                óÈ  € \        V \        4      '       d	   V '       g   R# V P                  RR4      P                  RR4      p\        ;_uu_ 4        \        P                  \        4       / 4      pW3 F#  pV'       g   K  VP                  VR4       RW#&   K%  	  \        V4      \        8”  d   V\        \        V4      4       K+   RRR4       R#   + '       g   i     R# ; i)a5  Register an exact vault secret value for model-facing redaction.

Called by the vault fill path BEFORE the injection happens, so no later browser tool result
can echo the value back into model context. Also registers the form a text input normalizes
it to (CR/LF stripped), since that is what the page holds.
NÚÚ Ú
)Ú
isinstancer	   ÚreplaceÚ_VAULT_REDACTION_LOCKÚ_VAULT_REDACTION_VALUESÚ
setdefaultr   ÚpopÚlenÚ _VAULT_REDACTION_MAX_PER_PROFILEÚnextÚiter)ÚvalueÚ
normalizedÚbucketÚvs   &   r   Úregister_vault_redaction_valuer)   .   s¨   € ô �eœS×!Ò!¯ÙØ—‘˜t RÓ(×0Ñ0°°rÓ:€Jß	Ö	Ü(×3Ñ3´L³NÀBÓGˆØÓ$ˆAß‰qØ—
‘
˜1˜dÔ#Ø �“	ñ %ô �&‹kÔ<Ô<Ø”tœD ›LÓ)Ò*ð =÷ 
×	×	Ò	ús   Á*CÂ ACÃC!	c                ó   € V ^8„  d   QhRR/# r   r   )r
   s   "r   r   r   B   s   € ÷ :ñ : dñ :r   c                 ó˜   € \         ;_uu_ 4        \        P                  \        4       R4       RRR4       R#   + '       g   i     R# ; i)zPDrop the current profile's registered values (profile teardown / explicit lock).N)r   r   r    r   r   r   r   Úclear_vault_redaction_valuesr,   B   s)   € ç	Ö	Ü×#Ñ#¤L£N°DÔ9÷ 
×	×	Ò	úó	   �8¸A		c                ó0   € V ^8„  d   QhR\         R\         /# ©r   Útextr   r   )r
   s   "r   r   r   H   s   € ÷ 
ñ 
¬ð 
´ñ 
r   c                óR  € \        V \        4      '       d	   V '       g   V # \        ;_uu_ 4        \        P	                  \        4       4      pV'       d   \        V\        RR7      MRpRRR4       X F  pW09   g   K  V P                  VR4      p K  	  V #   + '       g   i     L5; i)zUExact-substring scrub of every vault secret value registered for the current profile.T)ÚkeyÚreverseNu   Â«redacted-vault-secretÂ»r   )	r   r	   r   r   Úgetr   Úsortedr!   r   )r0   r'   Úvaluesr%   s   &   r   Úredact_registered_vault_valuesr7   H   sw   € ä�dœC× Ò ¯Øˆß	Ö	Ü(×,Ñ,¬\«^Ó<ˆß:@”˜¤C°Õ6Àbˆ÷ 
ó ˆØŽ=Ø—<‘< Ð'BÓCŠDñ ð €K÷ 
×	ús   ¯:BÂB&	ÚHERMES_REDACT_SECRETSÚtruec                ó$   € V ^8„  d   QhR\         /# r   ©Úbool)r
   s   "r   r   r   q   s   € ÷ ñ œñ r   c                 ó”  € ^ RI Hp Hp V ! 4       f   \        # V! 4       p\        P                  V4      pVe   V# Rp ^ RIHp V! 4       pV'       d   VP                  R4      MRpVf!   Vf   ^ RIH	p V! 4       P                  R4      pVfG   ^ RIH
p	 V	! 4       P                  R4      ;'       g    / P                  R	4      p
V
f   RM
\        V
4      pVe+   \        V4      P                  4       P                  4       R
9   p\        ;_uu_ 4        T\        T&   RRR4       T#   \         d    Rp L1i ; i  + '       g   i     T# ; i)zUEffective redaction switch for the active profile (launch snapshot when no override).)Úget_hermes_home_overrideÚhermes_home_keyNT)Úcurrent_secret_scoper8   )Úload_env)Úload_config_readonlyÚsecurityÚredact_secrets>   Ú1ÚonÚyesr9   )r   r>   r?   Ú_REDACT_ENABLEDÚ_REDACT_ENABLED_BY_HOMEr4   Úagent.secret_scoper@   Úhermes_cli.configrA   rB   r	   ÚstripÚlowerÚ	ExceptionÚ_REDACT_ENABLED_LOCK)r>   r?   Úhome_keyÚcachedÚenabledr@   ÚscopeÚrawrA   rB   Úcfg_vals              r   Ú_redact_enabledrV   q   s  € çJÙÓ!Ò)ÜÐÙÓ €HÜ$×(Ñ(¨Ó2€FØÒØˆØ€GðÝ;Ù$Ó&ˆß49ˆe�i‰iÐ/Ô0¸tˆØŠ;˜5š=õ 3Ù“*—.‘.Ð!8Ó9ˆCØŠ;Ý>Ù+Ó-×1Ñ1°*Ó=×CÐCÀ×HÑHÐIYÓZˆGØ!š/‘$¬s°7«|ˆCØŠ?Ü˜#“h—n‘nÓ&×,Ñ,Ó.Ð2LÑLˆG÷ 
Ö	Ø,3Ô Ñ)÷ 
à€Nøô	 ô ØŠðúç	Ö	à€Nús+   ½D# ÁAD# Â0AD# Ä
D6Ä#D3Ä2D3Ä6E	z(sk-[A-Za-z0-9_-](?:\.?[A-Za-z0-9_-]){9,}zghp_[A-Za-z0-9]{10,}zgithub_pat_[A-Za-z0-9_]{10,}zgho_[A-Za-z0-9]{10,}zghu_[A-Za-z0-9]{10,}zghs_[A-Za-z0-9]{10,}zghr_[A-Za-z0-9]{10,}zxapp-\d+-[A-Za-z0-9-]{10,}zxox[baprs]-[A-Za-z0-9-]{10,}zAIza[A-Za-z0-9_-]{30,}zpplx-[A-Za-z0-9]{10,}zfal_[A-Za-z0-9_-]{10,}zfc-[A-Za-z0-9]{10,}zbb_live_[A-Za-z0-9_-]{10,}zgAAAA[A-Za-z0-9_=-]{20,}zAKIA[A-Z0-9]{16}zsk_live_[A-Za-z0-9]{10,}zsk_test_[A-Za-z0-9]{10,}zrk_live_[A-Za-z0-9]{10,}zSG\.[A-Za-z0-9_-]{10,}zhf_[A-Za-z0-9]{10,}zr8_[A-Za-z0-9]{10,}znpm_[A-Za-z0-9]{10,}zpypi-[A-Za-z0-9_-]{10,}zdop_v1_[A-Za-z0-9]{10,}zdoo_v1_[A-Za-z0-9]{10,}zam_(?:org_)?[A-Za-z0-9]{20,}zsk_[A-Za-z0-9_]{10,}ztvly-[A-Za-z0-9]{10,}zexa_[A-Za-z0-9]{10,}zgsk_[A-Za-z0-9]{10,}zsyt_[A-Za-z0-9]{10,}zretaindb_[A-Za-z0-9]{10,}zhsk-[A-Za-z0-9]{10,}zmem0_[A-Za-z0-9]{10,}zbrv_[A-Za-z0-9]{10,}zxai-[A-Za-z0-9]{30,}zntn_[A-Za-z0-9]{10,}zfw-[A-Za-z0-9]{30,}zfw_[A-Za-z0-9]{30,}zfpk_[A-Za-z0-9]{30,}zglpat-[A-Za-z0-9_\-]{10,}zgloas-[A-Za-z0-9_\-]{10,}zgldt-[A-Za-z0-9_\-]{10,}zglrt-[A-Za-z0-9_.\-]{10,}zglrtr-[A-Za-z0-9_.\-]{10,}zglcbt-[A-Za-z0-9_\-]{10,}zglptt-[A-Za-z0-9_\-]{10,}zglft-[A-Za-z0-9_\-]{10,}zglimt-[A-Za-z0-9_\-]{10,}zglagent-[A-Za-z0-9_\-]{10,}zglsoat-[A-Za-z0-9_\-]{10,}zglffct-[A-Za-z0-9_\-]{10,}zglwt-[A-Za-z0-9_\-]{10,}zGR1348941[A-Za-z0-9_\-]{10,}zpk-lf-[A-Za-z0-9\-]{8,}zE(?:API_?KEY|KEY|TOKEN|SECRET|PASSWORD|PASSWD|PASS|PW|CREDENTIAL|AUTH)z([A-Z0-9_]{0,50}z&[A-Z0-9_]{0,50})\s*=\s*(['\"]?)(\S+)\2zƒ(?<![a-z0-9_])([a-z0-9_]+(?:_|^)(?:key|pass|pw|token|secret|password|passwd|credential|auth)(?=[^a-z0-9_]|$))\s*=\s*(['\"]?)(\S+)\2z?(?:api[ _.\-]?key|token|secret|passwd|password|credential|auth)z(?:[0-9]+(?:[|:\-]|\t)[ \t]*)?z(['\"]?)([^\s&]+?)\2(?=[\s&]|$)z0^(?:os\.(?:getenv|environ)|process\.env|\$ENV\{)z7(?<![A-Za-z0-9_.\-])([A-Za-z0-9_\-]++\.[A-Za-z0-9_.\-]*z"[A-Za-z0-9_.\-]*+|[A-Za-z0-9_.\-]*z%[A-Za-z0-9_.\-]*\.[A-Za-z0-9_.\-]++)=z(^[ \t]*z (?:export[ \t]+)?[A-Za-z0-9_\-]*z[A-Za-z0-9_\-]*)=z:(?:api[ _.\-]?key|token|secret|passwd|password|credential)z	(^[ \t]*+z[A-Za-z0-9_.\-]*z/[A-Za-z0-9_.\-]*+)(:[ \t]*+)(?!['\"])([^\s&]++)zy(?:api|auth|access|refresh|session|secret)[ _.\\-]?(?:key|token)|token|secret|passwd|password|pass|pw|credential|auth|keyzŽ(?:api|auth|access|refresh|session|id|bearer)[ _.\\-]?(?:key|token)|key[ _.\\-]?material|secret|passwd|password|pass|pw|credential|auth|bearerzpasswd|password|pass|pwz(\$(?:\{[A-Za-z_]\w*[^}]*\}|[A-Za-z_]\w*)z^(?:z|\$\(|~|/)(?:[\w./:-]|z)*$z3(?=[^.]*[a-z])(?=[^.]*[A-Z])(?=[^.]*[0-9])[^.]{16,}c                ó<   € V ^8„  d   QhR\         R\        R\        /# )r   ÚsÚir   ©r	   Úintr<   )r
   s   "r   r   r   `  s&   € ÷ Vñ V”cð Vœcð V¤dñ Vr   c                óœ  € V^ 8X  d   R# W^,
          ,          W,          r2VP                  4       '       d-   VP                  4       '       d   VP                  4       '       d   R# VP                  4       ;'       dS    VP                  4       ;'       d;    V^,           \        V 4      8  ;'       d    W^,           ,          P                  4       # )zdTrue if position ``i`` in ``s`` begins a word (edge, non-letter before, camelCase/acronym boundary).T)ÚisalphaÚisupperÚislowerr!   )rX   rY   ÚprevÚcurs   &&  r   Ú_is_word_startrb   `  s‚   € àˆA„vÙØ�a•%•˜!�$ˆ#Ø�<‰<�>Š>˜cŸk™kŸmšm°·±·²ÙØ�;‰;‹=×UÐU˜TŸ\™\›^×UÐU°°Aµ¼¸A»±×UÐUÀ1ÈÅUÅ8×CSÑCSÓCUÐUr   Úallow_pluralTc                óH   € V ^8„  d   QhR\         R\        R\        R\        /# )r   rX   Újrc   r   rZ   )r
   s   "r   r   r   j  s.   € ÷ Wñ W”Cð WœCð W´$ð WÄ$ñ Wr   c               ó.  € V\        V 4      8¼  d   R# W,          pVP                  4       '       d:   VP                  4       '       d&   W^,
          ,          P                  4       '       d   R# T;'       d"    VR9   ;'       d    \	        W^,           RR7      # )z\True if position ``j`` (exclusive end) in ``s`` ends a word; one trailing ``s`` is absorbed.TÚsSF)rc   )r!   r]   r^   r_   Ú_is_word_end)rX   re   rc   ra   s   &&$ r   rh   rh   j  si   € àŒC�‹F„{ÙØ
�$€CØ�;‰;�=Š=˜SŸ[™[Ÿ]š]¨q°Qµ­x×/?Ñ/?×/AÒ/AÙØ×VÐV˜C 4™K×VÐV¬L¸À½EÐPUÔ,VÐVr   c                óf   € V ^8„  d   QhR\         R\        P                  \         ,          R\        /# )r   r2   Ú
keyword_rer   )r	   ÚreÚPatternr<   )r
   s   "r   r   r   t  s.   € ÷ pñ p¤3ð p´B·J±J¼sµOð pÌñ pr   c                ó´   a € \         ;QJ d.    V 3R lVP                  S 4       4       F  '       g   K   R# 	  R# ! V 3R lVP                  S 4       4       4      # )zPTrue if ``keyword_re`` matches ``key`` at a word boundary (see _KEY_KEYWORD_RE).c              3   óœ   <"  € T FA  p\        SVP                  4       4      ;'       d    \        SVP                  4       4      x € KC  	  R # 5i©N)rb   Ústartrh   Úend)Ú.0Úmr2   s   & €r   Ú	<genexpr>Ú,_has_word_bounded_keyword.<locals>.<genexpr>v  s9   øé € ÐoÑVnÐQRŒ~˜c 1§7¡7£9Ó-×LÐL´,¸sÀAÇEÁEÃGÓ2LÔLÓVnùs
   ƒ%A©#ATF)ÚanyÚfinditer)r2   rj   s   f&r   Ú_has_word_bounded_keywordrx   t  sF   ø€ ç‹3ÔoÐV`×ViÑViÐjmÔVnÓo�3Œ3ÐoŠ3Ðoˆ3ÔoÐV`×ViÑViÐjmÔVnÓoÓoÐor   c                ó0   € V ^8„  d   QhR\         R\        /# ©r   r2   r   ©r	   r<   )r
   s   "r   r   r   y  s   € ÷ ;ñ ;¤ð ;¬ñ ;r   c                ó"   € \        V \        4      # )zYPost-match key validator: ``API_KEY``/``DB_PW`` count, ``KEYBOARD``/``secretary`` do not.)rx   Ú_KEY_KEYWORD_RE©r2   s   &r   Ú_key_has_secret_keywordr   y  s   € ä$ S¬/Ó:Ð:r   c                ó0   € V ^8„  d   QhR\         R\        /# ©r   r%   r   r{   )r
   s   "r   r   r   ~  s   € ÷ Wñ W¬ð W´ñ Wr   c                óT  a € S R8X  g   S P                  R4      '       d   R# \        S 4      ^8¼  d    \        P                  ! RS 4      '       d   R# \        S 4      ^8¼  d    \        P                  ! RS 4      '       d   R# \        S 4      ^8  d   R# \	        V 3R lR 4       4      ^8¬  # )	zœCredential-like shape test for ambiguous ``token``/``key`` values, so short
technical scalars (``CPU``, ``local``) are not masked merely for their key name.ú***õ   Â«redacted:Tz[A-Fa-f0-9]+z[A-Za-z0-9_./+=-]+Fc              3   ód   <"  € T F%  p\        \        P                  ! VS4      4      x € K'  	  R # 5iro   )r<   rk   Úsearch)rr   Úpr%   s   & €r   rt   Ú0_looks_like_opaque_credential.<locals>.<genexpr>‰  s&   øé € ÐQÑ2P¨QŒt”B—I’I˜a Ó'×(Ð(Ó2Pùs   ƒ-0)z[a-z]z[A-Z]z[0-9])Ú
startswithr!   rk   Ú	fullmatchÚsum)r%   s   fr   Ú_looks_like_opaque_credentialrŒ   ~  s„   ø€ ð �„~˜×)Ñ)¨-×8Ò8ÙÜ
ˆ5ƒz�RÔœBŸLšL¨¸%×@Ò@ÙÜ
ˆ5ƒz�RÔœBŸLšLÐ)>À×FÒFÙÜ
ˆ5ƒz�B„ÙÜÔQÑ2PÓQÓQÐUVÑVÐVr   c                óH   € V ^8„  d   QhR\         R\         R\        R\        /# )r   r2   r%   Úcheck_keywordr   r{   )r
   s   "r   r   r   Œ  s(   € ÷ 5ñ 5¤3ð 5¬sð 5Ädð 5Ìtñ 5r   c               ó*  € \         P                  V4      '       d   R# VR8X  g   VP                  R4      '       d   R# V'       d   \        V 4      '       g   R# \        P                  V4      '       d   \        V \        4      '       gi   V^ ,          R8X  gY   \        ;QJ d+    R VP                  R4       4       F  '       g   K   RM 	  RM! R VP                  R4       4       4      '       g   R# \        V \        4      ;'       g    \        V4      # )zôShared gate for the ENV / JSON / YAML assignment passes: skip programmatic env
lookups used as values, optionally require a word-bounded keyword in the key,
then redact when the key is unambiguously credential-bearing or the value looks opaque.Frƒ   u
   Â«redactedÚ$c              3   óL   "  € T F  p\         P                  V4      x € K  	  R # 5iro   )Ú_OPAQUE_PATH_SEGMENT_RErŠ   )rr   Úsegs   & r   rt   Ú,_should_redact_assignment.<locals>.<genexpr>¦  s"   é € Ð%iÑXhÐQTÔ&=×&GÑ&GÈ×&LÐ&LÓXhùs   ‚"$Ú/T)Ú_ENV_LOOKUP_VALUE_REÚmatchr‰   r   Ú_PATH_OR_VAR_VALUE_RErx   Ú_PASSWORD_KEY_RErv   ÚsplitÚ_STRONG_KEY_KEYWORD_RErŒ   )r2   r%   rŽ   s   &&$r   Ú_should_redact_assignmentrœ   Œ  sÒ   € ô ×!Ñ! %×(Ò(Ùð �„~˜×)Ñ)¨,×7Ò7ÙßÔ4°S×9Ò9Ùô ×"Ñ" 5×)Ò)Ô2KÈCÔQa×2bÒ2bð
 ��8�sŒ?§#£#Ñ%iÐX]×XcÑXcÐdgÔXhÓ%i§#§#¢#Ñ%iÐX]×XcÑXcÐdgÔXhÓ%i×"iÒ"iÙÜ% cÔ+AÓB÷ 4ð 4Ü,¨UÓ3ð5r   z„(?:api_?[Kk]ey|token|secret|password|access_token|refresh_token|auth_token|bearer|secret_value|raw_secret|secret_input|key_material)z("z")\s*:\s*"([^"]+)"z((\\+)"z\2")\s*:\s*\2"([^"\\]+)\2"z¯'(?P<key>[A-Za-z_][A-Za-z0-9_]*)'(?P<sep>\s*:\s*)(?:(?P<single_prefix>[bB]?)'(?P<single_value>(?:\\.|[^'\\])+)'|(?P<double_prefix>[bB]?)\"(?P<double_value>(?:\\.|[^\"\\])+)\")z*^(?P<prefix>[ \t]*E[ \t]{2,})(?P<body>.*)$z[^(?P<prefix>(?:[A-Za-z_]\w*\.)*[A-Za-z_]\w*(?:Error|Exception|Warning):[ \t]*)(?P<body>.*)$z?((?:Proxy-)?Authorization:\s*)([A-Za-z][\w.+-]*\s+)?([^\s\"']+)z(?:Ú|Ú)Ú(z\s*:\s*)(\S+)z*(?<!\d)(bot)?(\d{8,}):([-A-Za-z0-9_]{30,})zH-----BEGIN[A-Z ]*PRIVATE KEY-----[\s\S]*?-----END[A-Z ]*PRIVATE KEY-----zO((?:postgres(?:ql)?|mysql|mongodb(?:\+srv)?|redis|amqp)://[^:\s]+:)([^@\s]+)(@)zA((?:https?|wss?|git|ssh|ftp|ftps|sftp)://)([^\s:@/]{8,})(@[^\s]+)z2eyJ[A-Za-z0-9_-]{10,}(?:\.[A-Za-z0-9_=-]{4,}){0,2}z (\+[1-9]\d{6,14})(?![A-Za-z0-9])z;(https?|wss?|ftp)://([^\s/?#]+)([^\s?#]*)\?([^\s#]+)(#\S*)?z+(https?|wss?|ftp)://([^/\s:@]+):([^/\s@]+)@z.([?#&;])([A-Za-z0-9_.~+%\-]+)=([^#&;\s\"'<>]*)z//[^/\s?#@]+@zH^[A-Za-z_][A-Za-z0-9_.-]*=[^&\s]*(?:&[A-Za-z_][A-Za-z0-9_.-]*=[^&\s]*)+$z5[\x00-\x1f\x7f\u200b-\u200f\u2028-\u202f\u2060\ufeff]zAABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-.c                óZ   € V ^8„  d   QhR\         R\        P                  \        ,          /# )r   Úpatternsr   )Úlistrk   rl   r	   )r
   s   "r   r   r   M  s&   € ÷ [ñ [¤dð [¬r¯z©z¼#­ñ [r   c                 óh   € \         P                  ! R RP                  V 4      ,           R,           4      # )z(?<![A-Za-z0-9_-])(r�   z)(?![A-Za-z0-9_-]))rk   ÚcompileÚjoin)r¡   s   &r   Ú_compile_prefix_matcherr¦   M  s&   € Ü�:Š:Ð,¨s¯x©x¸Ó/AÕAÐDYÕYÓZÐZr   zE(?<![A-Za-z0-9_.-])([0-9a-f]{32}\.[A-Za-z0-9]{16,})(?![A-Za-z0-9_.-])c                ó0   € V ^8„  d   QhR\         R\         /# r/   r   )r
   s   "r   r   r   ]  s   € ÷ !ñ !¤Sð !´cñ !r   c           
     óR  € \         P                  RV 4      pW 8X  d   V # \        V 4       UUu. uF$  w  r4\         P                  V4      '       d   K"  VNK&  	  ppp\	        V 4      . rv\
        P                  V4       Fñ  pWXP                  ^4      ,          p	WXP                  ^4      ^,
          ,          ^,           p
W	V
 pRV9   g   RV9   d   \
        P                  V4      '       d   Kn  \        ;QJ d    R V 4       F  '       d   K   RM	  RM! R V 4       4      '       g   Kª  V
\        V 4      8¼  g   W
,          R8w  g   KÉ  VP                  WšV! VP                  ^4      4      34       Kó  	  \        V4       F  w  ršp\	        V4      WiV
% K  	  RP                  V4      # u uppi )uø  Mask tokens whose body is split by control/zero-width characters.

Match on a control-stripped copy, then mask the corresponding span in the
ORIGINAL â€” only when that span holds solely token-body and control chars, so
a match can never cross into another line's unrelated text.

A credential like ``sk-abc\x1bdef456â€¦`` or ``ghp_abc\n123defâ€¦`` has its token body interrupted, so the
contiguous _PREFIX_RE cannot match it and the secret leaks verbatim (issue #77484). ``EXA_API_KEY=*** is
rejected).
r   r   r   c              3   ól   "  € T F*  q\         9   ;'       g    \        P                  V4      x € K,  	  R # 5iro   )Ú_TOKEN_BODY_CHARSÚ_CONTROL_CHARS_REr—   )rr   Úcs   & r   rt   Ú-_mask_control_split_tokens.<locals>.<genexpr>y  s+   é € ÐSÉdÈÔ&Ñ&×DÐDÔ*;×*AÑ*AÀ!Ó*DÔDËdùs   ‚4–4FTÚ=)r«   ÚsubÚ	enumerater—   r¢   Ú
_PREFIX_RErw   rp   rq   r†   Úallr!   ÚappendÚgroupÚreversedr¥   )r0   Úmask_fnÚstrippedrY   r¬   Úorig_idxÚoutÚmatchesrs   Ú
start_origÚend_origÚspanÚreplacements   &&           r   Ú_mask_control_split_tokensr¿   ]  sO  € ô !×$Ñ$ R¨Ó.€HØÔØˆÜ'¨œoÔP™o‘d�aÔ5F×5LÑ5LÈQ×5O—�™o€HÑPÜ˜“:˜rˆÜ× Ñ  Ö*ˆØŸg™g a›jÕ)ˆ
ØŸE™E !›H q�LÕ)¨AÕ-ˆØ˜xÐ(ˆð
 �DŒL˜D DœL¬j×.?Ñ.?À×.EÒ.EÙ÷ ‹CÑSÉdÓS�C�CŠCÑSÉdÓS×SÔSØ¤ T£Ô*¨d­nÀÖ.CØ�N‰N˜J±'¸!¿'¹'À!»*Ó2EÐFÖGñ +ô .6°gÖ->Ñ)ˆ
˜kÜ#'¨Ó#4ˆ�xÒ ñ .?à�7‰7�3‹<Ðùó' Qs   ­F#ÁF#z?[\x00-\x1f\x7f\x80-\x9f\u200b-\u200f\u202a-\u202e\u2060-\u2064]ÚheadÚtailÚfloorÚplaceholderrƒ   Úemptyr   c                ól   € V ^8„  d   QhR\         R\        R\        R\        R\         R\         R\         /# )r   r%   rÀ   rÁ   rÂ   rÃ   rÄ   r   ©r	   r[   )r
   s   "r   r   r   †  sI   € ÷ Vñ V”sð V¤Sð V´Cð VÄCð VÜ ðVÜ14ðVÜ>AñVr   c               ó”   € V '       d   \         P                  RV 4      MT p V '       g   V# \        V 4      V8  d   V# V RV  RW) R  2# )u·   Mask a secret for display (``hermes config`` / ``status`` / ``dump``):
``sk-p...7890``; shorter than ``floor`` (after control-byte stripping) â†’
``placeholder``; falsy â†’ ``empty``.r   Nz...)Ú_DISPLAY_CONTROL_REr¯   r!   )r%   rÀ   rÁ   rÂ   rÃ   rÄ   s   &$$$$$r   Úmask_secretrÉ   †  sP   € ÷
 38Ô×#Ñ# B¨Ô.¸U€EßØˆÜ˜e›* uÔ,ˆ;ÐU°U¸5¸D°\°NÀ#ÀeÈEÈFÀmÀ_Ð2UÐUr   c                ó0   € V ^8„  d   QhR\         R\         /# ©r   Útokenr   r   )r
   s   "r   r   r   ‘  s   € ÷ 8ñ 8”sð 8œsñ 8r   c                ó4   € V '       g   R# \        V ^^^R7      # )uU   Mask a log token â€” 18-char floor, preserves 6 prefix / 4 suffix; empty â†’ ``***``.rƒ   )rÀ   rÁ   rÂ   )rÉ   )rÌ   s   &r   Ú_mask_tokenrÎ   ‘  s   € çÙÜ�u 1¨1°BÔ7Ð7r   c                ó0   € V ^8„  d   QhR\         R\        /# rz   r{   )r
   s   "r   r   r   ˜  s   € ÷ =ñ =¤Cð =¬Dñ =r   c                óÌ   € V P                  4       pV\        9   d   R# V P                  4       '       d   V P                  \        4      '       d   R# VP                  \
        4      # )zCReturn True for exact secret keys or credential-suffixed key names.T)ÚcasefoldÚ_PYTHON_REPR_SECRET_KEYSr^   ÚendswithÚ_PYTHON_REPR_ENV_SUFFIXESÚ _PYTHON_REPR_CREDENTIAL_SUFFIXES)r2   Úfoldeds   & r   Ú_is_python_repr_secret_keyr×   ˜  sH   € à�\‰\‹^€FØÔ)Ô)ÙØ
‡{�{‡}‚}˜Ÿ™Ô&?×@Ò@Ùð �?‰?Ô;Ó<Ð<r   c                ó0   € V ^8„  d   QhR\         R\        /# rz   )Úobjectr<   )r
   s   "r   r   r   ¨  s   € ÷ Dñ Dœfð D¬ñ Dr   c                óH   € \        V \        4      ;'       d    \        V 4      # )uš   True when a mapping field named ``key`` holds a credential â€” the repr-field policy, for callers
that mask structured config by field instead of by text.)r   r	   r×   r~   s   &r   Úis_secret_field_namerÛ   ¨  s   € ô �cœ3Ó×CÐCÔ$>¸sÓ$CÐCr   c                ó0   € V ^8„  d   QhR\         R\         /# r/   r   )r
   s   "r   r   r   ®  s   € ÷ 1ñ 1¤Sð 1¬Sñ 1r   c                ó8   € R R lp\         P                  W4      # )z?Fully mask credential fields in Python mapping ``repr`` output.c                óD   € V ^8„  d   QhR\         P                  R\        /# )r   r—   r   )rk   ÚMatchr	   )r
   s   "r   r   Ú0_redact_python_repr_fields.<locals>.__annotate__°  s"   € ÷ Gñ G”B—H‘Hð G¤ñ Gr   c                 ó   € V P                  R 4      p\        V4      '       g   V P                  ^ 4      # V P                  R4      pVe!   V P                  R4      ;'       g    RpRpTpM.V P                  R4      ;'       g    RpRpV P                  R4      p\        P                  V4      '       d   V P                  ^ 4      # RV9   g   VP	                  R	4      '       d   V P                  ^ 4      # RV RV P                  R
4       V V RV 2# )r2   Úsingle_valueÚsingle_prefixr   Ú'Údouble_prefixÚ"Údouble_valuerƒ   r„   Úsep)r´   r×   r–   r—   r‰   )r—   r2   râ   ÚprefixÚquoter%   s   &     r   Ú_subÚ(_redact_python_repr_fields.<locals>._sub°  sû   € Ø�k‰k˜%Ó ˆÜ)¨#×.Ò.Ø—;‘;˜q“>Ð!à—{‘{ >Ó2ˆØÒ#Ø—[‘[ Ó1×7Ð7°RˆFØˆEØ ‰Eà—[‘[ Ó1×7Ð7°RˆFØˆEØ—K‘K Ó/ˆEô  ×%Ñ% e×,Ò,Ø—;‘;˜q“>Ð!ð �EŒ>˜U×-Ñ-¨m×<Ò<Ø—;‘;˜q“>Ð!ð �3�%�q˜Ÿ™ UÓ+Ð,¨V¨H°U°G¸3¸u¸gÐFÐFr   )Ú_PYTHON_REPR_FIELD_REr¯   )r0   rë   s   & r   Ú_redact_python_repr_fieldsrî   ®  s   € õGô: !×$Ñ$ TÓ0Ð0r   c                ó0   € V ^8„  d   QhR\         R\         /# r/   r   )r
   s   "r   r   r   Ð  s   € ÷ ñ ´ð ¼ñ r   c                óü  € V P                  RR7      p\        V4       FË  w  r#RpTpVP                  R4      '       d   VRR
 RrEM7VP                  R4      '       g   VP                  R4      '       d
   VRR VRR rE\        P	                  V4      pVf   \
        P	                  V4      pVf   K’  VP                  R4      \        VP                  R	4      4      ,           V,           W&   KÍ  	  RP                  V4      # )zHMask repr fields only on pytest/error lines in source-preserving output.T)Úkeependsr   z
Nr   r   ré   Úbodyéþÿÿÿéÿÿÿÿ)	Ú
splitlinesr°   rÓ   Ú_PYTEST_DIAGNOSTIC_LINE_REr—   Ú_PYTHON_EXCEPTION_LINE_REr´   rî   r¥   )r0   ÚlinesÚindexÚlineÚendingÚ	body_liner—   s   &      r   Ú%_redact_python_diagnostic_repr_fieldsrý   Ð  sæ   € à�O‰O TˆOÓ*€EÜ  Ö'‰ˆØˆØˆ	Ø�=‰=˜× Ò Ø $ S b 	¨6‘vØ�]‰]˜4× Ò  D§M¡M°$×$7Ò$7Ø $ S b 	¨4°°¨9�vä*×0Ñ0°Ó;ˆØŠ=Ü-×3Ñ3°IÓ>ˆEØÔà—‘˜HÓ%Ü,¨U¯[©[¸Ó-@ÓAõBàõð ‹Lñ (ð" �7‰7�5‹>Ðr   c                ó0   € V ^8„  d   QhR\         R\         /# )r   Úqueryr   r   )r
   s   "r   r   r   ç  s   € ÷ ñ ¤ð ¬ñ r   c                ód   € V '       g   V # RP                  R V P                  R4       4       4      # )zQReplace values of sensitive ``k=v&k=v`` params with ``***``; others pass through.Ú&c              3   ó˜   "  € T F@  qP                  R 4      w  r#pV'       d   VP                  4       \        9   d   V R2MTx € KB  	  R# 5i)r®   ú=***N)Ú	partitionrM   Ú_SENSITIVE_QUERY_PARAMS)rr   Úpairr2   rè   Ú_s   &    r   rt   Ú'_redact_query_string.<locals>.<genexpr>ë  sA   é € ð á$ˆD¿¹ÈÓ9L©¨°1÷  §	¡	£Ô/FÔ Fˆ3ˆ%ˆt‰ÈDÔPÛ$ùs   ‚AA
)r¥   rš   )rÿ   s   &r   Ú_redact_query_stringr	  ç  s1   € çØˆØ�8‰8ñ à—K‘K Ô$óó ð r   c                ó0   € V ^8„  d   QhR\         R\         /# )r   Únamer   r   )r
   s   "r   r   r   ñ  s   € ÷ Uñ U¤Cð U¬Cñ Ur   c                ó²   € T p\        ^4       F  p\        V4      pW18X  d    MTpK  	  VP                  4       pV\        9   d   V# VP	                  RR4      # )zSDecode a URL parameter name (up to 3 unquote rounds) for case-insensitive matching.Ú-r  )Úranger   rÑ   r  r   )r  Údecodedr  Ú
next_valuerÖ   s   &    r   Ú_canonical_url_param_namer  ñ  s^   € à€GÜ�1ŽXˆÜ! 'Ó*ˆ
ØÔ ÙØŠñ	 ð
 ×ÑÓ€Fð Ô6Ô6ˆ6ÐT¸F¿N¹NÈ3ÐPSÓ<TÐTr   c                ó0   € V ^8„  d   QhR\         R\         /# r/   r   )r
   s   "r   r   r   ÿ  s   € ÷ ;ñ ;¬ð ;´ñ ;r   c                ó\   € \         P                  R V 4      p \        P                  RV 4      # )z™Strict egress-boundary redaction of URL credentials (absolute, relative and
network references); preserves keys, separators, public params, hosts, paths.c                 ó´   € \        V P                  ^4      4      \        9   d&   V P                  ^4       V P                  ^4       R2# V P                  ^ 4      # )r   r  )r  r´   r  ©rs   s   &r   Ú<lambda>Ú0_redact_strict_url_credentials.<locals>.<lambda>  sS   € Ü$ Q§W¡W¨Q£ZÓ0Ô4KÔKð —W‘W˜Q“Z�L §¡¨£ ¨DÐ1ð \ØQR×QXÑQXÐYZÓQ[ð\r   z
//***:***@)Ú_STRICT_URL_PARAM_REr¯   Ú_STRICT_URL_USERINFO_RE©r0   s   &r   Ú_redact_strict_url_credentialsr  ÿ  s3   € ô  ×#Ñ#ñ	\Ø]aóc€Dô #×&Ñ& |°TÓ:Ð:r   c                ó0   € V ^8„  d   QhR\         R\        /# r�   )rÙ   r	   )r
   s   "r   r   r     s   € ÷ Uñ Uœ&ð U¤Sñ Ur   c                ó¦   € \        V f   RM
\        V 4      4      pV'       g   V# \        P                  R V4      p\        P                  R V4      # )a  Mask secrets in a CDP/browser endpoint URL before it is logged.

Unlike ``redact_sensitive_text`` (which passes web-URL query params and
``user:pass@`` through for OAuth callbacks / magic links), CDP discovery
tokens are pure credentials, so this opts INTO both URL redactors.
r   c           
      óÚ   € V P                  ^4       RV P                  ^4       V P                  ^4       R\        V P                  ^4      4       V P                  ^4      ;'       g    R 2# )é   ú://Ú?r   )r´   r	  r  s   &r   r  Ú redact_cdp_url.<locals>.<lambda>  s`   € �Q—W‘W˜Q“Z�L  A§G¡G¨A£J <°·±¸³
¨|¸1Ô=QÐRS×RYÑRYÐZ[ÓR\Ó=]Ð<^Ð_`×_fÑ_fÐghÓ_i×_oÐ_oÐmoÐ^pÑqr   c                 óN   € V P                  ^4       RV P                  ^4       R2# )r  r   z:***@©r´   r  s   &r   r  r"    s!   € ¨Q¯W©W°Q«Z¨L¸¸A¿G¹GÀA»J¸<ÀuÑ*Mr   )Úredact_sensitive_textr	   Ú_URL_WITH_QUERY_REr¯   Ú_URL_USERINFO_RE)r%   r0   s   & r   Úredact_cdp_urlr(    sL   € ô ! u¢}¡¼#¸e»*ÓE€DßØˆÜ×!Ñ!ÙqØó€Dô ×ÑÑ MÈtÓTÐTr   c                ó0   € V ^8„  d   QhR\         R\         /# r/   r   )r
   s   "r   r   r     s   € ÷ .ñ .œCð .¤Cñ .r   c                ó¶   € V '       d8   RV 9   g1   RV 9  g*   \         P                  V P                  4       4      '       g   V # \        V P                  4       4      # )zIRedact sensitive values when the ENTIRE text is a clean ``k=v&k=v`` body.r   r  )Ú_FORM_BODY_REr—   rL   r	  r  s   &r   Ú_redact_form_bodyr,    s=   € ç�4˜4”< 3¨d¤?¼-×:MÑ:MÈdÏjÉjËl×:[Ò:[ØˆÜ §
¡
£Ó-Ð-r   c                ó0   € V ^8„  d   QhR\         R\         /# rË   r   )r
   s   "r   r   r      s   € ÷ 
Jñ 
J¤3ð 
J¬3ñ 
Jr   c                ól   a € S '       d   \        V 3R l\         4       R4      MRpV'       d   RV R2# R# )aé  Redact a prefix-matched credential to a NON-REUSABLE sentinel: no head/tail
chars (an agent once wrote a truncated-looking mask back into a config file),
only the vendor prefix label so the credential KIND stays visible.

* cannot be mistaken for a usable-but-truncated key, so an agent that reads it from a config file and
writes it back does NOT corrupt the stored credential into a dead 13-char string (issue #35519); and *
still does not leak the secret material (no head/tail chars).
c              3   óZ   <"  € T F   pSP                  V4      '       g   K  Vx € K"  	  R # 5iro   )r‰   )rr   r¯   rÌ   s   & €r   rt   Ú*_mask_token_nonreusable.<locals>.<genexpr>)  s"   øé € ÐMÑ!3˜#°u×7GÑ7GÈ×7L—#’#Ó!3ùs   ƒ+¡
+r   r„   u   â€¦Â»u   Â«redacted-secretÂ»)r#   Ú_PREFIX_SUBSTRINGS)rÌ   Úlabels   f r   Ú_mask_token_nonreusabler3     s6   ø€ ÷ W\ŒDÔMÕ!3ÓMÈrÔRÐac€Eß).ˆ[˜˜˜uÐ%ÐIÐ4IÐIr   c                ó$   € V ^8„  d   QhR\         /# )r   rŽ   r;   )r
   s   "r   r   r   -  s   € ÷ ñ ¬dñ r   c               ó   a a€ VV 3R lpV# )zbre.sub callback: keep the match unless the key/value pair (groups[0], groups[-1]) needs redaction.c                 óš   <€ V P                  4       p\        V^ ,          VR,          SR7      '       g   V P                  ^ 4      # S! V4      # )r   ©rŽ   rô   )Úgroupsrœ   r´   )rs   r8  rŽ   Úrenders   & €€r   rë   Ú_assignment_sub.<locals>._sub/  s=   ø€ Ø—‘“ˆÜ(¨°­°F¸2µJÈm×\Ó\Ø—7‘7˜1“:ÐÙ�f‹~Ðr   r   )r9  rŽ   rë   s   fd r   Ú_assignment_subr;  -  s   ù€ öð
 €Kr   Úmask_nonreusableFc                ó<   € V ^8„  d   QhR\         R\        R\         /# )r   r0   r<  r   r{   )r
   s   "r   r   r   7  s!   € ÷ 0ñ 0œcð 0¼ð 0Ìñ 0r   c               ó°  a€ V'       d   \         M\        oRV 9   d�   \        V3R lRR7      p\        P	                  W 4      p RV 9  d   \
        P	                  W 4      p RV 9  dF   \        P                  V 4      '       d+   \        P	                  W 4      p \        P	                  W 4      p RV 9   dY   RV 9   dR   \        P	                  \        V3R lR	R7      V 4      p R
V 9   d&   \        P	                  \        V3R lR	R7      V 4      p RV 9   d   RV 9   d   \        V 4      p RV 9   d-   RV 9  d&   \        P	                  \        V3R lRR7      V 4      p V # )u'  ENV / config / JSON / YAML assignment passes (skipped for code files). Passes
that would match ``token=``/``key=`` URL params skip ``://`` text (web-URL query
params are intentionally passed through, see redact_sensitive_text).

``mask_nonreusable`` masks the assignments with the ``Â«redacted:â€¦Â»`` sentinel that
``file_read=True`` already uses for prefix-matched credentials. Without it an agent
that read a secret-bearing file would hold a head/tail mask shaped like a real but
truncated key and could write it back as a dead credential (#35519).r®   c                 ó^   <€ V ^ ,           RV ^,           S! V ^,          4       V ^,           2# )r   r®   r   ©ÚgÚmasks   &€r   r  Ú%_redact_assignments.<locals>.<lambda>B  s,   ø€ °1°Qµ4°&¸¸!¸A½$¸ÁÀQÀqÅTÃ
¸|ÈAÈaÍDÈ6Ñ0Rr   Tr7  r   Ú:ræ   c                 ó<   <€ V ^ ,           RS! V ^,          4       R2# )r   z: "ræ   r   r@  s   &€r   r  rC  Y  s   ø€ ¨¨1­¨¨c±$°q¸µt³*°¸QÑ&?r   Fz\"c                 ób   <€ V ^ ,           RV ^,           RS! V ^,          4       V ^,           R2# )r   z: ræ   r   r@  s   &€r   r  rC  \  s0   ø€ ¨Q¨q­T¨F°"°Q°qµT°F¸!¹DÀÀ1Å»J¸<ÈÈ!ÍÀvÈQÑ*Or   rä   c                 óJ   <€ V ^ ,           V ^,           S! V ^,          4       2# ©r   r   r@  s   &€r   r  rC  f  s"   ø€ ¨¨1­¨¨q°­t¨f±T¸!¸A½$³Z°LÑ&Ar   )r3  rÎ   r;  Ú_ENV_ASSIGN_REr¯   Ú_ENV_ASSIGN_LOWER_REÚ_CFG_SECRET_WORD_REr†   Ú_CFG_DOTTED_REÚ_CFG_ANCHORED_REÚ_JSON_FIELD_REÚ_JSON_FIELD_ESCAPED_RErî   Ú_YAML_ASSIGN_RE)r0   r<  Ú_redact_envrB  s   &$ @r   Ú_redact_assignmentsrR  7  s*  ø€ ÷ '7Õ"¼K€DØ
ˆd„{Ü%Ô&RÐbfÔgˆÜ×!Ñ! +Ó4ˆØ˜Ôô
 (×+Ñ+¨KÓ>ˆDð ˜ÔÔ!4×!;Ñ!;¸D×!AÒ!AÜ!×%Ñ% kÓ8ˆDÜ#×'Ñ'¨Ó:ˆDà
ˆd„{�s˜d”{Ü×!Ñ!ÜÔ?ÈuÔUÐW[ó]ˆà�DŒ=Ü)×-Ñ-ÜÔ OÐ_dÔeÐgkómˆDð
 ˆd„{�s˜d”{Ü)¨$Ó/ˆð ˆd„{�u DÔ(Ü×"Ñ"ÜÔAÐQUÔVÐX\ó^ˆà€Kr   c                ó<   € V ^8„  d   QhR\         R\        R\         /# )r   r0   Ú	code_filer   r{   )r
   s   "r   r   r   j  s&   € ÷ 
hñ 
h¤#ð 
h´$ð 
h¼3ñ 
hr   c                óh   a€ V3R lp\         P                  W 4      p \        P                  R V 4      # )zODB connection-string passwords and bare-token URL userinfo (``://`` text only).c                 óþ   <€ V P                  ^4      pS'       d@   VP                  R4      '       d)   VP                  R4      '       d   V P                  ^ 4      # V P                  ^4       RV P                  ^4       2# )r   Ú{Ú}rƒ   )r´   r‰   rÓ   )rs   ÚpwrT  s   & €r   Ú
_redact_dbÚ+_redact_url_credentials.<locals>._redact_dbl  s`   ø€ ð �W‰W�Q‹Zˆß˜Ÿ™ s×+Ò+°·±¸C×0@Ò0@Ø—7‘7˜1“:ÐØ—'‘'˜!“*�˜S §¡¨£ Ð-Ð-r   c                 ó~   € V P                  ^4       \        V P                  ^4      4       V P                  ^4       2# ©r  ©r´   rÎ   r  s   &r   r  Ú)_redact_url_credentials.<locals>.<lambda>t  s5   € ¨q¯w©w°q«z¨l¼;ÀqÇwÁwÈqÃzÓ;RÐ:SÐTU×T[ÑT[Ð\]ÓT^ÐS_Ñ,`r   )Ú_DB_CONNSTR_REr¯   Ú_URL_BARE_TOKEN_RE)r0   rT  rZ  s   &f r   Ú_redact_url_credentialsrb  j  s/   ø€ õ.ô ×Ñ˜jÓ/€DÜ×!Ñ!Ñ"`ÐbfÓgÐgr   c                 óx   € V P                  ^4      p\        V4      ^8:  d   ^M^pVRV R,           W) R ,           # )r  Nz****)r´   r!   )rs   ÚphoneÚkeeps   &  r   Ú_redact_phonerf  w  s<   € Ø�G‰G�A‹J€EÜ�E“
˜a”‰1 Q€DØ��$ˆ<˜&Õ  5¨¨ =Õ0Ð0r   ÚforcerT  Ú	file_readÚsecret_fileÚredact_url_credentialsc                ól   € V ^8„  d   QhR\         R\        R\        R\        R\        R\        R\         /# )r   r0   rg  rT  rh  ri  rj  r   r{   )r
   s   "r   r   r   }  sJ   € ÷ mñ m¤ð m¬tð mÌð mÜ%)ðmÜ@Dðmä26ðmäCFñmr   c               ó  aa€ V f   R# \        V \        4      '       d   T M
\        V 4      p V '       g   V # \        V 4      p V'       g   \        4       '       g   V # T;'       g    T;'       d    V'       * p\	        V 4      '       d;   V'       d   \
        M\        o\        V S4      p \        P                  V3R lV 4      p RV 9   d/   V'       d   \
        M\        o\        P                  V3R lV 4      p V'       g   \        WR7      p RV 9   g   RV 9   d   \        P                  R V 4      p R	V 9   d/   \        P                  R
 V 4      p \        P                  R V 4      p RV 9   d   RV 9   d   \        P                  RV 4      p RV 9   d   \!        W4      p RV 9   d   \"        P                  R V 4      p V'       d   \%        V 4      p RV 9   d   RV 9   d   \'        V 4      p RV 9   d   \(        P                  \*        V 4      p V # )u`	  Apply all redaction patterns to a block of text.

Safe on any string. Enabled by default (``security.redact_secrets: false``
disables); ``force=True`` is for safety boundaries that must never return
raw secrets regardless.

``redact_url_credentials=True``: also redact credential-named query params
and the entire URL userinfo (``***:***@``) â€” off by default because OAuth-callback /
magic-link / pre-signed URLs must survive ordinary tool flows unchanged.
``code_file=True``: skip the ENV/JSON assignment passes for known source
code (``MAX_TOKENS=***``, ``"apiKey": "test"`` fixtures). ``file_read=True``
(implies code_file unless ``secret_file``): prefix-matched credentials become a
non-reusable sentinel (``Â«redacted:ghp_â€¦Â»``) instead of a head/tail mask an agent
could write back into config.yaml as a dead credential.
Every regex sits behind a cheap substring gate that its pattern requires,
so the gates are never false-negative.

Set code_file=True to also skip the Python-repr mapping pass (``{'API_KEY': 'â€¦'}``
fixtures in source); pytest/exception diagnostic lines get a narrow pass in
redact_terminal_output instead.

Set file_read=True for file *content* returned to the agent (read_file / search_files / cat). The old
mask looked like a real-but-truncated key, so an agent reading it from config.yaml and writing it back
silently corrupted the stored credential into a dead 13-char value â†’ 401 (issue #35519). The sentinel is
syntactically invalid as a token, so it can't be mistaken for a usable key or written back as one.

Set ``secret_file=True`` when the caller has already classified the SOURCE as secret-bearing
(``_is_secret_file_arg``: command reads on the terminal side, resolved tool paths on the
file side). It re-enables the ENV/JSON/YAML assignment passes that ``file_read`` would
otherwise skip, so an opaque prefix-less credential assigned to a credential-shaped key is
masked instead of passed through in cleartext (issue #110567). With ``file_read=True`` those
assignments are masked with the non-reusable sentinel, so the #35519 write-back hazard stays
closed. ``secret_file`` is authoritative: it wins over ``code_file``, so a caller cannot be
fail-open by setting both. Files that are not secret-bearing (any source file, a project's own
``config.yaml``) keep the code_file behaviour: ``MAX_TOKENS: 100`` and ``"apiKey": "test"``
fixtures are untouched.
Nc                 ó2   <€ S! V P                  ^4      4      # r]  r$  )rs   Ú_prefix_subs   &€r   r  Ú'redact_sensitive_text.<locals>.<lambda>º  s   ø€ ©°A·G±G¸A³JÔ(?r   Ú.c                 ó2   <€ S! V P                  ^4      4      # r]  r$  )rs   Ú
_zhipu_subs   &€r   r  ro  ¾  s   ø€ ©z¸!¿'¹'À!»*Ô/Er   )r<  ÚuthorizationÚUTHORIZATIONc                 ó¢   € V P                  ^4      V P                  ^4      ;'       g    R,           \        V P                  ^4      4      ,           # )r  r   r^  r  s   &r   r  ro  Ä  s8   € ¨Q¯W©W°Q«Z¸1¿7¹7À1»:×;KÐ;KÈÕ-LÌ{Ð[\×[bÑ[bÐcdÓ[eÓOfÖ-fr   rD  c                 ób   € V P                  ^4      \        V P                  ^4      4      ,           # r]  r^  r  s   &r   r  ro  Ç  s   € ¨q¯w©w°q«z¼KÈÏÉÐPQË
Ó<SÖ/Sr   c                 ó`   € V P                  ^4      ;'       g    R V P                  ^4       R2# )r  r   z:***r$  r  s   &r   r  ro  È  s(   € ¨Q¯W©W°Q«Z×-=Ð-=¸2Ð,>¸q¿w¹wÀq»z¸lÈ$Ñ*Or   ÚBEGINz-----z[REDACTED PRIVATE KEY]r   ÚeyJc                 ó6   € \        V P                  ^ 4      4      # rH  )rÎ   r´   r  s   &r   r  ro  Ö  s   € ¤[°·±¸³Ô%<r   r  r®   Ú+)r   r	   r7   rV   Ú_has_known_prefix_substringr3  rÎ   r¿   r±   r¯   Ú_ZHIPU_API_KEY_RErR  Ú_AUTH_HEADER_REÚ_SECRET_HEADER_REÚ_TELEGRAM_REÚ_PRIVATE_KEY_RErb  Ú_JWT_REr  r,  Ú_SIGNAL_PHONE_RErf  )r0   rg  rT  rh  ri  rj  rn  rr  s   &$$$$$@@r   r%  r%  }  s¨  ù€ ðP ‚|ÙÜ˜d¤C×(Ò(‰4¬c°$«i€DßØˆä)¨$Ó/€Dß”_×&Ò&Øˆð ×'Ð'˜i×<Ð<°¬_€Iô # 4×(Ò(ß1:Õ-Äˆô
 *¨$°Ó<ˆÜ�~‰~Ô?ÀÓFˆà
ˆd„{ß09Õ,¼{ˆ
Ü ×$Ñ$Ô%EÀtÓLˆçÜ" 4ÔDˆà˜Ô °4Ô!7Ü×"Ñ"Ñ#fÐhlÓmˆà
ˆd„{Ü ×$Ñ$Ñ%SÐUYÓZˆÜ×ÑÑ OÐQUÓVˆà�$„˜7 dœ?Ü×"Ñ"Ð#;¸TÓBˆð �„}Ü& tÓ7ˆà�„}Ü�{‰{Ñ<¸dÓCˆçô .¨dÓ3ˆà
ˆd„{�s˜d”{Ü  Ó&ˆà
ˆd„{Ü×#Ñ#¤M°4Ó8ˆà€Kr   c                óF   € V ^8„  d   QhR\         R\        \         ,          /# )r   Úcommandr   )r	   r¢   )r
   s   "r   r   r     s   € ÷ ñ œsð ¤t¬C¥yñ r   c                óº  € . p. pRpV  F–  pV'       d   VP                  V4       WC8X  d   RpK&  VR9   d   TpVP                  V4       KB  VR9   d=   RP                  V4      P                  4       pV'       d   VP                  V4       . pK…  VP                  V4       K˜  	  RP                  V4      P                  4       pV'       d   VP                  V4       V# )zÑPipeline/sequence segments, split only on unquoted ``| ; &`` so an
``awk '{print $1; print $2}'`` program or ``grep 'foo|bar'`` pattern stays one
segment. Backslash is not an escape (Windows ``C:\Users\...``).Nz'"z|;&r   )r³   r¥   rL   )r…  ÚsegmentsÚbufrê   Úchr“   s   &     r   Ú_command_segmentsrŠ    s½   € ð €HØ€CØ€EÛˆßØ�J‰J�rŒNØŒ{Ø�ÙØ�Œ;ØˆEØ�J‰J�rŒNÙØ�Œ;Ø—'‘'˜#“,×$Ñ$Ó&ˆCßØ—‘ Ô$ØˆCÙØ�
‰
�2Žñ! ð" �'‰'�#‹,×
Ñ
Ó
€Cß
Ø�‰˜ÔØ€Or   c                ó0   € V ^8„  d   QhR\         R\        /# )r   Úpathr   r{   )r
   s   "r   r   r   *  s   € ÷ ñ ¤ð ¬ñ r   c                ó8  € ^ RI Hp  \        P                  P	                  \        P                  P                  \        P                  P                  V 4      4      4      pT! 4        F~  p \        P                  P	                  \        P                  P                  \        T4      4      4      pY$8X  g/   TP                  T\        P                  ,           4      '       g   K}   R# 	  R#   \        \        3 d     R# i ; i  \        \        3 d     K°  i ; i)uø  True when an absolute ``config.yaml`` path sits under the active Hermes home or root.

The default home's basename is an installation detail â€” ``.hermes`` on POSIX, ``hermes``
under ``AppData/Local`` on Windows â€” and a resolved path never spells ``$HERMES_HOME``,
so the literal-segment test in ``_is_secret_file_arg`` cannot see a native Windows path.
Compare against the resolved homes instead. Only reached for a ``config.yaml`` basename,
so the resolve cost stays off the per-token command scan.
)Ú_hermes_dirsFT)Úagent.file_safetyrŽ  ÚosrŒ  ÚnormcaseÚrealpathÚ
expanduserÚOSErrorÚ
ValueErrorr	   r‰   rè   )rŒ  rŽ  ÚtargetÚhomeÚbases   &    r   Ú_is_under_hermes_homer™  *  sÐ   € õ /ðÜ—‘×!Ñ!¤"§'¡'×"2Ñ"2´2·7±7×3EÑ3EÀdÓ3KÓ"LÓMˆñ –ˆð	Ü—7‘7×#Ñ#¤B§G¡G×$4Ñ$4´S¸³YÓ$?Ó@ˆDð Œ>˜V×.Ñ.¨t´b·f±f­}×=Ô=Úñ ñ øô ”ZÐ ô Úðûô
 œÐ$ô 	Úð	ús%   ˆAC, Á,ADÃ,DÄ DÄDÄDc                ó0   € V ^8„  d   QhR\         R\        /# )r   Úargr   r{   )r
   s   "r   r   r   C  s   € ÷ Qñ QœSð Q¤Tñ Qr   c                ó¬  € V P                  R4      P                  RR4      pRp\         F,  pVP                  V4      '       g   K  V\	        V4      R pRp M	  \
         F*  pVP                  V4      '       g   K  V\	        V4      R p M	  RV9   d   R# VP                  R4       Uu. uF  qD'       g   K  VP                  4       NK  	  ppV'       g   R# VR
,          \        9   g   VR
,          \        9   d   R# VR
,          R8w  d!   VR
,          P                  R4      '       g   R# T;'       g    R	VRR
 9   ;'       g    \        V4      # u upi )a6  ``.env``-style or shell rc basename anywhere; ``config.yaml`` only under a
``.hermes`` directory, ``$HERMES_HOME``, or the resolved Hermes home (never arbitrary
YAML). The resolved-home arm is what covers native Windows, where the home directory
is ``%LOCALAPPDATA%\hermes`` and carries no ``.hermes`` segment.z"'Ú\r•   FNTr�   zconfig.yamlz.hermesrô   )zconfig.yaml.good.zconfig.yaml.corrupt.)rL   r   Ú_HERMES_HOME_PREFIXESr‰   r!   Ú_HOME_PREFIXESrš   rM   Ú_ENV_FILE_BASENAMESÚ_SHELL_RC_BASENAMESr™  )r›  rŒ  Úhermes_homeré   ÚpartÚpartss   &     r   Ú_is_secret_file_argr¥  C  s)  € ð
 �9‰9�UÓ×#Ñ# D¨#Ó.€DØ€Kß'ˆØ�?‰?˜6×"Ô"Øœ˜F›˜Ð%ˆDØˆKÙñ	 (÷
 !ˆØ�?‰?˜6×"Ô"Øœ˜F›˜Ð%ˆDÙñ !ð ˆd„{ÙØ&*§j¡j°¤oÓ>¡o˜d»Œ\ˆT�Z‰ZŽ\¡o€EÐ>ßÙØˆR…yÔ'Ô'¨5°­9Ô8KÔ+KÙð ˆR…y�MÔ!¨%°­)×*>Ñ*>Ð?l×*mÒ*mÙØ×PÐP˜) u¨S¨b zÑ1×PÐPÔ5JÈ4Ó5PÐPùò ?s   Â*	EÂ8Ec                ó>   € V ^8„  d   QhR\         R,          R\        /# ©r   r…  Nr   r{   )r
   s   "r   r   r   a  s   € ÷ ñ ¬¨d­
ð ´tñ r   c                ó   € V '       d   \        V \        4      '       g   R# \        V 4       FÙ  pVP                  4       pV'       g   K  V^ ,          P	                  R^4      R,          P                  4       pV\        9  d   KX  VR,           Uu. uF  qDP                  R4      '       d   K  VNK  	  ppV\        9   d
   VR,          p\        ;QJ d    R V 4       F  '       g   K   RM	  RM! R V 4       4      '       g   KØ   R# 	  R# u upi )zýTrue if ``command`` reads a secret-bearing file (see ``_is_secret_file_arg``) to
stdout. Defense-in-depth, not a boundary: indirect reads (``sudo cat .env``, ``$(cat
.env)``, unresolved variable paths) are not detected, matching ``is_env_dump_command``.Fr•   :r  NNr  c              3   ó8   "  € T F  p\        V4      x € K  	  R # 5iro   )r¥  )rr   r›  s   & r   rt   Ú-_command_reads_secret_file.<locals>.<genexpr>q  s   é € Ð>±:¨CÔ" 3×'Ð'³:ùó   ‚Trô   )
r   r	   rŠ  rš   ÚrsplitrM   Ú_FILE_READ_COMMANDSr‰   Ú_PATTERN_FIRST_COMMANDSrv   )r…  r“   ÚtokensÚreaderr›  Ú
positionals   &     r   Ú_command_reads_secret_filer²  a  sÊ   € ÷ œ* W¬c×2Ò2ÙÜ  Ö)ˆØ—‘“ˆßÙØ˜•×!Ñ! # qÓ)¨"Õ-×3Ñ3Ó5ˆØÔ,Ô,ÙØ%+¨B¦ZÓK¡Z˜c·~±~Àc×7J—c�c¡Zˆ
ÐKØÔ,Ô,Ø# B�ˆJß‹3Ñ>±:Ó>�3�3Š3Ñ>±:Ó>×>Ô>Úñ *ñ ùò Ls   ÂDÂ,Dc                ó>   € V ^8„  d   QhR\         R,          R\        /# r§  r{   )r
   s   "r   r   r   v  s   € ÷ ñ ¤ t¥ð ´ñ r   c                ó  € V '       d   \        V \        4      '       g   R# \        V 4       F9  p \        P                  ! V4      pV'       g   K$  V^ ,          \        9   g   K8   R# 	  R#   \
         d    TP	                  4       p LBi ; i)uš   True if any pipeline/sequence segment starts with an _ENV_DUMP_COMMANDS
token. Conservative: unrecognized â†’ False (callers fall back to code_file=True).FT)r   r	   rŠ  Úshlexrš   r•  Ú_ENV_DUMP_COMMANDS)r…  r“   r¯  s   &  r   Úis_env_dump_commandr·  v  so   € ÷ œ* W¬c×2Ò2ÙÜ  Ö)ˆð	!Ü—[’[ Ó%ˆF÷ ‰6�f˜Q•iÔ#5Ö5Úñ *ñ øô	 ô 	!Ø—Y‘Y“[ŠFð	!ús   °A+Á+B	ÂB	z[redaction-unavailable]z2\bBearer\s+(?:\[[^\]]+\]|[A-Za-z0-9._~+/-]{20,}=*)c                ó0   € V ^8„  d   QhR\         R\         /# r/   r   )r
   s   "r   r   r   Œ  s   € ÷ ñ œCð ¤Cñ r   c                ó´   € \        T ;'       g    R4      p  \        V RR7      p RT 9   d   \        P                  RT 4      p T #   \         d
    \        u # i ; i)uv  The one scrub for text leaving the process for a remote reader (chat platforms, A2A peers,
telemetry). ``redact_sensitive_text(force=True)`` â€” the only secret-pattern list â€” plus a bearer
sweep, because a ``Bearer <opaque>`` value with no vendor prefix carries no shape the prefix
matcher can key on. Fails CLOSED: if the redactor raises, the raw text is never returned.r   T)rg  ÚearerzBearer [redacted])r	   r%  rN   ÚREDACTION_UNAVAILABLEÚ_BEARER_RESIDUE_REr¯   r  s   &r   Úredact_for_egressr½  Œ  s\   € ô
 ˆt�zˆz�r‹?€Dð%Ü$ T°Ô6ˆð �$„Ü!×%Ñ%Ð&9¸4Ó@ˆØ€Køô	 ô %Ü$Ò$ð%ús   —A ÁAÁAc                óV   € V ^8„  d   QhR\         R\         R,          R\        R\         /# )r   Úoutputr…  Nrg  r   r{   )r
   s   "r   r   r   ›  s-   € ÷ ñ ¤3ð ´°tµð Ìdð Ô_bñ r   c               óì   € V '       g   V # \        V4      ;'       g    \        V4      '       * p\        WVR7      pV'       d2   V'       g   \        4       '       d   RV9   d   RV9   d   \	        V4      pV# )a  Single redaction policy for ALL terminal-output surfaces: the ENV/YAML-assignment
pass runs only when ``command`` is an env dump or reads a secret-bearing file (``.env``,
shell rc, Hermes ``config.yaml``); otherwise code_file=True avoids false positives on
source/config dumps.)rg  rT  rD  rä   )r·  r²  r%  rV   rý   )r¿  r…  rg  rT  Úredacteds   &&$  r   Úredact_terminal_outputrÂ  ›  s_   € ÷
 ØˆÜ(¨Ó1×XÐXÔ5OÐPWÓ5XÔY€IÜ$ VÀIÔN€H÷ —eœ×0Ò0°c¸X´oÈ#ÐQYÌ/Ü8¸ÓBˆØ€Or   c                ó0   € V ^8„  d   QhR\         R\         /# ©r   Úpatternr   r   )r
   s   "r   r   r   ¯  s   € ÷ ñ ¤Sð ¬Sñ r   c                óL   € Rp\        V 4       F  w  r#W19   g   K  V RV u # 	  V # )zALeading literal chars of a regex (up to the first metacharacter).z[(\.?*+|{^$N)r°   )rÅ  ÚmetarY   r‰  s   &   r   Ú_extract_literal_prefixrÈ  ¯  s0   € à€DÜ˜7Ö#‰ˆØŽ:Ø˜2˜A�;Òñ $ð €Nr   c                ó<   € V ^8„  d   QhR\         R\        R\        /# )r   rÅ  rY   r   rÆ   )r
   s   "r   r   r   ¸  s!   € ÷ ñ œcð ¤cð ¬cñ r   c                ó¸   € YV^,           V^,            R8X  d   ^M^,          pV\        V 4      8  d(   W,          R8w  d   YV,          R8X  d   ^M^,          pK7  V# )zJGiven ``pattern[i] == "["``, return the index just past the closing ``]``.Ú]r�  )r!   )rÅ  rY   s   &&r   Ú_skip_char_classrÌ  ¸  sQ   € à�a˜!•e˜A �EÐ" cÔ)‰¨qÕ0€AØ
Œc�'‹lÔ
˜w�z¨SÔ0Ø	˜!•* Ô$‰Q¨!Õ+ŠØ€Hr   c                ó<   € V ^8„  d   QhR\         R\        R\        /# )r   rÅ  re   r   rZ   )r
   s   "r   r   r   À  s!   € ÷ 
ñ 
¬3ð 
´3ð 
¼4ñ 
r   c                ó  € V\        V 4      8¼  d   R# W,          R9   d   R# W,          R8X  dS   V P                  RV4      pVR	8w  d   W^,           V MRpVRR	 P                  4       ;'       d    VP                  R4      # R# )
zSTrue if an open-ended quantifier (``*``, ``+``, ``{m,}``) starts at ``pattern[j]``.Fz*+TrW  rX  r   NÚ,rô   )r!   ÚfindÚisdigitrÓ   )rÅ  re   Úkrò   s   &&  r   Ú_unbounded_quantifier_followsrÓ  À  sw   € àŒC�‹LÔÙØ…z�TÔÙØ…z�SÔØ�L‰L˜˜aÓ ˆØ#$¨¤7ˆw˜1•u˜QÑ°ˆØ�C�Rˆy× Ñ Ó"×9Ð9 t§}¡}°SÓ'9Ð9Ùr   c                óR   € V ^8„  d   QhR\         R\        \        \        3,          /# rÄ  )r	   Útupler<   )r
   s   "r   r   r   Í  s#   € ÷  !ñ  !¤ð  !¬¬d´D¨jÕ(9ñ  !r   c                ó2  € R;rR.p^ pV\        V 4      8  dþ   W,          pVR8X  d   V^,          pK*  VR8X  d   \        W4      pMÄVR8X  d   VP                  R4       M«VR8X  d\   \        V4      ^8”  d   VP                  4       MRpV'       d   \	        W^,           4      '       d   RpVR
,          ;'       g    TVR
&   MIVR8X  d   \        V4      ^8X  d   RpM/\	        W4      '       d   RVR
&   VR8X  d   V P                  R	V4      pV^,          pEK  W3# )u  One scan â†’ ``(has_top_level_alternation, has_nested_unbounded_repeat)``.

Top-level ``|`` defeats the literal-prefix guarantee (in ``ab|.*`` the prefix
binds only the first branch; ``ab(?:x|y)`` is fine). An unbounded quantifier
on a group containing one (``(a+)+``, ``(a{2,})+``) is the canonical ReDoS
shape. Structural only; overlapping branches (``(a|aa)+``) are not detected.
Fr�  Ú[rŸ   rž   Tr�   rW  rX  rô   )r!   rÌ  r³   r    rÓ  rÐ  )rÅ  Útop_level_altÚnestedÚcontains_unboundedrY   r‰  Úinners   &      r   Ú_pattern_structurerÜ  Í  s  € ð #Ð"€MØ˜ÐØ	€AØ
Œc�'‹lÔ
Ø�ZˆØ�Œ:Ø��FˆAÙØ�Œ9Ü  Ó,‰AØ�3ŒYØ×%Ñ% eÕ,Ø�3ŒYÜ03Ð4FÓ0GÈ!Ô0KÐ&×*Ñ*Ô,ÐQVˆEßÔ6°wÀAÅ×FÒFØ�Ø%7¸Õ%;×%DÐ%D¸uÐ˜rÒ"Ø�3ŒYœ3Ð1Ó2°aÔ7Ø ‰MÜ*¨7×6Ò6Ø%)Ð˜rÑ"Ø�SŒyØ—L‘L  aÓ(�Ø	ˆQ�‹ØÐ Ð r   c                ó0   € V ^8„  d   QhR\         R\        /# rÄ  r{   )r
   s   "r   r   r   ð  s   € ÷ *ñ *¬ð *´ñ *r   c                 ó&   € \        V 4      ^ ,          # rH  ©rÜ  ©rÅ  s   &r   Ú_has_top_level_alternationrá  ð  ó   € Ü˜gÓ& qÕ)Ð)r   c                ó0   € V ^8„  d   QhR\         R\        /# rÄ  r{   )r
   s   "r   r   r   ô  s   € ÷ *ñ *¬#ð *´$ñ *r   c                 ó&   € \        V 4      ^,          # r]  rß  rà  s   &r   Ú_has_nested_unbounded_repeatrå  ô  râ  r   c              #   ó8   "  € T F  p\        V4      x € K  	  R # 5iro   ©rÈ  ©rr   r‡   s   & r   rt   rt   ø  s   é € ÐPÑ?O¸!Ô2°1×5Ð5Ó?Oùr«  c                ó0   € V ^8„  d   QhR\         R\        /# r/   r{   )r
   s   "r   r   r   û  s   € ÷ 6ñ 6¤cð 6¬dñ 6r   c                óˆ   a € \         ;QJ d#    V 3R l\         4       F  '       g   K   R# 	  R# ! V 3R l\         4       4      # )z4Cheap pre-check before the expensive ``_PREFIX_RE``.c              3   ó,   <"  € T F	  qS9   x € K  	  R # 5iro   r   )rr   r‡   r0   s   & €r   rt   Ú._has_known_prefix_substring.<locals>.<genexpr>ý  s   øé € Ð5Ñ"4˜Q�DŽyÓ"4ùs   ƒTF)rv   r1  r  s   fr   r|  r|  û  s.   ø€ ç‹3Ô5Õ"4Ó5�3Œ3Ð5Š3Ð5ˆ3Ô5Õ"4Ó5Ó5Ð5r   c                ó$   € V ^8„  d   QhR\         /# r   )r¢   )r
   s   "r   r   r   
  s   € ÷ Rñ Rœ$ñ Rr   c                 óh   € \         P                  4        U Uu. uF  q  F  qNK  	  K  	  upp # u upp i )z5All plugin-registered patterns in registration order.)Ú_PLUGIN_PREFIX_PATTERNSr6   )r¡   r‡   s     r   Ú_plugin_patternsrð  
  s-   € ä5×<Ñ<Ô>ÔQÑ>�(ÊÀ1ŠAÉ‰AÑ>ÒQÐQùÓQs   ˜.c                ó   € V ^8„  d   QhRR/# r   r   )r
   s   "r   r   r     s   € ÷ Mñ M ñ Mr   c                 ó¢   € \         \        4       ,           p \        V 4      s\        ;QJ d    . R V  4       F  NK  	  5sR# ! R V  4       4      sR# )z�Recompile the prefix alternation and pre-screen substrings; callers read the
module globals at call time, so the swap propagates immediately.c              3   ó8   "  € T F  p\        V4      x € K  	  R # 5iro   rç  rè  s   & r   rt   Ú*_rebuild_prefix_matcher.<locals>.<genexpr>  s   é € ÐLÁ8¸aÔ6°q×9Ð9Ã8ùr«  N)Ú_PREFIX_PATTERNSrð  r¦   r±   rÕ  r1  )Úcombineds    r   Ú_rebuild_prefix_matcherr÷    s>   € ô  Ô"2Ó"4Õ4€HÜ(¨Ó2€JßœÑLÁ8ÓLŸÒ˜ÑLÁ8ÓLÓLÒr   uÔ   %s: skipping redaction pattern %r â€” top-level alternation escapes the literal-prefix guarantee (in 'ab|.*' the prefix binds only the first branch); wrap alternation in a group after the prefix, e.g. 'ab(?:x|y)'u¯   %s: skipping redaction pattern %r â€” nested unbounded quantifiers (e.g. '(a+)+') can backtrack catastrophically, and registered patterns run on every log line and tool outputc                 ó0   € \        \        V 4      4      ^8  # )r   )r!   rÈ  rà  s   &r   r  r  "  s   € ”SÔ0°Ó9Ó:¸QÒ>r   u~   %s: skipping redaction pattern %r â€” must start with at least 2 literal characters (needed for the pre-screen substring gate)c                ó0   € V ^8„  d   QhR\         R\        /# )r   Úsourcer   rÆ   )r
   s   "r   r   r   (  s   € ÷  ñ  ´#ð  ÄSñ  r   c                óž  a€ . pT ;'       g    .  Fó  o\        S\        4      '       d   SP                  4       '       g   \        P	                  RV4       KG  SP                  4       o \
        P                  ! S4       \        T3R l\         4       R4      pT'       d   \        P	                  YAS4       K¨  S\        9   g   S\        4       9   g   ST9   d   \        P                  RTS4       Kâ  TP                  S4       Kõ  	  V'       dg   \        ;_uu_ 4        \        P!                  V. 4      P#                  V4       \%        4        RRR4       \        P'                  RV\)        V4      4       \)        V4      #   \
        P                   d%   p\        P	                  RTST4        Rp?EK¤  Rp?ii ; i  + '       g   i     Lw; i)u  Additively register credential-token regexes; returns the count accepted.

Invalid entries (non-compiling, top-level alternation, nested unbounded
quantifiers, < 2 literal prefix chars) and duplicates are warned/skipped,
never raised â€” a broken plugin must not break startup.
z/%s: skipping empty/non-string redaction patternz.%s: skipping invalid redaction pattern %r (%s)Nc              3   óL   <"  € T F  w  rV! S4      '       g   K  Vx € K  	  R # 5iro   r   )rr   ÚrejectÚmessagerÅ  s   &  €r   rt   Ú.register_redaction_patterns.<locals>.<genexpr>:  s    øé € ÐaÑ8M¡_ VÑQWÐX_×Q`ŸšÓ8Mùs   ƒ$š
$z+%s: redaction pattern %r already registeredz&%s: registered %d redaction pattern(s))r   r	   rL   ÚloggerÚwarningrk   r¤   Úerrorr#   Ú_PATTERN_REJECT_RULESrõ  rð  Údebugr³   Ú_registry_lockrï  r   Úextendr÷  Úinfor!   )r¡   rú  ÚacceptedÚexcÚrejectedrÅ  s   &&   @r   Úregister_redaction_patternsr  (  sO  ø€ ð €HØ—>�>˜r’>ˆÜ˜'¤3×'Ò'¨w¯}©}¯ªÜ�N‰NÐLÈfÔUÙØ—-‘-“/ˆð	Ü�JŠJ�wÔô ÔaÕ8MÓaÐcgÓhˆßÜ�N‰N˜8¨WÔ5ÙØÔ&Ô&¨'Ô5EÓ5GÔ*GÈ7ÐV^ÔK^Ü�L‰LÐFÈÐPWÔXÙØ�‰˜Ö ñ# "÷& ßŽ^Ü#×.Ñ.¨v°rÓ:×AÑAÀ(ÔKÜ#Ô%÷ ô 	�‰Ð<¸fÄcÈ(ÃmÔTÜˆx‹=Ðøô# �x‰xô 	Ü�N‰NÐKÈVÐU\Ð^aÔbÞûð	ú÷ �^ús$   Á(F Ä0F<Æ F9ÆF4Æ4F9Æ<G	c                ó   € V ^8„  d   QhRR/# r   r   )r
   s   "r   r   r   K  s   € ÷ "ñ "¨$ñ "r   c                 ó˜   € \         ;_uu_ 4        \        P                  4        \        4        RRR4       R#   + '       g   i     R# ; i)z:Drop all plugin-registered patterns (tests/teardown only).N)r  rï  Úclearr÷  r   r   r   Ú _reset_plugin_redaction_patternsr  K  s%   € ç	ŽÜ×%Ñ%Ô'ÜÔ!÷ 
��Šúr-   c                   óB   a a€ ] tR tRt oRtV3R lV 3R lltRtVtV ;t# )ÚRedactingFormatteriR  z9Log formatter that redacts secrets from all log messages.c                ó:   <€ V ^8„  d   QhRS[ P                  RS[/# )r   Úrecordr   )ÚloggingÚ	LogRecordr	   )r
   Ú__classdict__s   "€r   r   ÚRedactingFormatter.__annotate__U  s!   ø€ ÷ =ñ =™W×.Ñ.ð =±3ñ =r   c                ó4   <€ \        \        SV `	  V4      4      # ro   )r%  Úsuperr
   )Úselfr  Ú	__class__s   &&€r   r
   ÚRedactingFormatter.formatU  s   ø€ Ü$¤U¡W¡^°FÓ%;Ó<Ð<r   r   )	Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r
   Ú__static_attributes__Ú__classdictcell__Ú__classcell__)r  r  s   @@r   r  r  R  s   ù‡ € ÙC÷=÷ =ó =r   r  c                ó�   € V ^8„  d   Qh/ ^ \         9   d
   \        ;R&   ^\         9   d
   \        ;R&   ^\         9   d
   \        ;R&   # )r   r   rI   rï  )Ú__conditional_annotations__Údict)r
   s   "r   r   r      sH   € ÷ ñ ÷H #Ò "œÑ "ñI÷X #Ò "œÑ "ñY÷J( #Ò "œÑ "òK(r   >   Újwtr2   ÚsigÚauthÚcoderÌ   ÚapikeyÚsecretÚapi_keyÚsessionÚid_tokenÚpasswordÚ	signatureÚaccess_tokenÚclient_secretÚrefresh_tokenúx-amz-signatureúx-goog-signature>   rE   rF   rG   r9   >   rÌ   r,  ÚbearerÚpasswdr-  r.  r0  r1  Ú
auth_tokenÚ
credentialÚ
raw_secretÚcredentialsÚprivate_keyr3  Úkey_materialÚsecret_inputÚsecret_valueÚauthorizationr4  r5  )Ú_API_KEYÚ_TOKENÚ_SECRETÚ	_PASSWORDÚ_PASSWDÚ_CREDENTIALÚ_CREDENTIALS)r,  r.  rÌ   r-  r1  r9  r;  r=  )z	x-api-keyzx-goog-api-keyzapi-keyr,  zx-api-tokenzx-auth-tokenzx-access-token>   ÚenvÚsetÚexportÚdeclareÚprintenv>   ÚnlÚawkÚbatÚcatÚsedÚtacÚgreprÀ   ÚlessÚmorerÁ   ÚtypeÚviewÚzcatÚbatcat>   ú.zshrcú.bashrcú.zloginú.zshenvú.profileú	.zprofileú.bash_loginú.bash_profile>   rP  rS  rU  )z$HERMES_HOME/z${HERMES_HOME}/)z$HOME/z${HOME}/ro   )Úplugin)�r&  r!  r  r�  rk   rµ  Ú	threadingÚurllib.parser   r�  r   r   Ú	getLoggerr  r   ÚREDACT_WALK_MAX_DEPTHÚREDACT_WALK_DEPTH_MARKERr"   r   ÚLockr   r   r)   r,   r7   Ú	frozensetr  ÚgetenvrM   rH   rI   rO   rV   rõ  Ú_SECRET_ENV_NAMESr¤   rI  Ú
IGNORECASErJ  Ú_SECRET_CFG_NAMESÚ_LINE_NUMBER_GUTTERÚ
_CFG_VALUErK  r–   rL  Ú	MULTILINErM  Ú_YAML_CFG_NAMESrP  r}   r›   r™   Ú_SHELL_VAR_REFr˜   r’   rb   rh   rx   r   rŒ   rœ   Ú_JSON_KEY_NAMESrN  rO  rÒ   rÔ   rÕ   rí   rö   r÷   r~  ÚSECRET_HEADER_NAME_LISTr¥   Ú_SECRET_HEADER_NAMESr  r€  r�  r`  ra  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,  r3  r;  rR  rb  rf  r%  r¶  r­  r¡  r®  rž  rŸ  rŠ  r™  r¥  r²  r·  r»  r¼  r½  rÂ  rÈ  rÌ  rÓ  rÜ  rá  rå  rÕ  r1  r|  rï  r  rð  r÷  r  r  r  Ú	Formatterr  r   )r&  s   @r   Ú<module>ry     sÀ	  øðöó Û 	Û 	Û Û Ý %õ Tà	×	Ò	˜8Ó	$€ð
 Ð Ø6Ð ð $&Ð  Ø "Ð Ó "Ø!ŸšÓ(Ð õ"õ
+õ(:õ
ñ  $ò %ó Ð ð —)’)Ð3°VÓ<×BÑBÓDÐHbÑb€ð !#Ð Ó "Ø —~’~Ó'Ð õðDEð 0ðEð ðEð $ðEð ðEð ðEð ðEð ðEð "ðEð  $ð!Eð" ð#Eð$ ð%Eð& ð'Eð( ð)Eð* "ð+Eð,  ð-Eð. ð/Eð0  ð1Eð2  ð3Eð4  ð5Eð6 ð7Eð8 ð9Eð: ð;Eð< ð=Eð> ð?Eð@ ðAEðB ðCEðJ $ðKEðL ðMEðN ðOEðP ðQEðR ðSEðT ðUEðV !ðWEðX ðYEðZ ð[Eð\ ð]Eð^ ð_Eð` ðaEðb ðcEðd ðeEðf ðgEðl !ðmEðn !ðoEðp  ðqEðr !ðsEðt "ðuEðv !ðwEðx !ðyEðz  ð{Eð| !ð}Eð~ #ðEð@ "ðAEðB "ðCEðD  ðEEðF $ðGEðH ðIEÐ ð^ ]Ð Ø—’Ð1Ð2CÐ1DÐDlÐmÓn€ð —z’zð KØ‡M�MóÐ ð$ WÐ ð
 8Ð Ø/€
à—j’jÐ!2°B·M±MÓBÐ ð —z’zÐ"UÓVÐ ð —’ð+Ø+<Ð*=ð >Ø*Ð+ð ,	Ø	ˆðð ‡M�Mó€ð —:’:ØÐ#Ð$Ð$DÐEVÐDWÐWhÐisÐhtÐuØ‡M�M�B—L‘LÕ óÐ ð P€Ø—*’*ØÐ$Ð%Ð%5°oÐ5FÐFuÐvØ‡M�M�B—L‘LÕ ó€ð* —*’*ðAà‡M�Mó€ð ŸšðSà‡M�MóÐ ð —:’:Ð8¸"¿-¹-ÓHÐ ð =€ØŸ
š
 d¨>Ð*:Ð:PÐQ_ÐP`Ð`cÐ#dÓeÐ ð
 Ÿ*š*Ð%[Ó\Ð õVðW¸÷ Wõpõ
;õ
Wõ5ðB Z€Ø—’˜r /Ð!2Ð2DÐEÀrÇ}Á}ÓU€ð Ÿš w¨Ð.?Ð?YÐ$ZÐ\^×\iÑ\iÓjÐ ñ %ò &ó Ð ð,Ð ð	$Ð  ð Ÿ
š
ð	óÐ ð  ŸZšZÐ(UÓVÐ ØŸJšJð8óÐ ð —*’*Ð_Ðac×anÑanÓo€ð @Ð Ø˜cŸh™hÐ'>Ó?Ð@ÀÐBÐ Ø—J’J !Ð$8Ð#9¸ÐGÈÏÉÓWÐ ð �zŠzÐGÓH€à—*’*ÐhÓi€ð —’ØVØ‡M�Mó€ð  —Z’Zðð ‡M�Mó	Ð ð �*Š*ÐJÓ
K€ð —:’:ÐAÓBÐ ð —Z’ZÐ ^Ó_Ð Ø—:’:ÐLÓMÐ ð
 —z’zÐ"SÓTÐ ð Ÿ*š*Ð%5Ó6Ð ð —
’
ÐfÓg€ð —J’JÐWÓXÐ ñ
 ÐaÓbÐ õ[ñ %Ð%5Ó6€
ð —J’JØLóÐ õ
!ðL —j’jÐ!cÓdÐ ðV¨1ð V¸!ð VÈ"ð VØ#(ðVØ79÷Võ8õ=õ Dõ1õDõ.õUõ;õUõ".õ
Jõð0¸u÷ 0õf
hò1ðm°eð mÈuð mØ,1ðmØGLðmà9>÷mñn ÒNÓOÐ ñ  ò !ó Ð ñ  ò !ó Ð ñ $Ò$:Ó;Ð Ø<Ð ð (€õõ<õ2Qõ<õ*ð 2Ð ð —Z’ZÐ UÐWY×WdÑWdÓeÐ õñÐUZ÷ ð õ(õõ
õ !õF*õ*÷ �UÑPÑ?OÓP—U‘UÑPÑ?OÓPÓPÐ õ6ð !#Ð Ó "Ø—’Ó!€õRõ
Mð  ð2ð3ð "ðaðbñ ?ð2ð3ðÐ ÷ õF"ô=˜×*Ò*ö =r   