§
    ÷žyj¢W  ã                  óT  — d Z ddlmZ ddlZddlZddlZddlZddlZddlZddl	m
Z
 ddlmZ ddlmZmZmZ ddlmZ ddlmZmZmZ dd	lmZ  ej        ¦   «         Zd
ZdZdZdZdZdZ ej         d¦  «        Z! ed¬¦  «         G d„ d¦  «        ¦   «         Z"dad„Z#dad„Z$dbd„Z%dcd„Z&e
ddd„¦   «         Z'ded!„Z(dd"œdfd'„Z)dgd)„Z*dhd,„Z+did0„Z,djd1„Z-dkd2„Z.dld5„Z/dmd6„Z0dnd8„Z1dod:„Z2dpd;„Z3dqd>„Z4dqd?„Z5drdA„Z6dsdB„Z7dtdD„Z8dudF„Z9ddddGdHœdvdN„Z:dGdOœdwdQ„Z;ddRdSdGdTœdxdX„Z<dyd[„Z=dd\œdzd_„Z>d{d`„Z?dS )|a  Coding verification evidence ledger.

This module records what the agent actually proved while working in a code
workspace. It is deliberately passive: it never decides to run a suite, never
blocks completion, and never upgrades targeted checks into "repo green".
é    )ÚannotationsN)Úcontextmanager)Ú	dataclass)ÚdatetimeÚ	timedeltaÚtimezone)ÚPath)ÚAnyÚIteratorÚOptional©Úget_hermes_homeiÐ  é   éd   i'  )zhermes-verify-zhermes-ad-hoc-é   z\s*(?:&&|\|\||;)\s*T)Úfrozenc                  ó|   — e Zd ZU dZded<   ded<   ded<   ded<   ded<   ded	<   ded
<   ded<   ded<   dZded<   dS )ÚVerificationEvidencez,A classified command result worth recording.ÚstrÚcommandÚcanonical_commandÚkindÚscopeÚstatusÚintÚ	exit_codeÚcwdÚrootÚ
session_idÚ Úoutput_summaryN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú__annotations__r!   © ó    úA/home/ragecks/.hermes/hermes-agent/agent/verification_evidence.pyr   r   #   s}   € € € € € € à6Ð6à€L€L�LØÐÐÑØ€I€I�IØ€J€J�JØ€K€K�KØ€N€N�NØ€H€H�HØ€I€I�IØ€O€O�OØ€NÐÐÐÑÐÐr(   r   Úreturnr   c                 ób   — t          j        t          j        ¦  «                             ¦   «         S ©N)r   Únowr   ÚutcÚ	isoformatr'   r(   r)   Ú_utc_nowr0   3   s    € ÝŒ<�œÑ%Ô%×/Ò/Ñ1Ô1Ð1r(   c                 óŽ   — t          j        t          j        ¦  «        t	          t
          ¬¦  «        z
                       ¦   «         S )N)Údays)r   r-   r   r.   r   Ú_MAX_EVIDENCE_AGE_DAYSr/   r'   r(   r)   Ú_retention_cutoffr4   7   s1   € ÝŒL�œÑ&Ô&­Õ8NÐ)OÑ)OÔ)OÑO×ZÒZÑ\Ô\Ð\r(   r	   c                 ó$   — t          ¦   «         dz  S )Núverification_evidence.dbr   r'   r(   r)   Ú_db_pathr7   ;   s   € ÝÑÔÐ9Ñ9Ð9r(   úsqlite3.Connectionc                 ó\  — ddl m}  t          ¦   «         }|j                             dd¬¦  «         t          j        |¦  «        }t
          j        |_        	  | |d¬¦  «         | 	                    d¦  «         t          |¦  «         n## t          $ r |                     ¦   «          ‚ w xY w|S )Nr   )Úapply_wal_with_fallbackT)ÚparentsÚexist_okr6   )Údb_labelzPRAGMA busy_timeout=5000)Úhermes_stater:   r7   ÚparentÚmkdirÚsqlite3ÚconnectÚRowÚrow_factoryÚexecuteÚ_ensure_schemaÚ	ExceptionÚclose)r:   ÚpathÚconns      r)   Ú_connectrK   ?   sÅ   € Ø4Ð4Ð4Ð4Ð4Ð4å‰:Œ:€DØ„K×Ò˜d¨TÐÑ2Ô2Ð2ÝŒ?˜4Ñ Ô €DÝ”{€DÔðØÐ Ð/IÐJÑJÔJÐJØ�ŠÐ/Ñ0Ô0Ð0Ý�tÑÔÐÐøÝð ð ð ð 	�
Š
‰ŒˆØð	øøøð
 €Ks   Á1B	 Â	 B)úIterator[sqlite3.Connection]c               #  ó¾   K  — t          ¦   «         } 	 | 5  | V — ddd¦  «         n# 1 swxY w Y   |                      ¦   «          dS # |                      ¦   «          w xY w)uù  Open a connection, commit/rollback on exit, and ALWAYS close it.

    ``sqlite3.Connection.__enter__``/``__exit__`` only commit or roll back the
    transaction; they do not close the connection. Using ``with _connect()``
    alone therefore leaks a connection â€” and its WAL/SHM file descriptors â€” on
    every call, deferring the close to the garbage collector, which over a
    long-running process can exhaust ``RLIMIT_NOFILE`` (the cron-ledger sibling
    of this bug was #69567 / PR #69594).
    N)rK   rH   ©rJ   s    r)   Ú_transactionrO   R   sŸ   è è € õ ‰:Œ:€DðØð 	ð 	ØˆJˆJˆJð	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ð 	øøøð 	ð 	ð 	ð 	ð 	�
Š
‰Œˆˆˆøˆ�
Š
‰Œˆˆøøøs&   ’A ”%™A ¥)©A ¬)­A ÁArJ   ÚNonec                ó(  — |                       d¦  «         |                       d¦  «         |                       d¦  «         |                       d¦  «         |                       dt          t          ¦  «        f¦  «         |                      ¦   «          d S )Nz
        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)
        zDINSERT OR REPLACE INTO meta(key, value) VALUES ('schema_version', ?))rE   r   Ú_VERIFY_SCHEMA_VERSIONÚcommitrN   s    r)   rF   rF   e   s±   € Ø‡L‚Lð	ñô ð ð 	‡L‚Lð	ñô ð ð$ 	‡L‚Lð		ñô ð ð 	‡L‚Lð	ñô ð ð 	‡L‚LØNÝ	Õ#Ñ	$Ô	$Ð&ñô ð ð 	‡K‚K�M„M€M€M€Mr(   ©Úposixr   rU   Úboolúlist[list[str]]c               óì   — g }t                                |                      ¦   «         ¦  «        D ]D}|sŒ	 t          j        ||¬¦  «        }n# t          $ r Y Œ)w xY w|r|                     |¦  «         ŒE|S )NrT   )Ú_SHELL_SPLIT_REÚsplitÚstripÚshlexÚ
ValueErrorÚappend)r   rU   ÚsegmentsÚsegmentÚtokenss        r)   Ú_split_segment_tokensrb   ™   s’   € Ø "€HÝ"×(Ò(¨¯ª©¬Ñ9Ô9ð $ð $ˆØð 	Øð	Ý”[ °Ð6Ñ6Ô6ˆFˆFøÝð 	ð 	ð 	ØˆHð	øøøàð 	$Ø�OŠO˜FÑ#Ô#Ð#øØ€Os   µAÁ
AÁAÚtokenc                ó–   — |                       ¦   «         } |                      d¦  «        r| dd …         } |                      d¦  «        °| S )Nz./é   )r[   Ú
startswith)rc   s    r)   Ú_clean_tokenrg   §   sO   € Ø�KŠK‰MŒM€EØ
×
Ò
˜4Ñ
 Ô
 ð Ø�a�b�b”	ˆð ×
Ò
˜4Ñ
 Ô
 ð à€Lr(   Ú	canonicalú	list[str]c                ód   — 	 d„ t          j        | ¦  «        D ¦   «         S # t          $ r g cY S w xY w)Nc                ó0   — g | ]}|¯t          |¦  «        ‘ŒS r'   ©rg   ©Ú.0Úts     r)   ú
<listcomp>z%_canonical_tokens.<locals>.<listcomp>°   s#   € ÐEÐEÐE AÀ1ÐE•˜Q‘”ÐEÐEÐEr(   )r\   rZ   r]   )rh   s    r)   Ú_canonical_tokensrq   ®   sI   € ðØEÐE­¬°YÑ)?Ô)?ÐEÑEÔEÐEøÝð ð ð Øˆ	ˆ	ˆ	ðøøøs   ‚   /®/ra   ÚneedleúOptional[int]c                ó  — | r"|r t          |¦  «        t          | ¦  «        k    rd S d„ | D ¦   «         }t          dt          |¦  «        t          |¦  «        z
  dz   ¦  «        D ]$}|||t          |¦  «        z   …         |k    r|c S Œ%d S )Nc                ó,   — g | ]}t          |¦  «        ‘ŒS r'   rl   rm   s     r)   rp   z%_find_subsequence.<locals>.<listcomp>¸   s   € Ð/Ð/Ð/ 1�|˜A‰ŒÐ/Ð/Ð/r(   r   r   )ÚlenÚrange)ra   rr   ÚcleanedÚidxs       r)   Ú_find_subsequencerz   µ   s¡   € Øð ˜ð ¥3 v¡;¤;µ°V±´Ò#<Ð#<ØˆtØ/Ð/¨Ð/Ñ/Ô/€GÝ�Q�˜G™œ¥s¨6¡{¤{Ñ2°QÑ6Ñ7Ô7ð ð ˆØ�3�s�S ™[œ[Ñ(Ð(Ô)¨VÒ3Ð3ØˆJˆJˆJð 4àˆ4r(   c                óH  — t          | ¦  «        }|r|d         dk    r
|dd…         }|rVd|d         v rL|d                              d¦  «        s1|dd…         }|r%d|d         v r|d                              d¦  «        ¯1|r |d         dv r|dd…         }|r
|d         dv °|S )zDRemove harmless command prefixes before matching canonical commands.r   Úenvr   NÚ=Ú->   ÚtimeÚnoglobr   )Úlistrf   )ra   Ú	remainings     r)   Ú_strip_command_prefixrƒ   ¿   sÜ   € å�V‘”€IØð "�Y˜q”\ UÒ*Ð*Ø˜a˜b˜b”Mˆ	Ø
ð "˜˜y¨œ|Ð+Ð+°I¸a´L×4KÒ4KÈCÑ4PÔ4PÐ+Ø˜a˜b˜b”Mˆ	ð ð "˜˜y¨œ|Ð+Ð+°I¸a´L×4KÒ4KÈCÑ4PÔ4PÐ+à
ð "˜	 !œÐ(EÐEÐEØ˜a˜b˜b”Mˆ	ð ð "˜	 !œÐ(EÐEÐEàÐr(   c                ó~  — | g}t          | ¦  «        dk    r7| d         dk    r+| d         }| d         }|dv r|                     ||g¦  «         t          | ¦  «        dk    r1d| d         v r'|                     d| d         gd	| d         gg¦  «         | d
gk    r$|                     g d¢g d¢g d¢g d¢g d¢g¦  «         |S )zFReturn command spellings equivalent to the detected canonical command.é   r   Úrunr   re   >   ÚbunÚnpmÚpnpmÚyarnú/ÚbashÚshÚpytest)Úpythonú-mrŽ   )Úpython3r�   rŽ   )Úuvr†   rŽ   )Úpoetryr†   rŽ   )Úpipenvr†   rŽ   )rv   r^   Úextend)rr   Ú
candidatesÚpackage_managerÚscript_names       r)   Ú_equivalent_needlesr™   Ë   s  € à�€JÝ
ˆ6�{„{�aÒÐ˜F 1œI¨Ò.Ð.Ø  œ)ˆØ˜Q”iˆØÐ<Ð<Ð<Ø×Ò˜°Ð<Ñ=Ô=Ð=Ý
ˆ6�{„{�aÒÐ˜C 6¨!¤9Ð,Ð,Ø×Ò˜F F¨1¤IÐ.°°v¸a´yÐ0AÐBÑCÔCÐCØ�(�ÒÐØ×Òà*Ð*Ð*Ø+Ð+Ð+Ø'Ð'Ð'Ø+Ð+Ð+Ø+Ð+Ð+ðñ	
ô 	
ð 	
ð Ðr(   Úcanonical_commandsúOptional[tuple[str, list[str]]]c                ó  — t          | ¦  «        }|D ]t}t          |¦  «        }|sŒ|D ]]}t          |¦  «        }t          |¦  «        D ]<}|dt	          |¦  «        …         |k    r||t	          |¦  «        d…         fc c c S Œ=Œ^ŒudS )zEReturn ``(canonical, trailing_args)`` for the first detected command.N)rb   rq   rƒ   r™   rv   )r   rš   r_   rh   rr   ra   Úcandidate_tokensÚ	candidates           r)   Ú_find_canonical_matchrŸ   â   sÒ   € õ % WÑ-Ô-€HØ'ð Hð Hˆ	Ý" 9Ñ-Ô-ˆØð 	ØØð 	Hð 	HˆFÝ4°VÑ<Ô<ÐÝ0°Ñ8Ô8ð Hð H�	Ø# O¥S¨¡^¤^ OÔ4¸	ÒAÐAØ$Ð&6µs¸9±~´~°°Ô&GÐGÐGÐGÐGÐGÐGÐGÐGð BðHð	Hð
 ˆ4r(   c                óØ   ‡— |                       ¦   «         Št          ˆfd„dD ¦   «         ¦  «        rdS t          ˆfd„dD ¦   «         ¦  «        rdS d‰v rdS d‰v sd	‰v rd	S d
‰v rd‰vrd
S dS )Nc              3  ó    •K  — | ]}|‰v V — Œ	d S r,   r'   ©rn   ÚwordÚlowereds     €r)   ú	<genexpr>z$_kind_for_command.<locals>.<genexpr>ô   s'   øè è € Ð
BÐ
B˜tˆ4�7ˆ?Ð
BÐ
BÐ
BÐ
BÐ
BÐ
Br(   )ÚlintÚeslintÚruffr¦   c              3  ó    •K  — | ]}|‰v V — Œ	d S r,   r'   r¢   s     €r)   r¥   z$_kind_for_command.<locals>.<genexpr>ö   s'   øè è € Ð
UÐ
U˜tˆ4�7ˆ?Ð
UÐ
UÐ
UÐ
UÐ
UÐ
Ur(   )Ú	typecheckÚtscÚmypyÚpyrightÚtyrª   ÚbuildÚfmtÚformatÚcheckÚtest)ÚlowerÚany)rh   r¤   s    @r)   Ú_kind_for_commandr¶   ò   s±   ø€ Ø�oŠoÑÔ€GÝ
Ð
BÐ
BÐ
BÐ
BÐ'AÐ
BÑ
BÔ
BÑBÔBð ØˆvÝ
Ð
UÐ
UÐ
UÐ
UÐ'TÐ
UÑ
UÔ
UÑUÔUð Øˆ{Ø�'ÐÐØˆwØ�ÐÐ˜8 wÐ.Ð.ØˆxØ�'ÐÐ˜f¨GÐ3Ð3ØˆwØˆ6r(   Úargc                ó¨   — | r|                       d¦  «        sd| v rdS d| v p1d| v p-d| v p)|                      d¦  «        p|                       d¦  «        S )	Nr~   r}   Fr‹   ú\z::)z.pyz.jsz.jsxz.tsz.tsxz.rsz.goz.java)Útest_ÚtestsÚspecÚ	__tests__)rf   Úendswith)r·   s    r)   Ú_looks_like_targetr¿     s€   € Øð �#—.’. Ñ%Ô%ð ¨°¨¨Øˆuàˆsˆ
ð 	CØ�3ˆ;ð	Cà�3ˆ;ð	Cð �<Š<ÐTÑUÔUð	Cð �>Š>ÐAÑBÔBðr(   Úargsc                ó<   — t          d„ | D ¦   «         ¦  «        rdndS )Nc              3  ó4   K  — | ]}t          |¦  «        V — Œd S r,   )r¿   )rn   r·   s     r)   r¥   z"_scope_for_args.<locals>.<genexpr>  s+   è è € ÐEÐE¸Õ/°Ñ4Ô4ÐEÐEÐEÐEÐEÐEr(   ÚtargetedÚfull)rµ   )rÀ   s    r)   Ú_scope_for_argsrÅ     s(   € ÝÐEÐEÀÐEÑEÔEÑEÔEÐQˆ:ˆ:È6ÐQr(   c                óp  — | r|                       d¦  «        rdS 	 t          | ¦  «                             ¦   «         }|                     ¦   «         sdS |                     ¦   «         }t          t          j        ¦   «         ¦  «                             ¦   «         }||k    p||j        v S # t          $ r Y dS w xY w)Nr~   F)	rf   r	   Ú
expanduserÚis_absoluteÚresolveÚtempfileÚ
gettempdirr;   rG   )rc   rI   ÚresolvedÚ	temp_roots       r)   Ú_is_under_temp_dirrÎ     sÂ   € Øð �E×$Ò$ SÑ)Ô)ð ØˆuðÝ�E‰{Œ{×%Ò%Ñ'Ô'ˆØ×ÒÑ!Ô!ð 	Ø�5Ø—<’<‘>”>ˆÝ�Ô,Ñ.Ô.Ñ/Ô/×7Ò7Ñ9Ô9ˆ	Ø˜9Ò$ÐE¨	°XÔ5EÐ(EÐEøÝð ð ð Øˆuˆuðøøøs   ›5B' ÁAB' Â'
B5Â4B5r   ústr | Path | Nonec                ó  — |sdS 	 t          | ¦  «                             ¦   «                              ¦   «         }t          |¦  «                             ¦   «                              ¦   «         }||k    p||j        v S # t          $ r Y dS w xY w©NF)r	   rÇ   rÉ   r;   rG   )rc   r   rI   Ú	root_paths       r)   Ú_is_under_rootrÓ     s“   € Øð ØˆuðÝ�E‰{Œ{×%Ò%Ñ'Ô'×/Ò/Ñ1Ô1ˆÝ˜‘J”J×)Ò)Ñ+Ô+×3Ò3Ñ5Ô5ˆ	Ø�yÒ Ð= I°´Ð$=Ð=øÝð ð ð Øˆuˆuðøøøs   †A4A; Á;
B	ÂB	c                óè   — 	 t          | ¦  «                             ¦   «         j        }n# t          $ r Y dS w xY w|                     t
          ¦  «        ot          | ¦  «        ot          | |¦  «         S rÑ   )r	   rÇ   ÚnamerG   rf   Ú_AD_HOC_SCRIPT_NAME_PREFIXESrÎ   rÓ   )rc   r   rÕ   s      r)   Ú_is_temp_script_pathr×   *  s�   € ðÝ�E‰{Œ{×%Ò%Ñ'Ô'Ô,ˆˆøÝð ð ð Øˆuˆuðøøøð 	�ŠÕ4Ñ5Ô5ð 	,Ý˜uÑ%Ô%ð	,å˜u dÑ+Ô+Ð+ðs   ‚&) ©
7¶7úOptional[list[str]]c                ó2  — t          | ¦  «        }|sd S |d         }t          ||¦  «        r
|dd …         S |dv r]t          |dd …         d¬¦  «        D ]C\  }}|dk    rŒt          ||¦  «        r||dz   d …         c S |                     d¦  «        s d S ŒDd S )Nr   r   >   r�   rŒ   ÚnodeÚperlÚrubyr�   r‘   )Ústartz--r~   )rƒ   r×   Ú	enumeraterf   )ra   r   r�   r   ry   rc   s         r)   Ú_ad_hoc_script_argsrß   6  sÜ   € Ý,¨VÑ4Ô4ÐØð ØˆtØ˜qÔ!€GÝ˜G TÑ*Ô*ð $Ø   Ô#Ð#ØÐMÐMÐMÝ#Ð$4°Q°R°RÔ$8ÀÐBÑBÔBð 	ð 	‰JˆC�Ø˜Š}ˆ}ØÝ# E¨4Ñ0Ô0ð 2Ø'¨¨a©¨¨Ô1Ð1Ð1Ð1Ø×#Ò# CÑ(Ô(ð Ø�t�tðàˆ4r(   c                óh   — dD ].}t          | |¬¦  «        D ]}t          ||¦  «        }|�|c c S ŒŒ/d S )N)TFrT   )rb   rß   )r   r   rU   ra   Útrailing_argss        r)   Ú_find_ad_hoc_matchrâ   H  sg   € ð ð %ð %ˆÝ+¨G¸5ÐAÑAÔAð 	%ð 	%ˆFÝ/°¸Ñ=Ô=ˆMØÐ(Ø$Ð$Ð$Ð$Ð$Ð$ð )ð	%ð ˆ4r(   Úoutputc                óî   — | pd                      ¦   «         }t          |¦  «        t          k    r|S t          dz  }t          |z
  }|d |…         dt          |¦  «        t          z
  › d�z   || d …         z   S )Nr    r…   z
... [z chars omitted] ...
)r[   rv   Ú_MAX_OUTPUT_SUMMARY_CHARS)rã   ÚtextÚheadÚtails       r)   Ú_summarize_outputré   S  s„   € ØˆL�b×ÒÑ!Ô!€DÝ
ˆ4�y„yÕ-Ò-Ð-ØˆÝ$¨Ñ)€DÝ$ tÑ+€DàˆUˆdˆUŒØ
P•C˜‘I”IÕ 9Ñ9Ð
PÐ
PÐ
Pñ	Qà
�ˆuˆvˆvŒ,ñ	ðr(   r   c               óø   — t          ¦   «         }|                      d||||t          f¦  «         |                      d||f¦  «         |                      d|f¦  «         |                      dt          f¦  «         dS )z?Bound ledger growth without deleting the current state pointer.a!  
        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 ?
          )
        aQ  
        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
          )
        aD  
        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)r4   rE   Ú_MAX_EVENTS_PER_SESSION_ROOTÚ_MAX_TOTAL_UNREFERENCED_EVENTS)rJ   r   r   Úcutoffs       r)   Ú_prune_old_eventsrî   `  s³   € åÑ Ô €FØ‡L‚Lð
	ð 
�T˜: tÕ-IÐJñô ð ð 	‡L‚Lð	ð 
�Ðñô ð ð" 	‡L‚Lð	ð 
ˆ	ñ
ô 
ð 
ð 	‡L‚Lð	õ 
(Ð)ñô ð ð ð r(   r    ©r   r   r   rã   r   ú
str | Noner   r   úOptional[VerificationEvidence]c               ó6  — | rt          | t          ¦  «        sdS 	 ddlm}  ||¦  «        }n# t          $ r d}Y nw xY w|sdS t          |                     d¦  «        pg ¦  «        }t          | |¦  «        }d}	|€-|s+t          | |                     d¦  «        ¦  «        }
|
�d|
f}d}	|€dS |\  }}t          | ||	rd	nt          |¦  «        |	rd
nt          |¦  «        t          |¦  «        dk    rdndt          |¦  «        t          t          |pd¦  «                             ¦   «         ¦  «        t          |                     d¦  «        p"t          |pd¦  «                             ¦   «         ¦  «        t          |pd¦  «        t          |¦  «        ¬¦
  «
        S )zDClassify a terminal command as verification evidence, if applicable.Nr   ©Úproject_facts_forÚverifyCommandsFr   zad-hoc verification scriptTÚad_hocrÃ   ÚpassedÚfailedú.Údefault©
