+
    iHàj‰a  ã                  óº  € R t ^ RIHt ^ RI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HtHt ^ RIHt ^ RIHtHt ^ RIHt ]P,                  ! 4       tRt^t^dtR	tR]t^t0 R^mt]P>                  ! R
]P@                  4      t!]P>                  ! RRPE                  ]#! ]]$RR7      4      ,           R,           4      t%R_t&R`t'Rat(. RbO. RcO. RdO. ReO. RfO3t)Rgt*]
! RR7       ! R R4      4       t+]
! RR7       ! R R4      4       t,R R lt-R R lt.R R lt/R R lt0R t1R R lt2R R/R! R" llt3R# R$ lt4R% R& lt5R' R( lt6R) R* lt7R+ R, lt8R- R. lt9R/ R0 lt:R1 R2 lt;R3 R4 lt<R5 R6 lt=R7 R8 lt>RhR9 R: llt?R; R< lt@R= R> ltAR? R@ ltBRA RB ltCRC RD ltDRERRFRRG^ RHRI/RJ RK lltERHRI/RL RM lltFRFRRNRORPRQRHRI/RR RS lltGRT RU ltHRVR/RW RX lltIRY RZ ltJR[ R\ ltKR# )iuß   Coding verification evidence ledger: records what the agent actually proved in
a code workspace. Deliberately passive â€” it never runs a suite, never blocks
completion, and never upgrades targeted checks into "repo green".)ÚannotationsN)Ú	dataclass)ÚdatetimeÚ	timedeltaÚtimezoneÚUTC)ÚPath)ÚAnyÚOptional©Úget_hermes_homeiÐ  i'  z\.(?:exe|bat|cmd)$z^(?:Ú|T)ÚkeyÚreversez)(?:[0-9]+(?:\.[0-9]+)*)?$)Úfrozenc                  ó0   € ] tR t^\t$ R]R&   RtR]R&   RtR# )Ú_ShellSegmentú	list[str]ÚtokensNú
str | NoneÚfollowing_operator© )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__annotations__r   Ú__static_attributes__r   ó    Ú@/home/ubuntu/.hermes/hermes-agent/agent/verification_evidence.pyr   r   \   s   ‡ àÓØ%)Ð˜
×)r   r   c                  ó„   € ] tR t^bt$ RtR]R&   R]R&   R]R&   R]R&   R]R&   R]R	&   R]R
&   R]R&   R]R&   RtR]R&   RtR# )ÚVerificationEvidencez,A classified command result worth recording.ÚstrÚcommandÚcanonical_commandÚkindÚscopeÚstatusÚintÚ	exit_codeÚcwdÚrootÚ
session_idÚ Úoutput_summaryr   N)r   r   r   r   Ú__doc__r   r.   r   r   r   r   r!   r!   b   s=   ‡ á6àƒLØÓØ
ƒIØƒJØƒKØƒNØ	ƒHØ
ƒIØƒOØ€N�C×r   r!   c               ó   € V ^8„  d   QhRR/# )é   Úreturnr"   r   )Úformats   "r   Ú__annotate__r4   r   s   € ÷ )ñ )�#ñ )r   c                 óR   € \         P                  ! \        4      P                  4       # ©N)r   Únowr   Ú	isoformatr   r   r   Ú_utc_nowr9   r   s   € Ü�<Š<œÓ×&Ñ&Ó(Ð(r   c               ó   € V ^8„  d   QhRR/# )r1   r2   r   r   )r3   s   "r   r4   r4   v   s   € ÷ :ñ :�$ñ :r   c                 ó$   € \        4       R ,          # )úverification_evidence.dbr   r   r   r   Ú_db_pathr=   v   s   € ÜÓÐ9Õ9Ð9r   c               ó   € V ^8„  d   QhRR/# )r1   r2   Úboolr   )r3   s   "r   r4   r4   z   s   € ÷ $ñ $˜ñ $r   c                 ó   € ^ RI Hp  V ! 4       # )z¦The ledger exists only to feed verify-on-stop; when that guard is off nothing may
record, read, or even create the database (an unconsumed ledger is pure disk churn).©Úverify_on_stop_enabled)Úagent.verification_stoprB   rA   s    r   Ú_ledger_enabledrD   z   s   € õ ?á!Ó#Ð#r   c               ó   € V ^8„  d   QhRR/# )r1   r2   úsqlite3.Connectionr   )r3   s   "r   r4   r4   ‚   s   € ÷ _ñ _Ð$ñ _r   c                 ó<   € ^ RI Hp  V ! \        4       R\        R7      # )é    ©Úopen_dbr<   )Údb_labelÚ
initialize)Úhermes_cli.sqlite_utilrJ   r=   Ú_ensure_schemarI   s    r   Ú_connectrO   ‚   s   € Ý.á”8“:Ð(BÌ~Ô^Ð^r   c                 ó.   € ^ RI Hp  V ! \        4       4      # )rH   ©Útransaction)rM   rR   rO   rQ   s    r   Ú_transactionrS   ˆ   s   € Ý2á”x“zÓ"Ð"r   c               ó    € V ^8„  d   QhRRRR/# )r1   ÚconnrF   r2   ÚNoner   )r3   s   "r   r4   r4   Ž   s   € ÷ ñ Ð+ð °ñ r   c                ó¢   € \          F  pV P                  V4       K  	  V P                  R \        \        4      34       V P	                  4        R# )zDINSERT OR REPLACE INTO meta(key, value) VALUES ('schema_version', ?)N)Ú_SCHEMA_DDLÚexecuter"   Ú_VERIFY_SCHEMA_VERSIONÚcommit)rU   Úddls   & r   rN   rN   Ž   s>   € ßˆØ�‰�SÖñ à‡L�LØNÜ	Ô#Ó	$Ð&ôð 	‡K�K†Mr   Úposixc               ó$   € V ^8„  d   QhRRRRRR/# )r1   r#   r"   r]   r?   r2   úlist[_ShellSegment]r   )r3   s   "r   r4   r4   ˜   s"   € ÷ :?ñ :? 3ð :?°$ð :?ÐBUñ :?r   c               óh  € . p^ pRpRp^ pV\        V 4      8  Ed.   W,          pV'       g   VR8X  d   VR8w  d   V'       * pV^,          pKA  V'       g   VR9   d    Wt8X  d   RMT;'       g    TpV^,          pKo  RpV P                  RV4      '       d   WV^,            pMMVR8X  d   RpMCVR9   g;   VR	8X  d6   V^ 8X  g   W^,
          ,          R
9  d   V P                  RV4      '       g   TpVf   V^,          pKñ  WV P                  4       p	V	'       g   . # VP                  W˜34       YgR8X  d   ^M
\        V4      ,          pTpEK>  V'       g	   V'       d   . # WR P                  4       p
V
'       d   VP                  V
R34       MV'       d   VR,          ^,          R8w  d   . #  V U	Uu. uF&  w  r˜\	        \
        P                  ! W‘R7      V4      NK(  	  pp	p\        ;QJ d    R T 4       F  '       d   K   RM	  RM! R T 4       4      '       d   T# . # u upp	i   \         d    . u # i ; i)zäTokenize top-level shell commands while preserving their control operators.

Returns ``[]`` for anything unparseable (unbalanced quotes, empty segment,
trailing operator other than ``;``) so callers never match a partial parse.
NFÚ\Ú'z'"Ú
Ú;z;|Ú&z<>©r]   c              3  ó8   "  € T F  qP                   x € K  	  R # 5ir6   )r   ©Ú.0Úss   & r   Ú	<genexpr>Ú(_split_shell_segments.<locals>.<genexpr>Ò   s   é € Ð6©X¨Ÿ8ž8«Xùs   ‚T)ú&&ú||ú|&)z&>z&>>éÿÿÿÿ)	ÚlenÚ
startswithÚstripÚappendr   ÚshlexÚsplitÚ
ValueErrorÚall)r#   r]   Úraw_segmentsÚstartÚquoteÚescapedÚindexÚcharÚoperatorÚrawÚtrailingÚsegmentss   &$          r   Ú_split_shell_segmentsrƒ   ˜   sû  € ð 24€LØ€EØ€EØ€GØ€Eà
”#�g“,Õ
Ø�~ˆß�t˜t”|¨°¬Ø!”kˆGØ�Q�JˆEÙß�D˜E”MØ œM‘D°·°¸ˆEØ�Q�JˆEÙàˆØ×ÑÐ0°%×8Ò8Ø U¨Q¥YÐ/‰HØ�TŒ\Ø‰HØ�TŒ\Ø�CŒKØ˜!”˜w¨q¥yÕ1¸Ô=Ø×&Ñ& }°e×<Ò<àˆHàÒØ�Q�JˆEÙà˜EÐ"×(Ñ(Ó*ˆßØˆIØ×Ñ˜S˜OÔ,Ø˜d”l‘¬¨H«Õ5ˆØ‹ç—Øˆ	Ø�vˆ×$Ñ$Ó&€HßØ×Ñ˜X tÐ,Õ-ß	˜, rÕ*¨1Õ-°Ô4Øˆ	ðÙ`lÔmÑ`lÉ}Ès”M¤%§+¢+¨cÔ"?ÀÖJÑ`lˆÑm÷ “sÑ6©XÓ6—s—s’sÑ6©XÓ6×6Ò6ˆ8Ð>¸BÐ>ùó nøÜô ØŠ	ðús$   Æ)H! Æ.,HÇH! ÈH! È!H1È0H1c               ó(   € V ^8„  d   QhRRRRRRRR/# )r1   r‚   r_   Úmatch_indexr(   r)   r2   r?   r   )r3   s   "r   r4   r4   Õ   s1   € ÷ Jñ JÐ+>ð JÈSð JÐ]`ð JÐeiñ Jr   c                óÐ  € V '       dW   ^ Tu;8:  d   \        V 4      8  d?   M R# \        ;QJ d    R V  4       F  '       g   K   RM	  RM! R V  4       4      '       d   R# \        R \        V RR 4       4       ^ R7      pW8  d   R# WR  Uu0 uF  qDP                  kK  	  ppV0 R	m,          '       d   R# V'       * ;'       g    \        V4      ^ 8H  ;'       d    VR08H  # u upi )
zÝWhether the shell's status proves the matched segment's own status.

