
    (GjN,                        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 eh d          Zd,dZd-d.dZd/dZd0dZd1dZd2d!Zdd"d#d3d'Zd(d)gZdS )4a  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/rurouni/.hermes/hermes-agent/agent/verification_stop.py_is_non_code_pathr(   8   s    SNN   uuX^^F,,,t afllnn(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   >    clituitoolcodexlocaldesktopgatewaywebhook
api_servermsgraph_webhookc                    	 ddl m}  t          j        d          p | dd          } | dd          }ne# t          $ rX t          j        dd          pt          j                            dd          }t          j                            dd          }Y nw xY w||fD ]E}t          |pd                                          	                                }|r|t          vr dS FdS )	ai  Return whether this turn is delivered over a human messaging channel.

    The gateway binds the platform value (e.g. ``telegram``) to
    ``HERMES_SESSION_PLATFORM``; the CLI and TUI set ``HERMES_SESSION_SOURCE``
    (e.g. ``cli``, ``tui``) instead. Both are consulted via the session-context
    helper (with an ``os.environ`` fallback), alongside the ``HERMES_PLATFORM``
    override, matching the sibling platform resolution in
    ``agent/skill_commands.py`` and ``agent/prompt_builder.py``. A turn is a
    messaging surface when a resolved identity is present and is not a known
    non-messaging surface.
    r   )get_session_envHERMES_PLATFORMHERMES_SESSION_PLATFORMr4   HERMES_SESSION_SOURCETF)gateway.session_contextr@   osgetenvr    environgetr   stripr"   _NON_MESSAGING_SESSION_SURFACES)r@   platformsourceidentitys       r'   _session_is_messaging_surfacerN   g   s   =;;;;;; I'(( >8"== 	 !!8"== = = =9.33 
rz~~%r8
 8
  7<<	=
 v&  x~2&&,,..4466 	(GGG445s   25 ABB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agentverify_on_stop>   1onyestrueTFauto)rE   rG   rH   rI   r"   hermes_cli.configrW   r    
isinstancedictr   r   rN   )rO   envrW   	agent_cfgcfg_valtokens         r'   verify_on_stop_enabledrf      sg    *..0
1
1C
yy{{  ""*EEE~	555555 []]FF 	 	 	FFF	/9&$/G/GQ2""7+++TI1;It1L1LVimm,---RVG'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_cwdsrv      s    JUUD . . 		99''))D $>4;I9,,..//HH 	 	 	H	4HHXd8nn---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)rw   cwdstatus
unverifiedpassed)agent.coding_contextr|   agent.verification_evidencer}   r    rv   r   rH   )	rw   ry   r|   r}   first_snapshotr~   factsr   snapshots	            r'   _verification_snapshotr      s    ::::::CCCCCCC   tt DHN}-- 	 	!!#&& 	$$
DDDE?!%Nvzz(##3|44@@OOO 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   rs   s     r'   r1   z)_format_changed_paths.<locals>.<listcomp>   s     ---t]4]]]---r2   r   z
- ... and z more
)_MAX_CHANGED_PATHS_IN_NUDGElenrp   join)r)   shownlines	remainings       r'   _format_changed_pathsr      su    .../E--u---EE

SZZ'I1}}2)22233399Ur2   r   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 )Nr   r   evidencecanonical_commandcommandoutput_summaryr4   zlast command `r   i  z
... [truncated]zlast output:
r   )	r   rH   r`   ra   rI   rp   r   rstripr   )r   stater   r   summarypartsmax_summarys          r'   _status_detailr      sE   

8$$455E)3FJJz4J4JD)Q)Q[vzz*%%%W[H ll.//J8<<	3J3JG(,,/006B77==??GGE 20g000111 1w<<+%%l{l+22447JJG/g//00099Ur2      )attemptsmax_attemptsr   intr   c           	        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}|rFdd                    d |dd         D                       z   t          |          dk    rdndz   dz   }nt          j                    }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LqCFFLLLr2   N)rw   ry   c                    g | ]D}t          |                                          #t          |                                          ES r.   )r   rI   r0   cmds     r'   r1   z.build_verify_on_stop_nudge.<locals>.<listcomp>	  sN       s88>>C  r2   verifyCommandsr   r   r   r   )coding_verify_guidancez

r4   z+Run the relevant verification command now (z, c              3  "   K   | ]
}d | d V  dS )r   Nr.   r   s     r'   	<genexpr>z-build_verify_on_stop_nudge.<locals>.<genexpr>  s*      BBs
C


BBBBBBr2      z, ...z@), 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   r   rH   r   agent.verify_hooksr   r    r   r   tempfile
gettempdirr   r   )rw   ry   r   r   r)   r   r   r   verify_commandsr   r   guidanceaddendumcommand_instructiontemp_dirs                  r'   build_verify_on_stop_nudger      s    LL$<]$K$KLLLMME H,,t%5QQQHtMFE II.//52  O 

8$$455Et======))++   $,4 h   "H 
9iiBBobqb.ABBBBBCo..22ww< QQ 	 &((4<   		 .v 6 6	 	 177	 	 		 	 	 	 	s   B* *B98B9r   rf   )r   r   r   r   )r)   r*   r   r+   )r   r   ri   )rO   rP   r   r   )r)   r*   r   rg   )rw   rx   ry   r+   r   rz   )r)   r+   r   r   )r   r   r   r   )
rw   rx   ry   r*   r   r   r   r   r   rx   )__doc__
__future__r   rE   r   pathlibr   typingr   r   r   	frozensetr#   r%   r(   r3   rJ   rN   rf   rv   r   r   r   r   __all__r.   r2   r'   <module>r      s    # " " " " " 				                           (i    & 'Y  
 
    @ @ @ @  #,)  # # "   @#/ #/ #/ #/ #/L   $   4      . A A A A A AH ()A
Br2   