r   r   r   r   r   r   r   r   r   r!   )Ú
isinstancer   Úagent.coding_contextrô   rG   r�   ÚgetrŸ   râ   r   r¶   rÅ   r   r	   rÉ   ré   )r   r   r   r   rã   rô   ÚfactsÚverify_commandsÚmatchÚ	is_ad_hocÚad_hoc_argsrh   rá   s                r)   Úclassify_verification_commandr  ž  sÔ  € ð ð �* W­cÑ2Ô2ð ØˆtðØ:Ð:Ð:Ð:Ð:Ð:à!Ð! #Ñ&Ô&ˆˆøÝð ð ð Øˆˆˆðøøøàð Øˆtå˜5Ÿ9š9Ð%5Ñ6Ô6Ð<¸"Ñ=Ô=€OÝ! '¨?Ñ;Ô;€EØ€IØ€}˜_€}Ý(¨°%·)²)¸FÑ2CÔ2CÑDÔDˆØÐ"Ø1°;Ð?ˆEØˆIØ€}Øˆtà$Ñ€Iˆ}ÝØØ#Ø"ÐDˆXˆXÕ(9¸)Ñ(DÔ(DØ%ÐIˆjˆj­?¸=Ñ+IÔ+IÝ˜y™>œ>¨QÒ.Ð.ˆxˆx°HÝ�i‘.”.Ý•�S�Z˜CÑ Ô ×(Ò(Ñ*Ô*Ñ+Ô+Ý�—’˜6Ñ"Ô"Ð@¥d¨3¨:°#Ñ&6Ô&6×&>Ò&>Ñ&@Ô&@ÑAÔAÝ�zÐ. YÑ/Ô/Ý(¨Ñ0Ô0ðñ ô ð s   ›- ­<»<)rã   úOptional[dict[str, Any]]c                óP   — t          | ||||¬¦  «        }|€dS t          |¦  «        S )zERecord a foreground terminal result when it is verification evidence.rï   N)r  Ú_insert_evidence)r   r   r   r   rã   Úevidences         r)   Úrecord_terminal_resultr	  Í  sB   € õ -ØØØØØðñ ô €Hð ÐØˆtÝ˜HÑ%Ô%Ð%r(   úhermes verifyrÄ   )r   r   r   rã   ú
str | PathÚokr   c                ó”  — 	 ddl m}  || ¦  «        }n# t          $ r d}Y nw xY wt          t	          | ¦  «                             ¦   «         ¦  «        }t          |dd|dv r|nd|rdnd	|rdnd
|t          |pi                      d¦  «        p|¦  «        t          |pd¦  «        t          |¦  «        ¬¦
  «
        }	t          |	¦  «        S )uÖ  Record a completed ``hermes verify`` run as verification evidence.

    Explicit CLI-side write: unlike :func:`record_terminal_result` there is
    nothing to classify â€” the caller (the ``hermes verify`` command) already
    knows the run was a verification pass and whether it succeeded. A passing
    run marks the workspace ``passed`` for the verify-on-stop guard exactly
    like a passing canonical test command would; a failing run records the
    failure so the guard keeps asking for a fix.

    ``root`` is re-resolved through :func:`agent.coding_context.project_facts_for`
    so the recorded workspace root matches what :func:`verification_status`
    derives when the stop guard later looks the evidence up.
    r   ró   Nr
  Úverify>   rÄ   rÃ   rÄ   r÷   rø   r   r   rú   rû   )