Only the last ``;``-separated sequence reports its status; backgrounding,
pipes and ``||`` hide it; an ``&&`` chain proves each member only on success.
c              3  ó>   "  € T F  qP                   R 8H  x € K  	  R# 5i)re   N©r   rh   s   & r   rk   Ú/_exit_status_is_attributable.<locals>.<genexpr>Û   s   é € ÐBqÑhpÐcd×CWÑCWÐ[^ÖC^Óhpùs   ‚TFc              3  ó^   "  € T F#  w  rVP                   R 8X  g   K  V^,           x € K%  	  R# 5i)rd   Nrˆ   )ri   Úirj   s   &  r   rk   r‰   ß   s)   é € ÐSÑ3‘4�1°q×7KÑ7KÈsÑ7RŒˆˆQ�ŠÓ3ùs   ‚-œ-N)Údefaultrm   rp   >   r   ro   rn   )rq   ÚanyÚmaxÚ	enumerater   r(   )r‚   r…   r)   Úsequence_startÚsegmentÚ	operatorss   &&&   r   Ú_exit_status_is_attributabler“   Õ   sÌ   € ÷ ˜1 Ö;¬c°(«mÖ;Ù÷ @C»sÑBqÑhpÓBq¿s¿sºsÑBqÑhpÓBq×?qÒ?qÙäÙSœ9 X¨c¨r ]Ô3ÓSÐ]^ô€Nð Ô#Ùà;CÐSUÑ;VÓWÑ;V°×+Ô+Ñ;V€IÐWØÒ$×$Ô$ÙØŒ=×IÐIœS ›^¨qÑ0×HÐH°YÀ4À&Ñ5HÐIùò Xs   ÂC#c               ó    € V ^8„  d   QhRRRR/# )r1   Ú	canonicalr"   r2   r   r   )r3   s   "r   r4   r4   ê   s   € ÷ ñ  ð ¨ñ r   c           	     óÚ   €  \         P                  ! V 4       Uu. uF2  q'       g   K  \        P                  ! RRVP	                  4       4      NK4  	  up# u upi   \
         d    . u # i ; i)zGTokenize a canonical command, stripping leading ``./`` from each token.z	^(?:\./)+r-   )ru   rv   ÚreÚsubrs   rw   )r•   Úts   & r   Ú_canonical_tokensrš   ê   sW   € ðÜ=B¿[º[ÈÔ=SÓYÑ=S¸ÓWXÔ3”—’�| R¨¯©«Ö3Ñ=SÑYÐYùÒYøÜô ØŠ	ðús'   ‚A š	A¨*AÁA ÁA ÁA*Á)A*c               ó    € V ^8„  d   QhRRRR/# )r1   r   r   r2   r   )r3   s   "r   r4   r4   ò   s   € ÷ ñ  )ð °	ñ r   c                ó*  € V '       d   V ^ ,          R8X  d   ^M^ pV\        V 4      8  d6   RW,          9   d)   W,          P                  R4      '       g   V^,          pKE  V\        V 4      8  d   W,          R9   d   V^,          pK(  \        WR 4      # )zCRemove harmless command prefixes (env, VAR=x, command/time/noglob).ÚenvÚ=Ú-N>   ÚtimeÚnoglobr#   )rq   rr   Úlist)r   r‹   s   & r   Ú_strip_command_prefixr£   ò   sr   € ç˜˜q�	 UÔ*‰°€AØ
