§
    ÷žyjC-  ã                  óÜ   — d Z ddlmZ ddlZddlZddlmZ ddlmZm	Z	 dZ
 eh d£¦  «        Z eh d£¦  «        Zd,d„Zd-d„Zd.d„Zd/d0d„Zd1d„Zd2d„Zd3d„Zd4d „Zd5d#„Zdd$d%œd6d)„Zd*d+gZdS )7a  Turn-end verification guard for coding edits.

This module is intentionally policy-only. It never runs checks itself; it turns
the passive verification ledger into a bounded follow-up when the model tries to
finish immediately after editing code without fresh evidence.
é    )ÚannotationsN)ÚPath)ÚAnyÚIterableé   >   ú.mdú.csvú.logú.mdxú.orgú.rstú.tsvú.txtú.adocú.textú	.asciidocú	.markdown>   ÚnoticeÚauthorsÚlicenceÚlicenseÚ	changelogÚ
codeownersÚcontributorsÚrawÚstrÚreturnÚboolc                óô   — 	 t          t          | ¦  «        ¦  «        }n# t          $ r Y dS w xY w|j                             ¦   «         }|t
          v rdS |s"|j                             ¦   «         t          v rdS dS )zNReturn True when a changed path is documentation/prose with nothing to verify.FT)r   r   Ú	ExceptionÚsuffixÚlowerÚ_NON_CODE_VERIFY_EXTENSIONSÚnameÚ_NON_CODE_VERIFY_FILENAMES)r   Úpr!   s      ú=/home/ragecks/.hermes/hermes-agent/agent/verification_stop.pyÚ_is_non_code_pathr(   8   s…   € ðÝ•�S‘”‰NŒNˆˆøÝð ð ð ØˆuˆuðøøøàŒX�^Š^ÑÔ€FØÕ,Ð,Ð,ØˆtØð �a”f—l’l‘n”nÕ(BÐBÐBØˆtØˆ5s   ‚ Ÿ
-¬-ÚpathsúIterable[str]ú	list[str]c                ó   — d„ | D ¦   «         S )zODrop documentation/prose paths; keep paths that could have verifiable behavior.c                ó4   — g | ]}|¯t          |¦  «        °|‘ŒS © )r(   ©Ú.0r&   s     r'   ú
<listcomp>z,_filter_verifiable_paths.<locals>.<listcomp>H   s+   € Ð?Ð?Ð?�! Ð?Õ*;¸AÑ*>Ô*>Ð?ˆAÐ?Ð?Ð?ó    r.   )r)   s    r'   Ú_filter_verifiable_pathsr3   F   s   € à?Ð?�uÐ?Ñ?Ô?Ð?r2   c                 óF   — 	 ddl m}   | ¦   «         S # t          $ r Y dS w xY w)uÕ  Whether this turn is delivered over a human messaging channel.

    Verify-on-stop defaults ON for the interactive coding surfaces and
    programmatic callers, and OFF on a conversational platform (Telegram,
    Discord, Slack, ...) where the verification narrative reaches a human as
    chat noise. The surface classification itself is shared with the other
    consumers of this distinction â€” see
    ``gateway.session_context.session_is_messaging_surface``.
    r   ©Úsession_is_messaging_surfaceF)Úgateway.session_contextr6   r    r5   s    r'   Ú_session_is_messaging_surfacer8   K   sL   € ðØHÐHÐHÐHÐHÐHà+Ð+Ñ-Ô-Ð-øÝð ð ð ð ˆuˆuðøøøs   ‚ ’
 Ÿ Úconfigúdict[str, Any] | Nonec                ó˜  — t           j                             d¦  «        }|�(|                     ¦   «                              ¦   «         dvS | €$	 ddlm}  |¦   «         } n# t          $ r i } Y nw xY wt          | t          ¦  «        r| pi                      d¦  «        nd}t          |t          ¦  «        r|                     d¦  «        nd}t          |t          ¦  «        r|S t          |t          ¦  «        rG|                     ¦   «                              ¦   «         }|dv rd	S |dv rd