rý   rô   rG   r   r	   rÉ   r   rþ   ré   r  )
r   r   r  r   r   rã   rô   rÿ   rÌ   r  s
             r)   Úrecord_verify_runr  ã  s  € ð,Ø:Ð:Ð:Ð:Ð:Ð:à!Ð! $Ñ'Ô'ˆˆøÝð ð ð Øˆˆˆðøøøõ •4˜‘:”:×%Ò%Ñ'Ô'Ñ(Ô(€HÝ#ØØ)ØØÐ 4Ð4Ð4ˆeˆe¸&ØÐ+ˆxˆx 8Ø�.�!�!˜qØÝ�%�+˜2×"Ò" 6Ñ*Ô*Ð6¨hÑ7Ô7Ý�zÐ. YÑ/Ô/Ý(¨Ñ0Ô0ðñ ô €Hõ ˜HÑ%Ô%Ð%s   ‚ ”#¢#r  údict[str, Any]c                óf  — t          ¦   «         }t          5  t          ¦   «         5 }|                     d|| j        | j        | j        | j        | j        | j	        | j
        | j        | j        | j        f¦  «        }|j        €t          d¦  «        ‚t!          |j        ¦  «        }|                     d| j        | j        |f¦  «         t#          || j        | j        ¬¦  «         |                     ¦   «          ddd¦  «         n# 1 swxY w Y   ddd¦  «         n# 1 swxY w Y   d|i| j        ¥d|i¥S )zAInsert a classified evidence row and repoint the workspace state.a  
                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 = '[]'
                )r   r   ÚidÚ