Œc�&‹kŒ/˜c V¥YÔ.°vµy×7KÑ7KÈC×7PÒ7PØ	ˆQ�ŠØ
Œc�&‹kŒ/˜f�iÐ+HÔHØ	ˆQ�ŠÜ��r�
ÓÐr   c               ó    € V ^8„  d   QhRRRR/# )r1   Úneedler   r2   zlist[list[str]]r   )r3   s   "r   r4   r4   ü   s   € ÷ 	ñ 	 	ð 	¨oñ 	r   c                óF  € V .p\        V 4      ^8¼  d>   V ^,          R8X  d0   V ^ ,          R9   d"   VP                  V ^ ,          V ^,          .4       \        V 4      ^8X  d,   RV ^ ,          9   d   VRV ^ ,          .RV ^ ,          ..,          pV R.8X  d   V\        ,          pV# )zFReturn command spellings equivalent to the detected canonical command.ÚrunÚ/ÚbashÚshÚpytest>   ÚbunÚnpmÚpnpmÚyarn)rq   rt   Ú_PYTEST_SPELLINGS)r¥   Ú
candidatess   & r   Ú_equivalent_needlesr²   ü   sš   € à�€JÜ
ˆ6ƒ{�aÔ˜F 1�I¨Ô.°6¸!µ9Ð@^Ô3^Ø×Ñ˜6 !�9 f¨Q¥iÐ0Ô1Ü
ˆ6ƒ{�aÔ˜C 6¨!¥9Ô,Ø˜  q¥	Ð*¨T°6¸!µ9Ð,=Ð>Õ>ˆ
Ø�(�ÔØÔ'Õ'ˆ
ØÐr   c               ó(   € V ^8„  d   QhRRRRRRRR/# )	r1   r#   r"   Úcanonical_commandsr   r)   r(   r2   zOptional[tuple[str, list[str]]]r   )r3   s   "r   r4   r4     s*   € ÷ ñ  3ð ¸Ið ÐRUð ÐZyñ r   c                óF  € \        V 4      pV F�  p\        V4      pV'       g   K  \        V4       Fh  w  rg\        VP                  4      p\        V4       F?  p	VR\        V	4       V	8X  g   K  \        W6V4      '       g   K,  WH\        V	4      R 3u u u # 	  Kj  	  K‘  	  R# )zEReturn ``(canonical, trailing_args)`` for the first detected command.N)rƒ   rš   r�   r£   r   r²   rq   r“   )
r#   r´   r)   r‚   r•   r¥   r}   r‘   Úcandidate_tokensÚ	candidates
   &&&       r   Ú_find_canonical_matchr¸     s�   € ä$ WÓ-€HÛ'ˆ	Ü" 9Ó-ˆßÙÜ'¨Ö1‰NˆEÜ4°W·^±^ÓDÐÜ0°Ö8�	Ø# O¤S¨£^Ð4¸	ÖAÔFbÐckÐt}×F~ÔF~Ø$´s¸9³~°Ð&GÐGÖGó 9ó 2ñ	 (ñ r   c               ó    € V ^8„  d   QhRRRR/# )r1   r•   r"   r2   r   )r3   s   "r   r4   r4     s   € ÷ Yñ Y ð Y¨ñ Yr   c                ó�   a€ V P                  4       o\        V3R  l\         4       R4      pT;'       g    RS9   d
   RS9  d   R# R# )c              3  ó°   <"  € T FK  w  r\         ;QJ d    V3R  lV 4       F  '       g   K   RM	  RM! V3R  lV 4       4      '       g   KG  Vx € KM  	  R# 5i)c              3  ó,   <"  € T F	  qS9   x € K  	  R # 5ir6   r   )ri   ÚwÚlowereds   & €r   rk   Ú._kind_for_command.<locals>.<genexpr>.<genexpr>  s   øé € Ð8UÉuÈ!¸g¾Ëuùó   ƒTFN)r�   )ri   ÚwordsÚkr¾   s   &  €r   rk   Ú$_kind_for_command.<locals>.<genexpr>  s2   øé € ÐV¡>‘x�u·S³SÔ8UÉuÓ8U·S·S²SÔ8UÉuÓ8U×5U—’£>ùs   ƒ&A¬AÁ
ANÚcheckÚtest)ÚlowerÚnextÚ_KIND_KEYWORDS)r•   r%   r¾   s   & @r   Ú_kind_for_commandrÉ     sD   ø€ Ø�o‰oÓ€GÜÔV¥>ÓVÐX\Ó]€DØ×XÐX˜w¨'Ô1°fÀGÔ6K�GÐXÐQWÐXr   c               ó    € V ^8„  d   QhRRRR/# )r1   Úargr"   r2   r?   r   )r3   s   "r   r4   r4     s   € ÷ ñ ˜Cð  Dñ r   c                óh  a € \        S 4      ;'       d     S P                  R 4      '       * ;'       d‚    RS 9  ;'       du    \        ;QJ d    V 3R lR 4       F  '       g   K   RM	  RM! V 3R lR 4       4      ;'       g3    S P                  \        4      ;'       g    S P                  \
        4      # )rŸ   rž   c              3  ó,   <"  € T F	  qS9   x € K  	  R # 5ir6   r   )ri   ÚmrË   s   & €r   rk   Ú%_looks_like_target.<locals>.<genexpr>  s   øé € Ð0Ñ/˜�ŽHÓ/ùrÀ   TF)r¨   ra   z::)r?   rr   r�   ÚendswithÚ_TARGET_EXTENSIONSÚ_TARGET_PREFIXES)rË   s   fr   Ú_looks_like_targetrÓ     sˆ   ø€ Ü�‹9÷ ð ˜SŸ^™^¨CÓ0Ô0÷ ð °SÀ±^÷ ð ß‹Ô0Ñ/Ó0��ŠÔ0Ñ/Ó0Ó0×xÐx°C·L±LÔASÓ4T×xÐxÐX[×XfÑXfÔgwÓXxðr   c               ó$   € V ^8„  d   QhRRRRRR/# )r1   Útokenr"   Úbaseústr | Path | Noner2   r?   r   )r3   s   "r   r4   r4   #  s"   € ÷ ñ �Sð Ð 1ð °dñ r   c                ó>  € V'       g   R#  \        V 4      P                  4       pVP                  4       '       g   R# VP                  4       \        V4      P                  4       P                  4       rCW48H  ;'       g    WCP                  9   #   \
         d     R# i ; i)zJWhether absolute path ``token`` is ``base`` or lies beneath it (resolved).F)r   Ú
expanduserÚis_absoluteÚresolveÚparentsÚ	Exception)rÕ   rÖ   ÚpathÚresolvedÚ	base_paths   &&   r   Ú	_is_underrá   #  s€   € çÙðÜ�E‹{×%Ñ%Ó'ˆØ×Ñ×!Ò!ÙØ"Ÿl™l›n¬d°4«j×.CÑ.CÓ.E×.MÑ.MÓ.O�)ØÑ$×EÐE¨	×5EÑ5EÑ(EÐEøÜô Úðús   Œ/B ½AB ÂBÂBc               ó$   € V ^8„  d   QhRRRRRR/# )r1   rÕ   r"   r+   r×   r2   r?   r   )r3   s   "r   r4   r4   1  s'   € ÷ Dñ D ð DÐ+<ð DÀñ Dr   c                ó  €  \        V 4      P                  4       P                  pTP	                  \
        4      ;'       d8    \        T \        P                  ! 4       4      ;'       d    \        Y4      '       * #   \         d     R# i ; i)zMAn ad-hoc verify script: prefixed name, under the temp dir, outside the repo.F)	r   rÙ   ÚnamerÝ   rr   Ú_AD_HOC_SCRIPT_NAME_PREFIXESrá   ÚtempfileÚ