S |dk    rt          ¦   «          S t          ¦   «          S )u’  Return whether edit -> verify-before-finish behavior is enabled.

    Precedence: an explicit ``HERMES_VERIFY_ON_STOP`` env var wins, then an
    explicit ``agent.verify_on_stop`` config value. The config default is
    ``"auto"`` (see ``DEFAULT_CONFIG``) â€” surface-aware: ON for interactive
    coding surfaces (CLI, TUI, desktop) and programmatic callers, OFF for
    conversational messaging surfaces (Telegram, Discord, etc.) where the
    verification narrative would reach a human as chat noise. An explicit
    bool forces the behavior in either direction. A missing or unrecognized
    value falls back to the surface-aware ``"auto"`` default.
    ÚHERMES_VERIFY_ON_STOPN>   Ú0ÚnoÚoffÚfalser   )Úload_config_readonlyÚagentÚverify_on_stop>   Ú1ÚonÚyesÚtrueTFÚauto)ÚosÚenvironÚgetÚstripr"   Úhermes_cli.configrA   r    Ú
isinstanceÚdictr   r   r8   )r9   ÚenvrA   Ú	agent_cfgÚcfg_valÚtokens         r'   Úverify_on_stop_enabledrT   _   sj  € õ Œ*�.Š.Ð0Ñ
1Ô
1€CØ
€Ø�yŠy‰{Œ{× Ò Ñ"Ô"Ð*EÐEÐEØ€~ð	Ø>Ð>Ð>Ð>Ð>Ð>à)Ð)Ñ+Ô+ˆFˆFøÝð 	ð 	ð 	ØˆFˆFˆFð	øøøå/9¸&Å$Ñ/GÔ/GÐQ��˜2×"Ò" 7Ñ+Ô+Ð+ÈT€IÝ1;¸IÅtÑ1LÔ1LÐVˆi�mŠmÐ,Ñ-Ô-Ð-ÐRV€GÝ�'�4Ñ Ô ð ØˆÝ�'�3ÑÔð 7Ø—’‘”×%Ò%Ñ'Ô'ˆØÐ.Ð.Ð.Ø�4ØÐ/Ð/Ð/Ø�5Ø�FŠ?ˆ?Ý4Ñ6Ô6Ð6Ð6å,Ñ.Ô.Ð.Ð.s   ÁA ÁA-Á,A-ú
list[Path]c                óŽ  — g }t          ¦   «         }| D ]±}|sŒ	 t          |¦  «                             ¦   «         }|                     ¦   «         r|n|j        }t          |                     ¦   «         ¦  «        }n# t          $ r Y Œrw xY w||vr7|                     |¦  «         | 	                    t          |¦  «        ¦  «         Œ²|S ©N)
Úsetr   Ú
expanduserÚis_dirÚparentr   Úresolver    ÚaddÚappend)r)   Ú
candidatesÚseenr   ÚpathÚ	candidateÚresolveds          r'   Ú_candidate_cwdsrd   …   s×   € Ø€JÝ‘U”U€DØð .ð .ˆØð 	Øð	Ý˜‘9”9×'Ò'Ñ)Ô)ˆDØ $§¢¡¤Ð>˜˜°4´;ˆIÝ˜9×,Ò,Ñ.Ô.Ñ/Ô/ˆHˆHøÝð 	ð 	ð 	ØˆHð	øøøà˜4ÐÐØ�HŠH�XÑÔÐØ×Ò�d 8™nœnÑ-Ô-Ð-øØÐs   ™AA9Á9
BÂBÚ
session_idú
str | NoneÚchanged_pathsú,tuple[dict[str, Any], dict[str, Any]] | Nonec                ó
  — 	 ddl m} ddlm} n# t          $ r Y dS w xY wd}t          |¦  «        D ]Q} ||¦  «        }|sŒ || |¬¦  «        }||f}|€|}t          |                     d¦  «        pd¦  «        dk    r|c S ŒR|S )	zHReturn ``(status, facts)`` for the first edited workspace needing proof.r   )Úproject_facts_for)Úverification_statusN)re   ÚcwdÚstatusÚ