created_at)r0   Ú_DB_LOCKrO   rE   r   r   r   r   r   r   r   r   r   r!   Ú	lastrowidÚRuntimeErrorr   rî   rS   Ú__dict__)r  r  rJ   ÚcurÚevent_ids        r)   r  r    s¹  € å‘”€JÝ	ð 'ð 'Ý‰^Œ^ð &	˜tØ—,’,ðð ØÔ'Ø”LØ”MØÔ$ØÔ.Ø”MØ”NØ”OØÔ&ØÔ+ðñô ˆCð* Œ}Ð$Ý"Ð#SÑTÔTÐTÝ˜3œ=Ñ)Ô)ˆHØ�LŠLðð Ô$ h¤m°XÐ>ñô ð õ ˜d¨xÔ/BÈÌÐWÑWÔWÐWØ�KŠK‰MŒMˆMðM&	ð &	ð &	ñ &	ô &	ð &	ð &	ð &	ð &	ð &	ð &	øøøð &	ð &	ð &	ð &	ð'ð 'ð 'ñ 'ô 'ð 'ð 'ð 'ð 'ð 'ð 'øøøð 'ð 'ð 'ð 'ðR �(ÐJ˜hÔ/ÐJ°¸zÐJÐJÐJs5   –D¥CDÃ6DÄD	ÄDÄ	D	Ä
DÄDÄ D)Úpathsr  ú"list[str] | tuple[str, ...] | Nonec                óÌ  — 	 ddl m}  ||¦  «        }n# t          $ r d}Y nw xY w|sdS t          | pd¦  «        }t          |                     d¦  «        p"t          |pd¦  «                             ¦   «         ¦  «        }t          d„ |pg D ¦   «         ¦  «        }t          ¦   «         }t          5  t          ¦   «         5 }	|	                     d||f¦  «                             ¦   «         }
t          ¦   «         }|
�P	 t          t          j        |
d	         pd
¦  «        ¦  «        }n%# t           t"          f$ r t          ¦   «         }Y nw xY wt          |t          |¦  «        z  ¦  «        dd…         }|	                     d|||t          j        |¦  «        f¦  «         |	                     ¦   «          ddd¦  «         n# 1 swxY w Y   ddd¦  «         n# 1 swxY w Y   ||||dœS )z>Mark verification evidence stale after a successful file edit.r   ró   Nrú   r   rù   c                ó0   — h | ]}|¯t          |¦  «        ’ŒS r'   )r   )rn   Úps     r)   ú	<setcomp>z(mark_workspace_edited.<locals>.<setcomp>R  s#   € Ð?Ð?Ð? q¸QÐ?�C ™FœFÐ?Ð?Ð?r(   z…
                SELECT changed_paths_json FROM verification_state
                WHERE session_id = ? AND root = ?
                Úchanged_paths_jsonú[]i8ÿÿÿa~  
                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_json
                )r   r   Úlast_edit_atÚchanged_paths)rý   rô   rG   r   rþ   r	   rÉ   Úsortedr0   r  rO   rE   ÚfetchoneÚsetÚjsonÚloadsÚ	TypeErrorr]   ÚdumpsrS   )r   r   r  rô   rÿ   Úsidr   r#  Ú	edited_atrJ   ÚrowÚexistingÚmergeds                r)   Úmark_workspace_editedr0  ?  s“  € ðØ:Ð:Ð:Ð:Ð:Ð:à!Ð! #Ñ&Ô&ˆˆøÝð ð ð Øˆˆˆðøøøàð Øˆtå