gettempdir)rÕ   r+   rä   s   && r   Ú_is_temp_script_pathrè   1  s†   € ðÜ�E‹{×%Ñ%Ó'×,Ñ,ˆð �?‰?Ô7Ó8÷  Dð  D¼YÀuÌh×NaÒNaÓNcÓ=d÷  Dð  DÔmvÐw|ó  nDô  jDð  Døô ô Úðús   ‚#A9 Á9BÂBc               ó    € V ^8„  d   QhRRRR/# )r1   rÕ   r"   r2   r?   r   )r3   s   "r   r4   r4   :  s   € ÷ 	Rñ 	R ð 	R¨ñ 	Rr   c                ó¸   € V P                  RR4      P                  R^4      R,          p\        \        P	                  \
        P                  RV4      4      4      # )aB  Whether a command word names a shell interpreter.

``python3``, ``python3.12`` and ``/usr/bin/python3.12`` are the same interpreter; matching
only the bare token left the ad-hoc branch blind to the invocation shapes the nudge hands
the agent, so a passing run recorded no evidence and the workspace stayed ``unverified``.
ra   r¨   r-   rp   )ÚreplaceÚrsplitr?   Ú_INTERPRETER_NAME_REÚmatchÚ_WINDOWS_EXE_SUFFIX_REr˜   )rÕ   rä   s   & r   Ú_is_interpreter_tokenrð   :  sK   € ð �=‰=˜˜sÓ#×*Ñ*¨3°Ó2°2Õ6€DÜÔ$×*Ñ*Ô+A×+EÑ+EÀbÈ$Ó+OÓPÓQÐQr   c               ó$   € V ^8„  d   QhRRRRRR/# )r1   r   r   r+   r×   r2   úOptional[list[str]]r   )r3   s   "r   r4   r4   F  s#   € ÷ ñ  	ð Ð1Bð ÐGZñ r   c                óú  € \        V 4      pV'       g   R # V^ ,          p\        W14      '       d
   VR,          # \        V4      P                  R8X  d:   \	        V4      ^8”  d*   \        V^,          4      '       d   VR,          V^,          r2\        V4      '       d_   \        VR,          ^R7       FF  w  rE\        WQ4      '       d   W$^,           R  u # VR8w  g   K,  VP                  R4      '       d   KE   R # 	  R # )N:é   NNr�   )rz   z--rŸ   )r£   rè   r   rä   rq   rð   r�   rr   )r   r+   r¶   r#   ÚidxrÕ   s   &&    r   Ú_ad_hoc_script_argsrö   F  sÔ   € Ü,¨VÓ4ÐßÙØ˜qÕ!€GÜ˜G×*Ò*Ø Õ#Ð#ÜˆGƒ}×Ñ˜UÔ"¤sÐ+;Ó'<¸qÔ'@ÔEZÐ[kÐlmÕ[n×EoÒEoà$4°RÕ$8Ð:JÈ1Õ:M˜'Ü˜W×%Ò%ä#Ð$4°RÕ$8À×B‰JˆCÜ# E×0Ò0Ø'¨a­¨Ð1Ò1Ø˜Ž} U×%5Ñ%5°c×%:Ô%:Úñ	 Cñ
 r   c               ó(   € V ^8„  d   QhRRRRRRRR/# )	r1   r#   r"   r+   r×   r)   r(   r2   rò   r   )r3   s   "r   r4   r4   Z  s*   € ÷ ñ  ð Ð+<ð Èð ÐUhñ r   c                óÀ   € R FW  p\        WR7      p\        V4       F9  w  rV\        VP                  V4      pVf   K!  \	        WEV4      '       g   K5  Vu u # 	  KY  	  R# )Trf   N)TF)rƒ   r�   rö   r   r“   )r#   r+   r)   r]   r‚   r}   r‘   Útrailing_argss   &&&     r   Ú_find_ad_hoc_matchrú   Z  sV   € ãˆÜ(¨Ô>ˆÜ'¨Ö1‰NˆEÜ/°·±ÀÓEˆMØÔ(Ô-IÈ(Ð[d×-eÔ-eØ$Ô$ó 2ñ ñ r   c               ó    € V ^8„  d   QhRRRR/# )r1   Úoutputr"   r2   r   )r3   s   "r   r4   r4   e  s   € ÷ ñ ˜cð  cñ r   c                óØ   € T ;'       g    R P                  4       p\        V4      \        8:  d   V# \        ^,          pVRV  R\        V4      \        ,
           RW\        ,
          R  2# )r-   Nz
... [z chars omitted] ...
)rs   rq   Ú_MAX_OUTPUT_SUMMARY_CHARS)rü   ÚtextÚheads   &  r   Ú_summarize_outputr  e  sm   € Ø�LˆL�b×ÑÓ!€DÜ
ˆ4ƒyÔ-Ô-ØˆÜ$¨Õ)€Dà��ˆ;ˆ-�wœs 4›yÔ+DÕDÐEÐEZØÔ0Õ0Ð1Ð2Ð
3ð	5ðr   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r1   rU   rF   r,   r"   r+   r2   rV   r   )r3   s   "r   r4   r4   p  s*   € ÷  ñ  Ð.ð  ¸sð  È#ð  ÐRVñ  r   c               ó,  € \         P                  ! \        4      \        \        R7      ,
          P                  4       pV P                  RWW\        34       V P                  RW334       V P                  RV34       V P                  R\        34       R# )u  Bound ledger growth without deleting the current state pointer.

