
    q(j[                    &   d Z ddlmZ ddlZddlmZ ddlmZmZm	Z	m
Z
 ddlmZ ddlmZ dZd	Zd
ZdZdZdZdZdZdZdZddZdddZ	 dedd	 	 	 	 	 	 	 	 	 	 	 ddZddZ	 d	 	 	 	 	 	 	 	 	 d dZ	 d	 	 	 	 	 	 	 	 	 d dZ	 d	 	 	 	 	 	 	 	 	 d dZd!dZ y)"u  utils.real_merge_artifact_schema — artifact writers + post_smoke schema-only.

task-2637 — real merge executor wiring 코드화 (activation false default · 실제 merge 실행 0).

Spec: memory/specs/system_real_merge_executor_wiring_spec_260523.md §7
sha256: bcaf654e981a43083af50879164021c918eeac9753cad3b3ad146209a1a62765

회장 verbatim (회장 10결정 #6 + spec §7):
    artifact 위치: memory/events/real_merge/<pr>/<head_sha>/
    canonical_root resolver (task-2636) 기준 atomic write
    dedupe (pr + head_sha 동일 → 재호출 0 부작용)

writers (구현):
    * write_merge_decision           → merge_decision.json (schema real_merge.decision.v1)
    * write_pre_merge_gate_snapshot  → pre_merge_gate_snapshot.json
    * write_merge_execution_result   → merge_execution_result.json

schema-only (writer 본 task 범위 외 — pilot 단계에서 구현, 회장 결정 task-2637 expected_files):
    * POST_SMOKE_SCHEMA + POST_SMOKE_REQUIRED_KEYS — 스키마 정의 + validate_post_smoke_payload
    )annotationsN)Path)AnyDictListOptional)atomic_json_write)CANONICAL_ROOT_DEFAULTzreal_merge.decision.v1zreal_merge.pre_gate_snapshot.v1zreal_merge.execution_result.v1zreal_merge.post_smoke.v1zmemory/events/real_mergezmerge_decision.jsonzpre_merge_gate_snapshot.jsonzmerge_execution_result.jsonzpost_merge_smoke_result.json)schemats_kstmerge_commit_shaorigin_main_beforeorigin_main_aftersmoke_checksall_okc                    	 t        |       }t        |t              r|st        d      d| d| S # t        t        f$ r t        d|       w xY w)zABuild the ``<pr>/<head_sha>/`` segment with deterministic naming.z pr must be int-convertible, got z#head_sha must be a non-empty stringpr_/)int	TypeError
ValueError
isinstancestr)prhead_shapr_ints      Q/home/jay/workspace/.worktrees/task-2638-dev6/utils/real_merge_artifact_schema.py_pr_dirr   <   si    DR h$H>??($$	 z" D;B6BCCDs	   2 Ac           
        |xs t         }t        j                  j                  |      st	        d|      t        j                  j                  t        j                  j                  |t        t        | |                  S )z>Return the absolute directory path for a given (pr, head_sha).z!canonical_root must be absolute: )	r
   ospathisabsr   normpathjoinREAL_MERGE_EVENTS_RELDIRr   )r   r   canonical_rootroots       r   resolve_artifact_dirr(   G   s`    33D77==<THEFF77BGGLL/GQSU]I^_``    )filename	fs_existsc                   ||nt         j                  j                  }t         j                  j                  t	        | ||      |      }t         ||            S )u   Dedupe check (spec §12.1).

    True if the named artifact already exists for this (pr, head_sha) — caller
    must transition to NO_OP_DUPLICATE without writing or invoking merge.
    )r    r!   existsr$   r(   bool)r   r   r&   r*   r+   r-   targets          r   artifact_already_presentr0   O   sI     $/YRWW^^FWW\\R>:HF vr)   c                <    t        |       j                  dd       y )NT)parentsexist_ok)r   mkdir)r!   s    r   _ensure_dirr5   c   s    JTD1r)   c                    t        | ||      }t        |       t        j                  j	                  |t
              }t        |      }|j                  dt               t        ||       |S )u2   Atomic write ``merge_decision.json`` (spec §7.1).r   )
r(   r5   r    r!   r$   MERGE_DECISION_FILENAMEdict
setdefaultMERGE_DECISION_SCHEMAr	   r   r   payloadr&   out_dirr/   canonical_payloads          r   write_merge_decisionr?   g   sZ     #2x@GWW\\'#:;FW  +@Af/0Mr)   c                    t        | ||      }t        |       t        j                  j	                  |t
              }t        |      }|j                  dt               t        ||       |S )u;   Atomic write ``pre_merge_gate_snapshot.json`` (spec §7.2).r   )
r(   r5   r    r!   r$   PRE_GATE_SNAPSHOT_FILENAMEr8   r9   PRE_GATE_SNAPSHOT_SCHEMAr	   r;   s          r   write_pre_merge_gate_snapshotrC   w   sZ     #2x@GWW\\'#=>FW  +CDf/0Mr)   c                    t        | ||      }t        |       t        j                  j	                  |t
              }t        |      }|j                  dt               t        ||       |S )u:   Atomic write ``merge_execution_result.json`` (spec §7.4).r   )
r(   r5   r    r!   r$   EXECUTION_RESULT_FILENAMEr8   r9   EXECUTION_RESULT_SCHEMAr	   r;   s          r   write_merge_execution_resultrG      sZ     #2x@GWW\\'#<=FW  +BCf/0Mr)   c                P   g }t        | t              sdt        |       j                   gS | j	                  d      t
        k7  r*|j                  dt
        d| j	                  d             t        D ]  }|| vs|j                  d|         | j	                  d      }|7t        |t              s'|j                  dt        |      j                          | j	                  d      }|7t        |t              s'|j                  d	t        |      j                          |S )
u=  Schema-only validator for post_merge_smoke_result.json (spec §7.3).

    Writer is intentionally out of scope for task-2637 (pilot 단계에서 구현).
    This validator exists so the schema contract is fixed *now* — callers can
    author payloads with confidence and the pilot writer will reuse the check.
    zpayload must be dict, got r   zschema must be z, got zrequired key missing: r   z!smoke_checks must be a list, got r   zall_ok must be bool, got )
r   r8   type__name__getPOST_SMOKE_SCHEMAappendPOST_SMOKE_REQUIRED_KEYSlistr.   )r<   errorskeysmoker   s        r   validate_post_smoke_payloadrS      s    Fgt$,T']-C-C,DEFF{{8 11/2&X9N8QR	
 ( :gMM23%89: KK'EE4!89$u+:N:N9OPQ[["F*VT":1$v,2G2G1HIJMr)   )r   r   r   r   returnr   )N)r   r   r   r   r&   Optional[str]rT   r   )r   r   r   r   r&   rU   r*   r   r+   zOptional[Any]rT   r.   )r!   r   rT   None)
r   r   r   r   r<   zDict[str, Any]r&   rU   rT   r   )r<   r   rT   z	List[str])!__doc__
__future__r   r    pathlibr   typingr   r   r   r   utils.atomic_writer	   utils.callback_envelope_schemar
   r:   rB   rF   rL   r%   r7   rA   rE   POST_SMOKE_FILENAMErN   r   r(   r0   r5   r?   rC   rG   rS    r)   r   <module>r_      sq  ( # 	  , , 0 A
 1 < : .  6  0 ; 9 4  %a %) 
 .#    " 
     
 (2 %)	  "	
 	( %)	  "	
 	( %)	  "	
 	 r)   