ˆjÐ%˜IÑ
&Ô
&€CÝˆu�yŠy˜Ñ Ô Ð>¥D¨¨°Ñ$4Ô$4×$<Ò$<Ñ$>Ô$>Ñ?Ô?€DÝÐ?Ð?¨U¨[°bÐ?Ñ?Ô?Ñ@Ô@€MÝ‘
”
€Iå	ð ð Ý‰^Œ^ð 	˜tØ—,’,ðð �d�ñô ÷ Šh‰jŒjð õ "%¡¤ˆHØˆð%Ý"¥4¤:¨cÐ2FÔ.GÐ.OÈ4Ñ#PÔ#PÑQÔQ�H�HøÝ!¥:Ð.ð %ð %ð %Ý"™uœu�H�H�Hð%øøøå˜X­¨MÑ(:Ô(:Ñ:Ñ<Ô<¸T¸U¸UÔCˆFØ�LŠLðð �d˜I¥t¤z°&Ñ'9Ô'9Ð:ñ
ô 
ð 
ð �KŠK‰MŒMˆMð5	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ð 	øøøð 	ð 	ð 	ð 	ðð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð ð:  t¸YÐYfÐgÐgÐgsg   ‚ ”#¢#Â0GÂ?;F=Ã;)D%Ä$F=Ä%EÅF=ÅEÅA*F=Æ1GÆ=G	ÇGÇG	ÇGÇGÇGc                ó˜  — 	 ddl m}  ||¦  «        }n# t          $ r d}Y nw xY w|sdddœS t          | pd¦  «        }t          |                     d¦  «        p"t          |pd¦  «                             ¦   «         ¦  «        }t          5  t          ¦   «         5 }| 	                    d	||f¦  «         
                    ¦   «         }|€ d