Order matters: per-(session, root) cap, expire stale state rows, then expire
old events and cap the total â€” never dropping an event still referenced
by a ``verification_state.last_event_id``.
)Údaysz°DELETE FROM verification_events WHERE session_id = ? AND root = ? AND id NOT IN ( SELECT id FROM verification_events WHERE session_id = ? AND root = ? ORDER BY id DESC LIMIT ?)z¾DELETE FROM verification_state WHERE (last_edit_at IS NOT NULL AND last_edit_at < ?) OR (last_edit_at IS NULL AND last_event_id IN ( SELECT id FROM verification_events WHERE created_at < ?))z’DELETE FROM verification_events WHERE created_at < ? AND id NOT IN ( SELECT last_event_id FROM verification_state WHERE last_event_id IS NOT NULL)zÌDELETE FROM verification_events WHERE id NOT IN ( SELECT id FROM verification_events ORDER BY id DESC LIMIT ?) AND id NOT IN ( SELECT last_event_id FROM verification_state WHERE last_event_id IS NOT NULL)N)	r   r7   r   r   Ú_MAX_EVIDENCE_AGE_DAYSr8   rY   Ú_MAX_EVENTS_PER_SESSION_ROOTÚ_MAX_TOTAL_UNREFERENCED_EVENTS)rU   r,   r+   Úcutoffs   &$$ r   Ú_prune_old_eventsr	  p  s•   € ô �lŠlœ3Ó¤)Ô1GÔ"HÕH×SÑSÓU€FØ‡L�Lð	%ð 
˜:Ô-IÐJô	ð 	‡L�Lð	Eð 
Ðôð 	‡L�Lð	Yà	ˆ	ôð
 	‡L�Lð	Yô 
(Ð)ör   c               ó    € V ^8„  d   QhRRRR/# )r1   r*   r×   r2   úOptional[dict[str, Any]]r   )r3   s   "r   r4   r4   “  s   € ÷ ñ Ð)ð Ð.Fñ r   c                óD   €  ^ RI Hp V! V 4      #   \         d     R# i ; i)zLWorkspace facts for ``cwd``; ``None`` when detection fails or finds nothing.)Úproject_facts_forN)Úagent.coding_contextr  rÝ   )r*   r  s   & r   Ú_project_factsr  “  s'   € ðÝ:á  Ó%Ð%øÜô Úðús   ‚ �žc               ó$   € V ^8„  d   QhRRRRRR/# )r1   Úfactszdict[str, Any] | Noner*   r×   r2   r"   r   )r3   s   "r   r4   r4   �  s(   € ÷ Hñ HÐ*ð HÐ1Bð HÀsñ Hr   c                ó    € \        T ;'       g    / P                  R 4      ;'       g$    \        T;'       g    R4      P                  4       4      # )r+   Ú.)r"   Úgetr   rÛ   )r  r*   s   &&r   Ú	_root_forr  �  s:   € Ü�—�˜× Ñ  Ó(×FÐF¬D°·°¸Ó,<×,DÑ,DÓ,FÓGÐGr   c               ó    € V ^8„  d   QhRRRR/# )r1   r€   r	   r2   z	list[Any]r   )r3   s   "r   r4   r4   ¡  s   € ÷ ñ ˜Sð  Yñ r   c                óv   €  \         P                  ! T ;'       g    R 4      #   \        \        3 d    . u # i ; i)z[])ÚjsonÚloadsÚ	TypeErrorrw   )r€   s   &r   Ú_load_changed_pathsr  ¡  s5   € ðÜ�zŠz˜#Ÿ+˜+ Ó&Ð&øÜ”zÐ"ô ØŠ	ðús   ‚" ›" ¢8·8r*   r,   r)   rü   r-   c               ó0   € V ^8„  d   QhRRRRRRRRR	RR
R/# )r1   r#   r"   r*   r×   r,   r   r)   r(   rü   r2   zOptional[VerificationEvidence]r   )r3   s   "r   r4   r4   ¨  s<   € ÷ ñ ØðØ+ðØ@JðØ^aðØorðà#ñr   c               ó°  € V '       d   \        V \        4      '       g   R# \        V4      pV'       g   R# \        VP	                  R4      ;'       g    . 4      p\        W\        V4      4      pVe4   Vw  r‰\        V4      p
\        \        \        V	4      4      '       d   RMRpM5V'       g'   \        WP	                  R4      \        V4      4      f   R# RRRrºp\        YY«\        V4      ^ 8X  d   RMR	\        V4      \        \        T;'       g    R
4      P                  4       4      \        WQ4      \        T;'       g    R4      \!        V4      R7
      # )zÂClassify a terminal command as verification evidence, if applicable.