unverifiedÚpassed)Úagent.coding_contextrj   Úagent.verification_evidencerk   r    rd   r   rK   )	re   rg   rj   rk   Úfirst_snapshotrl   Úfactsrm   Úsnapshots	            r'   Ú_verification_snapshotru   —   sí   € ðØ:Ð:Ð:Ð:Ð:Ð:ØCÐCÐCÐCÐCÐCÐCøÝð ð ð Øˆtˆtðøøøð DH€NÝ˜}Ñ-Ô-ð 	ð 	ˆØ!Ð! #Ñ&Ô&ˆØð 	ØØ$Ð$°
ÀÐDÑDÔDˆØ˜E�?ˆØÐ!Ø%ˆNÝˆv�zŠz˜(Ñ#Ô#Ð3 |Ñ4Ô4¸Ò@Ð@ØˆOˆOˆOð AàÐs   ‚ �
œc                óÞ   — | d t           …         }d„ |D ¦   «         }t          | ¦  «        t          |¦  «        z
  }|dk    r|                     d|› d�¦  «         d                     |¦  «        S )Nc                ó   — g | ]}d |› d�‘Œ	S )z- `ú`r.   )r0   ra   s     r'   r1   z)_format_changed_paths.<locals>.<listcomp>³   s    € Ð-Ð-Ð-˜tˆ]�4ˆ]ˆ]ˆ]Ð-Ð-Ð-r2   r   z
- ... and z moreÚ
)Ú_MAX_CHANGED_PATHS_IN_NUDGEÚlenr^   Újoin)r)   ÚshownÚlinesÚ	remainings       r'   Ú_format_changed_pathsr€   ±   su   € ØÐ.Õ.Ð.Ô/€EØ-Ð- uÐ-Ñ-Ô-€EÝ�E‘
”
�S ™ZœZÑ'€IØ�1‚}€}Ø�ŠÐ2 )Ð2Ð2Ð2Ñ3Ô3Ð3Ø�9Š9�UÑÔÐr2   Úrootr   c                ó  — | sdS 	 t          t          | ¦  «        ¦  «        }ddlm}  ||¦  «                             ¦   «         rdS ddlm}  ||¦  «        }t          |duo|j        ¦  «        S # t          $ r Y dS w xY w)uŠ  Whether the workspace has a runtime verify recipe ``hermes verify`` can run.

    True when a saved ``.hermes/environment.json`` manifest exists, or when
    cheap static detection (:func:`agent.verify.recipes.detect_recipe`) finds a
    recipe with a start command. Deliberately fail-silent and cheap â€” this only
    decorates the nudge text; it must never break or slow the nudge path.
    Fr   )Úmanifest_pathT)Údetect_recipeN)