d||g dœcddd¦  «         cddd¦  «         S d}|d         �/| 	                    d|d         f¦  «         
                    ¦   «         }ddd¦  «         n# 1 swxY w Y   ddd¦  «         n# 1 swxY w Y   g }		 t          j        |d         pd¦  «        }	n# t          t          f$ r g }	Y nw xY w|€d
d|||	dœS t          |¦  «        }
|d         r|d         |
d         k    rd}n|
d         }||
|||	dœS )zAReturn the best known verification state for a session/workspace.r   ró   NÚnot_applicable)r   r  rú   r   rù   z²
                SELECT last_event_id, last_edit_at, changed_paths_json
                FROM verification_state
                WHERE session_id = ? AND root = ?
                Ú
unverified)r   r  r   r   r#  Úlast_event_idz.SELECT * FROM verification_events WHERE id = ?r   r!  r"  r  Ústaler   )rý   rô   rG   r   rþ   r	   rÉ   r  rO   rE   r%  r'  r(  r)  r]   Údict)r   r   rô   rÿ   r+  r   rJ   ÚstateÚeventr#  r  r   s               r)   Úverification_statusr9  u  s  € ðØ:Ð:Ð:Ð:Ð:Ð:à!Ð! #Ñ&Ô&ˆˆøÝð ð ð Øˆˆˆðøøøàð >Ø*¸Ð=Ð=Ð=å
ˆjÐ%˜IÑ
&Ô
&€CÝˆu�yŠy˜Ñ Ô Ð>¥D¨¨°Ñ$4Ô$4×$<Ò$<Ñ$>Ô$>Ñ?Ô?€DÝ	ð ð Ý‰^Œ^ð 	˜tØ—L’Lðð
 �d�ñô ÷ Šh‰jŒjð ð ˆ}à*Ø $Ø Ø"%Ø%'ðð ð	ð 	ð 	ð 	ñ 	ô 	ð 	ðð ð ð ñ ô ð ð ð$ ˆEØ�_Ô%Ð1ØŸšØDØ˜?Ô+Ð-ñô ÷ ’(‘*”*ð ð'	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ð 	øøøð 	ð 	ð 	ð 	ðð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð ð2  "€MðÝœ
 5Ð)=Ô#>Ð#FÀ$ÑGÔGˆˆøÝ•zÐ"ð ð ð Øˆˆˆðøøøð €}à"ØØØØ*ð