Ad-hoc temp scripts only count when the project has no canonical verify
commands at all, so they never shadow a real suite.
NÚverifyCommandsÚtargetedÚfullr+   zad-hoc verification scriptÚad_hocÚpassedÚfailedr  rŒ   ©
r#   r$   r%   r&   r'   r)   r*   r+   r,   r.   )Ú
isinstancer"   r  r¢   r  r¸   r(   rÉ   r�   ÚmaprÓ   rú   r!   r   rÛ   r  r  )r#   r*   r,   r)   rü   r  Úverify_commandsrî   r•   rù   r%   r&   s   &$$$$       r   Úclassify_verification_commandr(  ¨  s  € ÷ œ* W¬c×2Ò2ÙÜ˜3Ó€EßÙä˜5Ÿ9™9Ð%5Ó6×<Ð<¸"Ó=€OÜ! '¼CÀ	»NÓK€EØÒØ#(Ñ ˆ	Ü  Ó+ˆÜ!¤#Ô&8¸-Ó"H×IÒI‘
Èv‰çÔ0°¿)¹)ÀFÓ:KÌSÐQZË^Ó\ÒdÙØ!=¸xÈ˜ˆ	ÜØ¸4Ü˜y›>¨QÔ.‰x°HÌÈIËÜ”�S—Z�Z˜CÓ ×(Ñ(Ó*Ó+´)¸EÓ2GÜ�z×.Ð. YÓ/Ô@QÐRXÓ@Yô	ð r   c               ó0   € V ^8„  d   QhRRRRRRRRR	RR
R/# )r1   r#   r"   r*   r×   r,   r   r)   r(   rü   r2   r  r   )r3   s   "r   r4   r4   È  sD   € ÷ Dñ DØðDØ+ðDØ9CðDØPSðDØ]`ðDàñDr   c                ód   € \        4       '       g   R# \        WW#VR7      pVf   R# \        V4      # )zERecord a foreground terminal result when it is verification evidence.N)r*   r,   r)   rü   )rD   r(  Ú_insert_evidence)r#   r*   r,   r)   rü   Úevidences   $$$$$ r   Úrecord_terminal_resultr-  È  s5   € ô ×ÒÙÜ,¨WÈ*ÐrxÔy€HØÒ#ˆ4ÐCÔ)9¸(Ó)CÐCr   r#   úhermes verifyr&   r   c               ó4   € V ^8„  d   QhRRRRRRRRR	RR
RRR/# )r1   r+   z
str | Pathr,   r   Úokr?   r#   r"   r&   rü   r2   r  r   )r3   s   "r   r4   r4   Ò  sF   € ÷ ñ ØðØ%/ðØ<@ðØKNðàðà!$ðð ñr   c                ó‚  € \        4       '       g   R# \        \        V 4      P                  4       4      p\	        \        TRRVR
9   d   TMRV'       d   RMRV'       d   ^ M^T\        \        V 4      ;'       g    / P                  R4      ;'       g    T4      \        T;'       g    R4      \        V4      R	7
      4      # )a  Record a completed ``hermes verify`` run as verification evidence.

A pass marks the workspace ``passed`` for the verify-on-stop guard like a
canonical test command would. ``root`` is re-resolved through project facts
so it matches what :func:`verification_status` derives later.
Nr.  Úverifyr   r"  r#  r+   rŒ   r$  >   r   r  )	rD   r"   r   rÛ   r+  r!   r  r  r  )r+   r,   r0  r#   r&   rü   rß   s   $$$$$$ r   Úrecord_verify_runr3  Ò  s    € ô ×ÒÙÜ”4˜“:×%Ñ%Ó'Ó(€HÜÔ0Ø¨?ÀØÐ 4Ô4‰e¸&ß‰x 8¿B±qÀAÈ8Ü”. Ó&×,Ð,¨"×1Ñ1°&Ó9×EÐE¸XÓFÜ�z×.Ð. YÓ/Ô@QÐRXÓ@Yôó ð r   c               ó    € V ^8„  d   QhRRRR/# )r1   r,  r!   r2   údict[str, Any]r   )r3   s   "r   r4   r4   è  s   € ÷ &Dñ &DÐ3ð &D¸ñ &Dr   c                ó¸  € \        4       pT p\        ;_uu_ 4        \        4       ;_uu_ 4       pVP                  RWP                  VP
                  VP                  VP                  VP                  VP                  VP                  VP                  VP                  VP                  34      pVP                  f   \        R4      h\!        VP                  4      pVP                  RVP                  VP                  V34       VP                  R8X  dK   VP                  R8X  d:   VP                  R8X  d)   VP                  RWRP                  VP                  34       \#        W2P                  VP                  R	7       VP%                  4        RRR4       RRR4       R