r   r   Úagent.verify.environmentrƒ   Úis_fileÚagent.verify.recipesr„   r   Ústartr    )r�   Ú	root_pathrƒ   r„   Úrecipes        r'   Ú_workspace_has_runnable_reciper‹   º   s¹   € ð ð ØˆuðÝ�˜T™œ‘O”Oˆ	Ø:Ð:Ð:Ð:Ð:Ð:àˆ=˜Ñ#Ô#×+Ò+Ñ-Ô-ð 	Ø�4Ø6Ð6Ð6Ð6Ð6Ð6à�˜yÑ)Ô)ˆÝ�F $Ð&Ð7¨6¬<Ñ8Ô8Ð8øÝð ð ð Øˆuˆuðøøøs   †?A0 Á(A0 Á0
A>Á=A>rm   údict[str, Any]c                ó’  — t          |                      d¦  «        pd¦  «        }t          |                      d¦  «        t          ¦  «        r|                      d¦  «        nd }|s|S |                     d¦  «        p|                     d¦  «        }t          |                     d¦  «        pd¦  «                             ¦   «         }|g}|r|                     d|› d	�¦  «         |rLd
}t          |¦  «        |k    r|d |…                              ¦   «         dz   }|                     d|› �¦  «         d                     |¦  «        S )Nrm   rn   ÚevidenceÚcanonical_commandÚcommandÚoutput_summaryÚ zlast command `rx   i°  z
... [truncated]zlast output:
ry   )	r   rK   rN   rO   rL   r^   r{   Úrstripr|   )rm   ÚstaterŽ   r�   ÚsummaryÚpartsÚmax_summarys          r'   Ú_status_detailr˜   Ò   sE  € Ý�—
’
˜8Ñ$Ô$Ð4¨Ñ5Ô5€EÝ)3°F·J²J¸zÑ4JÔ4JÍDÑ)QÔ)QÐ[ˆv�zŠz˜*Ñ%Ô%Ð%ÐW[€HØð Øˆà�lŠlÐ.Ñ/Ô/ÐJ°8·<²<À	Ñ3JÔ3J€GÝ�(—,’,Ð/Ñ0Ô0Ð6°BÑ7Ô7×=Ò=Ñ?Ô?€GØˆG€EØð 2Ø�ŠÐ0 gÐ0Ð0Ð0Ñ1Ô1Ð1Øð 1ØˆÝˆw‰<Œ<˜+Ò%Ð%Ø˜l˜{˜lÔ+×2Ò2Ñ4Ô4Ð7JÑJˆGØ�ŠÐ/ gÐ/Ð/Ñ0Ô0Ð0Ø�9Š9�UÑÔÐr2   é   )ÚattemptsÚmax_attemptsrš   Úintr›   c           	     óp  — t          d„ t          |¦  «        D ¦   «         ¦  «        }|r||k    rdS t          | |¬¦  «        }|€dS |\  }}d„ |                     d¦  «        pg D ¦   «         }t	          |                     d¦  «        pd¦  «        }	|	dk    rdS 	 d	d
lm}
  |
¦   «         }n# t          $ r d}Y nw xY w|rd|› �nd}|rmdd                     d„ |dd…         D ¦   «         ¦  «        z   t          |¦  «        dk    rdndz   dz   }t          |                     d¦  «        ¦  «        r|dz  }n[t          j                             t          j        ¦   «         ¦  «        }t          |                     d¦  «        ¦  «        rd}nd|› d�}dt!          |¦  «        › dt#          |¦  «        › d|› d|› d�	S )zGReturn a synthetic follow-up when edited code lacks fresh verification.c                ó,   — h | ]}t          |¦  «        ’ŒS r.   )r   r/   s     r'   ú	<setcomp>z-build_verify_on_stop_nudge.<locals>.<setcomp>ð   s   € ÐLÐLÐL˜q•C˜‘F”FÐLÐLÐLr2   N)re   rg   c                ó’   — g | ]D}t          |¦  «                             ¦   «         ¯#t          |¦  «                             ¦   «         ‘ŒES r.   )r   rL   ©r0   Úcmds     r'   r1   z.build_verify_on_stop_nudge.<locals>.<listcomp>ù   sN   € ð ð ð àÝˆs‰8Œ8�>Š>ÑÔðÝˆC‰Œ�ŠÑÔðð ð r2   ÚverifyCommandsrm   rn   ro   r   )Úcoding_verify_guidancez

r’   z+Run the relevant verification command now (z, c              3  ó"   K  — | ]
}d |› d �V — ŒdS )rx   Nr.   r¡   s     r'   ú	<genexpr>z-build_verify_on_stop_nudge.<locals>.<genexpr>  s*   è è € ÐBÐB s˜
˜C˜
˜
˜
ÐBÐBÐBÐBÐBÐBr2   é   z, ...z@), read any failure, repair the code, and summarize what passed.r�   u°    For a full check including a runtime boot (build + test + start + readiness), prefer `hermes verify --json` â€” a passing run records verification evidence for this workspace.a4  No canonical test/lint/build command was detected, but the project has a runnable verification recipe. Run `hermes verify --json` (detect -> build -> test -> boot -> readiness poll); a passing run records verification evidence for this workspace. Read any failure, repair the code, and summarize what passed.ziNo canonical test/lint/build command was detected. Create a focused temporary verification script under `z×` using an OS-safe `tempfile` path with a `hermes-verify-` filename prefix, run it against the changed behavior, clean it up when possible, and summarize it explicitly as ad-hoc verification rather than suite green.z†[System: You edited code in this turn, but the workspace does not have fresh passing verification evidence yet.

Verification status: z

Changed paths:
zn If verification is not possible, explain the concrete blocker instead of claiming the work is fully verified.Ú])Úsortedr3   ru   rK   r   Úagent.verify_hooksr¤   r    r|   r{   r‹   rI   ra   ÚrealpathÚtempfileÚ
gettempdirr˜   r€   )re   rg   rš   r›   r)   rt   rm   rs   Úverify_commandsr”   r¤   ÚguidanceÚaddendumÚcommand_instructionÚtemp_dirs                  r'   Úbuild_verify_on_stop_nudger³   å   s  € õ ÐLÐLÕ$<¸]Ñ$KÔ$KÐLÑLÔLÑMÔM€EØð �H Ò,Ð,Øˆtå%°È5ÐQÑQÔQ€HØÐØˆtØ�M€FˆEðð à—I’IÐ.Ñ/Ô/Ð5°2ðñ ô €Oõ �—
’
˜8Ñ$Ô$Ð4¨Ñ5Ô5€EØ�ÒÐØˆtðØ=Ð=Ð=Ð=Ð=Ð=à)Ð)Ñ+Ô+ˆˆøÝð ð ð Øˆˆˆðøøøà$,Ð4Ð �hÐ Ð Ð °"€Hàð à9Ø�iŠiÐBÐB¨o¸b¸q¸bÔ.AÐBÑBÔBÑBÔBñCå˜oÑ.Ô.°Ò2Ð2ˆwˆw¸ñ<ð QñQð 	õ *¨%¯)ª)°FÑ*;Ô*;Ñ<Ô<ð 	ØðHñÐøõ ”7×#Ò#¥HÔ$7Ñ$9Ô$9Ñ:Ô:ˆÝ)¨%¯)ª)°FÑ*;Ô*;Ñ<Ô<ð 	ðPð  ÐðØ8@ðð ð ð  ð	å .¨vÑ 6Ô 6ð	ð 	õ 1°Ñ7Ô7ð	ð 	ð ð		ð 	ð ð	ð 	ð 	ðs   ÂB* Â*B9Â8B9r³   rT   )r   r   r   r   )r)   r*   r   r+   )r   r   rW   )r9   r:   r   r   )r)   r*   r   rU   )re   rf   rg   r+   r   rh   )r)   r+   r   r   )r�   r   r   r   )rm   rŒ   r   r   )
re   rf   rg   r*   rš   rœ   r›   rœ   r   rf   )Ú__doc__Ú
__future__r   rI   r¬   Úpathlibr   Útypingr   r   rz   Ú	frozensetr#   r%   r(   r3   r8   rT   rd   ru   r€   r‹   r˜   r³   Ú__all__r.   r2   r'   ú<module>rº      s©  ððð ð #Ð "Ð "Ð "Ð "Ð "à 	€	€	€	Ø €€€Ø Ð Ð Ð Ð Ð Ø  Ð  Ð  Ð  Ð  Ð  Ð  Ð  ð  Ð ð (˜iðð ð ñô Ð ð& '˜Yðð ð ñ
ô 
Ð ðð ð ð ð@ð @ð @ð @ð
ð ð ð ð(#/ð #/ð #/ð #/ð #/ðLð ð ð ð$ð ð ð ð4ð ð ð ðð ð ð ð0ð ð ð ð. ØðPð Pð Pð Pð Pð Pðf (Ð)AÐ
B€€€r2   