ð 
ð 	
õ �E‰{Œ{€HØˆ^Ôð $  ~Ô!6¸À,Ô9OÒ!OÐ!OØˆˆà˜(Ô#ˆàØØØØ&ðð ð s`   ‚ ”#¢#Â
EÂ4D+ÃEÃ&9D+ÄEÄ+D/	Ä/EÄ2D/	Ä3EÅEÅ	EÅE- Å-FÆF)r*   r   )r*   r	   )r*   r8   )r*   rL   )rJ   r8   r*   rP   )r   r   rU   rV   r*   rW   )rc   r   r*   r   )rh   r   r*   ri   )ra   ri   rr   ri   r*   rs   )ra   ri   r*   ri   )rr   ri   r*   rW   )r   r   rš   ri   r*   r›   )rh   r   r*   r   )r·   r   r*   rV   )rÀ   ri   r*   r   )rc   r   r*   rV   )rc   r   r   rÏ   r*   rV   )ra   ri   r   rÏ   r*   rØ   )r   r   r   rÏ   r*   rØ   )rã   r   r*   r   )rJ   r8   r   r   r   r   r*   rP   )r   r   r   rÏ   r   rð   r   r   rã   r   r*   rñ   )r   r   r   rÏ   r   rð   r   r   rã   r   r*   r  )r   r  r   rð   r  rV   r   r   r   r   rã   r   r*   r  )r  r   r*   r  )r   rð   r   rÏ   r  r  r*   r  )r   rð   r   rÏ   r*   r  )@r%   Ú
__future__r   r'  Úrer\   rA   rÊ   Ú	threadingÚ
contextlibr   Údataclassesr   r   r   r   Úpathlibr	   Útypingr
   r   r   Úhermes_constantsr   ÚLockr  rå   r3   rë   rì   rÖ   rR   ÚcompilerY   r   r0   r4   r7   rK   rO   rF   rb   rg   rq   rz   rƒ   r™   rŸ   r¶   r¿   rÅ   rÎ   rÓ   r×   rß   râ   ré   rî   r  r	  r  r  r0  r9  r'   r(   r)   ú<module>rD     s>  ððð ð #Ð "Ð "Ð "Ð "Ð "à €€€Ø 	€	€	€	Ø €€€Ø €€€Ø €€€Ø Ð Ð Ð Ø %Ð %Ð %Ð %Ð %Ð %Ø !Ð !Ð !Ð !Ð !Ð !Ø 2Ð 2Ð 2Ð 2Ð 2Ð 2Ð 2Ð 2Ð 2Ð 2Ø Ð Ð Ð Ð Ð Ø *Ð *Ð *Ð *Ð *Ð *Ð *Ð *Ð *Ð *à ,Ð ,Ð ,Ð ,Ð ,Ð ,ð ˆ9Œ>ÑÔ€Ø Ð ØÐ Ø"Ð Ø!'Ð ØCÐ ØÐ Ø�"”*Ð3Ñ4Ô4€ð €�$ÐÑÔðð ð ð ð ñ ô ñ Ôðð2ð 2ð 2ð 2ð]ð ]ð ]ð ]ð:ð :ð :ð :ðð ð ð ð& ðð ð ñ „ðð$1ð 1ð 1ð 1ðh :>ð ð ð ð ð ð ðð ð ð ðð ð ð ðð ð ð ð	ð 	ð 	ð 	ðð ð ð ð.ð ð ð ð ð ð ð ð	ð 	ð 	ð 	ðRð Rð Rð Rðð ð ð ðð ð ð ð	ð 	ð 	ð 	ðð ð ð ð$ð ð ð ð
ð 
ð 
ð 
ð;ð ;ð ;ð ;ðB "Ø!ØØð,ð ,ð ,ð ,ð ,ð ,ðj ð&ð &ð &ð &ð &ð &ð2 "à"ØØð*&ð *&ð *&ð *&ð *&ð *&ðZ,Kð ,Kð ,Kð ,Kðf 15ð	3hð 3hð 3hð 3hð 3hð 3hðlEð Eð Eð Eð Eð Er(   