X/VP&                  CRV/C#   + '       g   i     L,; i  + '       g   i     L7; i)zAInsert a classified evidence row and repoint the workspace state.z¸INSERT INTO verification_events( created_at, session_id, cwd, root, command, canonical_command, kind, scope, status, exit_code, output_summary) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)Nz.verification event insert did not return an ida  INSERT INTO verification_state( session_id, root, last_event_id, last_edit_at, changed_paths_json) VALUES (?, ?, ?, NULL, '[]') ON CONFLICT(session_id, root) DO UPDATE SET last_event_id = excluded.last_event_id, last_edit_at = NULL, changed_paths_json = '[]'r2  r"  r   z‚UPDATE verification_state SET last_event_id = ?, last_edit_at = NULL, changed_paths_json = '[]' WHERE root = ? AND session_id != ?)r,   r+   ÚidÚ
created_at)r9   Ú_DB_LOCKrS   rY   r,   r*   r+   r#   r$   r%   r&   r'   r)   r.   Ú	lastrowidÚRuntimeErrorr(   r	  r[   Ú__dict__)r,  r8  ÚerU   ÚcurÚevent_ids   &     r   r+  r+  è  s`  € ä“€JØ€Aß	Ž”<—>”> TØ�l‰lð9ð Ÿ™ q§u¡u¨a¯f©f°a·i±iÀ×ATÑATÐVW×V\ÑV\Ð^_×^eÑ^eØ�X‰X�q—{‘{ A×$4Ñ$4ð6ó
ˆð �=‰=Ò ÜÐOÓPÐPÜ�s—}‘}Ó%ˆØ�‰ð)ð �\‰\˜1Ÿ6™6 8Ð,ô		
ð �6‰6�XÔ !§(¡(¨hÔ"6¸1¿7¹7ÀfÔ;LØ�L‰Lð6ð Ÿ6™6 1§<¡<Ð0ô	ô 	˜$¯<©<¸a¿f¹fÕEØ�‰Œ÷A "�ðD �(ÐC˜aŸj™jÐC¨,¸
ÑCÐC÷E "—>ú��ús#   ›G	®E$F6	ÆG	Æ6GÇG	Ç	G	Úpathsc               ó(   € V ^8„  d   QhRRRRRRRR/# )	r1   r,   r   r*   r×   r@  z"list[str] | tuple[str, ...] | Noner2   r  r   )r3   s   "r   r4   r4     s2   € ÷ "hñ "hØð"hØ$5ð"hØ>`ð"hàñ"hr   c                ó  € \        4       '       g   R# \        V4      pV'       g   R# \        T ;'       g    R4      p\        W14      p\	        T;'       g    .  Uu0 uF  qf'       g   K  \        V4      kK  	  up4      p\        4       p\        ;_uu_ 4        \        4       ;_uu_ 4       p	V	P                  RWE34      P                  4       p
V
e   \        V
R,          4      M. p\	        \        V4      \        V4      ,          4      R
R pV	P                  RWEV\        P                  ! V4      34       V	P                  4        RRR4       RRR4       RVRVRVR	V/# u upi   + '       g   i     L'; i  + '       g   i     L2; i)z>Mark verification evidence stale after a successful file edit.NrŒ   zSSELECT changed_paths_json FROM verification_state WHERE session_id = ? AND root = ?Úchanged_paths_jsonzÿINSERT INTO verification_state( session_id, root, last_event_id, last_edit_at, changed_paths_json) VALUES (?, ?, NULL, ?, ?) ON CONFLICT(session_id, root) DO UPDATE SET last_edit_at = excluded.last_edit_at, changed_paths_json = excluded.changed_paths_jsonr,   r+   Úlast_edit_atÚchanged_pathsi8ÿÿÿ)rD   r  r"   r  Úsortedr9   r9  rS   rY   Úfetchoner  Úsetr  Údumpsr[   )r,   r*   r@  r  Úsidr+   ÚprE  Ú	edited_atrU   ÚrowÚexistingÚmergeds   $$$          r   Úmark_workspace_editedrP    s<  € ô ×ÒÙÜ˜3Ó€EßÙä
ˆj×%Ð%˜IÓ
&€CÜ�UÓ €DÜ¨U¯[¨[°b¨[Ó?©[ q»QœFœC žF©[Ñ?Ó@€MÜ“
€Iç	Ž”<—>”> TØ�l‰lØaØˆKó
÷ ‰(‹*ð 	ð
 FIÂ_Ô& sÐ+?Õ'@ÔAÐZ\ˆÜœ˜H›¬¨MÓ(:Õ:Ó;¸D¸EÐBˆØ�‰ð@ð ˜	¤4§:¢:¨fÓ#5Ð6ô	
ð 	�‰Œ÷# "�ð& ˜#˜v t¨^¸YÈÐYfÐgÐgùò- @÷ "—>ú��ús1   Á	EÁ)EÂE6Â*BE#	ÅE6Å#E3Å.E6Å6F	c               ó(   € V ^8„  d   QhRRRRRRRR/# )	r1   rU   rF   r+   r"   Úsincer   r2   zOptional[sqlite3.Row]r   )r3   s   "r   r4   r4   6  s,   € ÷ ñ Ø
ðØ'*ðØ3=ðàñr   c               ó–   € V'       d"   V P                  RW34      P                  4       # V P                  RV34      P                  4       # )zXLatest full passing ``hermes verify`` for ``root``, optionally not older than ``since``.zšSELECT * FROM verification_events WHERE root = ? AND kind = 'verify' AND status = 'passed' AND scope = 'full' AND created_at >= ? ORDER BY id DESC LIMIT 1z†SELECT * FROM verification_events WHERE root = ? AND kind = 'verify' AND status = 'passed' AND scope = 'full' ORDER BY id DESC LIMIT 1)rY   rG  )rU   r+   rR  s   &$$r   Ú_newest_workspace_verifyrT  6  sU   € ÷ Ø�|‰|ð(ð ˆMó
÷ ‰(‹*ð	ð �<‰<ð	$ð 
ˆó	÷
 �hƒjðr   c               ó$   € V ^8„  d   QhRRRRRR/# )r1   r,   r   r*   r×   r2   r5  r   )r3   s   "r   r4   r4   J  s'   € ÷ *dñ *d zð *dÐ8Ið *dÈnñ *dr   c                óÆ  € \        4       '       g   RRRR/# \        V4      pV'       g   RRRR/# \        T ;'       g    R4      p\        W!4      p\        ;_uu_ 4        \        4       ;_uu_ 4       pVP                  RW434      P                  4       pVf!   RRRRR	VR
VR. /uuRRR4       uuRRR4       # RpVR,          e)   VP                  RVR,          34      P                  4       pVR,          p\        VRJ;'       d    T;'       d    W‡R,          8„  4      p	Ve	   V	'       d   \        WTVR7      p
V
e   T
pRp	RRR	VR
VR\        VR,          4      /pVf   RR/VCuuRRR4       uuRRR4       # \        V4      pRV	'       d   RMVR,          /VCRV/CuuRRR4       uuRRR4       #   + '       g   i     M; iRRR4       R#   + '       g   i     R# ; i)a  Return the best known verification state for a session/workspace.

Evidence recorded before the latest edit is reported as ``stale``. A
``hermes verify`` event for the same ``root`` that is at least as new as
that edit satisfies the guard even if another session recorded it.
r'   Údisabledr,  NÚnot_applicablerŒ   zpSELECT last_event_id, last_edit_at, changed_paths_json FROM verification_state WHERE session_id = ? AND root = ?Ú
unverifiedr+   r,   rE  Úlast_event_idz.SELECT * FROM verification_events WHERE id = ?rD  r8  )r+   rR  FrC  Ústale)rD   r  r"   r  r9  rS   rY   rG  r?   rT  r  Údict)r,   r*   r  rJ  r+   rU   ÚstateÚeventrD  r[  ÚsharedÚresultr,  s   $$           r   Úverification_statusra  J  sÇ  € ô ×ÒØ˜* j°$Ð7Ð7Ü˜3Ó€EßØÐ*¨J¸Ð=Ð=ä
ˆj×%Ð%˜IÓ
&€CÜ�UÓ €Dß	Ž”<—>”> TØ—‘ðIàˆKó
÷ ‰(‹*ð	 	ð
 Š=Ø˜l¨J¸¸fÀdÈLÐZ]Ð_nÐprÐs÷ "‘>�Šð ˆØ�Õ!Ò-Ø—L‘LÐ!QÐTYÐZiÕTjÐSlÓm×vÑvÓxˆEØ˜^Õ,ˆÜ�U $Ð&×^Ð^¨<×^Ð^¸LÐQ]ÕK^Ñ<^Ó_ˆØŠ=ŸEÜ-¨dÀ\ÔRˆFØÒ!Ø�Ø�ð ˜˜f d¨L¸#ØÔ0°Ð7KÕ1LÓMð
ˆð Š=Ø˜lÐ5¨fÐ5÷1 "‘>�Šô4 ˜“;ˆØ§U™'°¸Õ0BÐcÀfÐcÈjÐZbÑc÷7 "‘>�Š—>—>ú���ŠúsO   ÁGÁ11F2	Â"
GÂ7AF2	Ä	F2	ÄF2	Ä+8F2	Å#
GÅ8%F2	Æ
GÆ2GÆ=GÇG 	)zhermes-verify-zhermes-ad-hoc->   Úpyrª   r©   ÚnodeÚperlÚrubyÚpythonÚpython3)z.pyz.jsz.jsxz.tsz.tsxz.rsz.goz.java)Útest_ÚtestsÚspecÚ	__tests__)))ÚlintÚeslintÚruffrl  ))Ú	typecheckÚtscÚmypyÚpyrightÚtyro  ))Úbuildrt  ))Úfmtr3   r3   )rf  ú-mr«   )rg  rv  r«   )Úuvr§   r«   )Úpoetryr§   r«   )Úpipenvr§   r«   )z
        CREATE TABLE IF NOT EXISTS meta (
            key TEXT PRIMARY KEY,
            value TEXT NOT NULL
        )
        a  
        CREATE TABLE IF NOT EXISTS verification_events (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            created_at TEXT NOT NULL,
            session_id TEXT NOT NULL,
            cwd TEXT NOT NULL,
            root TEXT NOT NULL,
            command TEXT NOT NULL,
            canonical_command TEXT NOT NULL,
            kind TEXT NOT NULL,
            scope TEXT NOT NULL,
            status TEXT NOT NULL,
            exit_code INTEGER NOT NULL,
            output_summary TEXT NOT NULL
        )
        a9  
        CREATE TABLE IF NOT EXISTS verification_state (
            session_id TEXT NOT NULL,
            root TEXT NOT NULL,
            last_event_id INTEGER,
            last_edit_at TEXT,
            changed_paths_json TEXT NOT NULL DEFAULT '[]',
            PRIMARY KEY (session_id, root)
        )
        z‹
        CREATE INDEX IF NOT EXISTS idx_verification_events_session_root
        ON verification_events(session_id, root, id DESC)
        )rH   )Lr/   Ú
__future__r   r  r—   ru   Úsqlite3ræ   Ú	threadingÚdataclassesr   r   r   r   r   Úpathlibr   Útypingr	   r
   Úhermes_constantsr   ÚLockr9  rþ   r  r  r  rå   rZ   Ú_INTERPRETERSÚcompileÚ
IGNORECASErï   ÚjoinrF  rq   rí   rÑ   rÒ   rÈ   r°   rX   r   r!   r9   r=   rD   rO   rS   rN   rƒ   r“   rš   r£   r²   r¸   rÉ   rÓ   rá   rè   rð   rö   rú   r  r	  r  r  r  r(  r-  r3  r+  rP  rT  ra  r   r   r   Ú<module>r†     s(  ðñEõ #ã Û 	Û Û Û Û Ý !ß 7Ó 7Ý ß  å ,ð �>Š>Ó€Ø Ð ØÐ Ø"Ð Ø!'Ð ØCÐ ØÐ âQ€àŸšÐ$9¸2¿=¹=ÓIÐ ð
 —z’zØˆc�h‰h‘v˜m°¸dÔCÓDÕDÐGdÕdóÐ ð RÐ Ø:Ð ð€ò Ò ;ÚÒ8Ò:UðÐ ð%€ñP �$Ô÷*ð *ó ð*ñ
 �$Ô÷ð ó ðõ)õ:õ$õ_ò#õð:?¸÷ :?õzJõ*õõ	õõYõõõDõ	Rõ÷(õõ õFõHõðØ.2ðØMQðØdeðØuw÷ð@DØce÷DðØ26ðØQ`ðàðà')÷õ,&DðR"hØcg÷"hõJ÷(*dr   