
    4ju/                        d Z ddlZddlmc 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Zej                  j                  ej                  j!                  ej                  j#                  e      dd            Zej                  j!                  edd      Zej                  j!                  edd      Zej                  j!                  ed      Zej                  j!                  ed      Zej                  j!                  ed	      Zd
Zej                  j!                  edd      Zej                  j!                  ed      ZdZdZdZdddddZdddddZ d Z!d Z"d Z# G d dejH                        Z% G d d ejH                        Z& G d! d"ejH                        Z' G d# d$ejH                        Z(e)d%k(  r ejT                  d&'       yy)(ut  Regression — task-2553+40 TRACK C: 기존 task-2553 사례 policy_profile
인스턴스화 + C1 engine dry-run 검증.

계약 (task-2553+40.md §3 / §5 / §6, +36 settled C1 canonical API):
  * 4 신규 policy_profile 인스턴스(memory/policy_profiles/task-2553+40.*.json)는
    C1 generic meta-schema 로 valid 하며 C1 engine 이 이름만으로 로딩 가능.
  * C1 canonical API parse_goal_request -> resolve_policy(profile_json_dir=...)
    로 각 인스턴스를 dry-run 하면 PolicyResolution.status ∈ {RESOLVED,
    HOLD_FOR_CHAIR} (PURE CONTRACT DERIVER — 역사적 runtime terminal status 를
    재생하지 않음). gate 조건 집합이 +35 Phase-A 기준선(= 기존 실제 결과로부터
    read-only 도출, +35 regression 검증) 및 profile 인코딩과 일치.
  * 실 merge / 실 GitHub write / 실 thread resolve 0 (정적 입증):
    C1 engine 모듈에 네트워크/merge 호출 토큰 부재 + 비교 artifact invariants=0.
  * C1 engine byte-0 + 기존 거버넌스 profile byte-0 (전후 sha256 동일).
  * mismatch → FAIL (엔진 결함 시사 — §6 HOLD 로 에스컬레이션할 신호).
    Nz..memoryeventspolicy_profilesz$task-2553+40.dry-run-comparison.jsonztask-2553+40.decision.jsonztask-2553+40.result.jsonzanu_v3.policy_profile_engineanu_v3zpolicy_profile_engine.pyz$test_only_hardening_pr_merge_v1.json@6f96c78ba77f5bd2354fd0658aa4fd3690a13686dc26e4f6db4ac48fc2852ad3@2363e291a0a43884892f5e554f115481a077322bd5caa3000fb75bf5b72bc6be@7e161d7dd579aae025d9c2c202e9f226839dcbbfdea312cb55f624e4a6582a13z'task-2553+40.clean_replacement_pr_mergez)task-2553+40.test_only_hardening_pr_mergez"task-2553+40.review_thread_cleanupz/task-2553+40.post_merge_smoke_artifact_closeout)PR#128 clean replacement merge PR#129 test-only hardening mergereview thread cleanup*post-merge smoke harness artifact closeoutmerge_clean_replacement_prmerge_test_only_hardening_pr gemini_thread_resolution_limited"post_merge_smoke_artifact_closeoutc                 t    t        | dd      5 }t        j                  |      cd d d        S # 1 sw Y   y xY w)Nrutf-8encoding)openjsonloadpathfhs     W/home/jay/workspace/tests/regression/test_policy_profile_instances_dryrun_2553plus40.py_loadr   <   s0    	dC'	* byy}  s   .7c                     t        | d      5 }t        j                  |j                               j	                         cd d d        S # 1 sw Y   y xY w)Nrb)r   hashlibsha256read	hexdigestr   s     r   _sha256r%   A   s>    	dD	 5R~~bggi(2245 5 5s   1AAc                      t         j                  j                  t              sy	 t        j
                  j                  t              d uS # t        t        t        f$ r Y yw xY w)NF)osr   isfileENGINE_PATH	importlibutil	find_specENGINE_MODULEImportError
ValueErrorModuleNotFoundError     r   _engine_presentr3   F   sN    77>>+&~~''6dBB%89 s   $A A"!A"c                   >    e Zd ZdZed        Zd Zd Zd Zd Z	d Z
y)	ArtifactSchemaTestu:   Engine-independent — 비교/decision artifact 무결성.c                 T    t        t              | _        t        t              | _        y N)r   
COMPARISONcmpDECISIONdec)clss    r   
setUpClasszArtifactSchemaTest.setUpClassR   s    
#/r2   c                    | j                  | j                  d   d       | j                  | j                  d   t               | j                  | j                  d          | j                  | j                  d   d   d       y )Ntaskztask-2553+40task_md_sha256engine_presentphase_bstateEXECUTED)assertEqualr9   TASK_MD_SHA
assertTrueselfs    r   test_comparison_identityz+ArtifactSchemaTest.test_comparison_identityW   si    &)>:"23[A!123),W5zBr2   c                 j   t         j                         D ]  }t        j                  j	                  t
        |dz         }| j                  t        j                  j                  |      |       t        |      }| j                  d|       | j                  |d   d       | j                  d|        y )N.json
profile_idversionz	^v[0-9]+$gate_predicate)	INSTANCESvaluesr'   r   joinPROFILE_DIRrG   r(   r   assertInassertRegex)rI   namepdocs       r   test_four_instances_presentz.ArtifactSchemaTest.test_four_instances_present]   s    $$& 	1D[$.9AOOBGGNN1-q1(CMM,,S^\:MM*C0	1r2   c                 D   | j                   d   }| j                  |d   d       | j                  |d   d       | j                  |d   d       | j                  |d   d       | j                  |d   d       | j                  |d          | j                  |d	          y )
Ndry_run_invariants
real_merger   real_github_writereal_thread_resolvec1_core_modified existing_2553_artifacts_modified!existing_governance_profile_byte0contamination)r9   rE   rG   assertFalse)rI   invs     r   .test_dry_run_invariants_zero_real_side_effectszAArtifactSchemaTest.test_dry_run_invariants_zero_real_side_effectsf   s    hh+,\*A.011523Q7/0!4?@!D?@A_-.r2   c                    | j                  | j                  d   d          | j                  | j                  d   d   g        | j                  | j                  d          | j                  | j                  d   d       y )NrB   all_targets_match_phase_amismatch_targetshold_for_chairdecisionTRACK_C_PASS)rG   r9   rE   rc   r;   rH   s    r   test_all_targets_match_no_holdz1ArtifactSchemaTest.test_all_targets_match_no_holdp   sm    +,GHI),-?@"E"234*-~>r2   c                     | j                  | j                  d          | j                  | j                  d   | j                  d          y )Nengine_byte0engine_sha256_beforeengine_sha256_after)rG   r9   rE   rH   s    r   test_engine_byte0_recordedz-ArtifactSchemaTest.test_engine_byte0_recordedv   s>    01HH+,dhh7L.M	
r2   N)__name__
__module____qualname____doc__classmethodr=   rJ   rY   re   rl   rq   r1   r2   r   r5   r5   O   s1    D" "C1/?
r2   r5   c                       e Zd ZdZd Zd Zy)EngineByteZeroTestuE   C1 engine + 기존 거버넌스 profile = byte-0 (read-only consume).c                 J    | j                  t        t              t               y r7   )rE   r%   r)   ENGINE_SHA_PINrH   s    r   test_engine_sha_pinnedz)EngineByteZeroTest.test_engine_sha_pinned   s    -~>r2   c                 J    | j                  t        t              t               y r7   )rE   r%   GOV_PROFILEGOV_PROFILE_SHA_PINrH   s    r   "test_governance_profile_sha_pinnedz5EngineByteZeroTest.test_governance_profile_sha_pinned   s    -/BCr2   N)rr   rs   rt   ru   r{   r   r1   r2   r   rx   rx   }   s    O?Dr2   rx   c                       e Zd ZdZd Zy)NoRealMergeStaticTestuS   정적 입증 — C1 engine 모듈에 실 merge/network/GitHub write 호출 부재.c                    t        t        dd      j                         }t        j                  |      }h d}g }t        j
                  |      D ]  }t        |t        j                        rN|j                  D ]>  }|j                  j                  d      d   |v s$|j                  |j                         @ kt        |t        j                        s|j                  xs dj                  d      d   |v s|j                  |j                          | j                  |g d|        | j                  d	|       | j                  d
|       y )Nr   r   r   >
   ghhttpxmergeGithubgithubsocketurllibrequests
subprocessmerge_pull_request.r    u9   C1 engine 에 부작용 import 발견(순수성 위반): u   부작용 0zGitHub API 0)r   r)   r#   astparsewalk
isinstanceImportnamesrV   splitappend
ImportFrommodulerE   rT   )rI   srctreebannedbadnodeas          r   0test_engine_module_has_no_network_or_merge_callszFNoRealMergeStaticTest.test_engine_module_has_no_network_or_merge_calls   s   ;g6;;=yy~
 HHTN 	,D$

+ +Avv||C(+v5

166*+ D#..1KK%2,,S1!4>JJt{{+	, 	PQTPUV	
 	mS)nc*r2   N)rr   rs   rt   ru   r   r1   r2   r   r   r      s
    ]+r2   r   c                   :    e Zd ZdZed        Zh dZd Zd Zd Z	y)EngineDryRunReproductionTestuD   Engine-consuming — dry-run only, 실 merge/write/thread resolve 0.c                     t               | _        t        t              | _        t        t
        j                  j                  t        d            }|d   d   D ci c]  }|d   |
 c}| _	        ddi| _
        y c c}w )Nz$task-2553+35.dry-run-comparison.jsonphase_atargetstargetr   zGemini thread resolve)r3   presentr   r8   r9   r'   r   rR   EVENTSb35	b35_alias)r<   r   ts      r   r=   z'EngineDryRunReproductionTest.setUpClass   so    %'
#GGLL!GH
 ,/y>)+DEa1X;>E#%<
 Fs   A:>   kindnoteactual_failedactual_ALL_PASSall_keys_independently_provenc                     g }|j                         D ]U  \  }}|| j                  v rt        |t              r|t        |      z  }4t        |t              sE|j                  |       W |S r7   )items_METAr   listboolr   )rI   egr   kvs        r   _baseline_gate_namesz1EngineDryRunReproductionTest._baseline_gate_names   sb    HHJ 	 DAqDJJ!T"a At$Q	  r2   c                 8   | j                   s| j                  d       t        j                  t              }|j
                  }|j                  }|j                  }| j                  t              5   |dddi       d d d        t        j                         D ]  \  }}| j                  j                  ||      }| j                  |   }d| d| t        |   d|ig d	d
}	 ||	      }
| j!                  |
d   |	d   |        ||
t"              }| j%                  |j&                  d| d|j&                   d       |j(                  D cg c]  }|j*                   }}t-        t.        j0                  j3                  t"        |dz               }t5        |d   j7                               }| j9                  |d         }| j!                  ||| d       | j!                  t;        |      t;        |      | dt;        |       dt;        |       d       | j!                  t=        t?        |j@                        t?        |jB                        z        g | d       | jE                  t?        |d         jG                  t?        |j@                              | d       | jE                  t?        |d         jG                  t?        |jB                              | d       | j%                  d|jH                  |       | j%                  d|jJ                  |        | j                  |      5 } | |ddddid      t"               d d d        | jE                  jL                  jN                         y # 1 sw Y   xY wc c}w # 1 sw Y   AxY w) NzC1 engine absentxdry_runT)	goal_typeboundaryzdryrun-2553p40-zdry-run application: rV   )r   no_real_mergeno_github_writeno_thread_resolve)goal_idgoal_statementr   policy_profiler   r   )profile_json_dir)RESOLVEDHOLD_FOR_CHAIRz!: status out of contract domain ()rL   rO   expected_gatez: gate roundtripz: gate count vs +35 baseline (z != u   : allowed∩forbidden 누수allowed_actionsz: allowed supersetforbidden_actionsz: forbidden supersetconcretezdryrun-2553p40-absentzabsent profile fail-closed__task2553p40_absent__)r   r   r   )(r   skipTestr*   import_moduler-   parse_goal_requestresolve_policyPolicyEngineErrorassertRaises	TypeErrorrP   r   r   getr   	GOAL_TYPErE   rS   rT   statusgaterV   r   r'   r   rR   r   keysr   lensortedsetr   r   rG   issubsetcompletion_packet_schemaevidence_schema	exceptioncode)rI   enginer   r   r   tgtpnameb35keybasegoal_requestgrresgengine_gateprofencoded	base_gatectxs                     r   /test_canonical_dry_run_matches_phase_a_baselinezLEngineDryRunReproductionTest.test_canonical_dry_run_matches_phase_a_baseline   ss   ||MM,-((7#66.."44 y) 	FSIt3DE	F $//+ 3	@JC^^''S1F88F#D,UG4$9#"?&s^#)5/	L $L1BR
^\*-EsK kBC MM

:%8AF
 ,/884a1664K4k57?CDD4 016689G11$2GHI['cU:J3KLK #i.% $%T#i.)9< s3../#c6K6K2LLMse78
 OOD*+,55c#:M:M6NO%)* OOD,-.77--. %+,	 MM*c&B&BCHMM*c&9&93?g3	@l 01 	S"6&B'-/G&H$ 
 "-	 	**+E	F 	F4 5>	 	s   0M>N5N>NNc                 P   dddd}| j                   d   d   D ci c]  }|d   |
 }}|j                         D ]e  \  }\  }}}t        t        j                  j                  t        |            }| j                  ||   ||       | j                  ||   d   ||       g y	c c}w )
uR   source event terminal status 를 독립 재도출 → comparison 충실 인코딩.)ztask-2553+12.result.jsonr   r   )ztask-2553+26.result.jsonoutcomeCOMPLETE_MERGED)ztask-2553+13.result.jsonr   DONE)r
   r   r   rB   dry_run_results_per_targetr   *actual_terminal_status_provenance_readonlyN)r9   r   r   r'   r   rR   r   rE   )	rI   rederiver   perr   fnkeyexpectrX   s	            r   /test_actual_terminal_status_provenance_readonlyzLEngineDryRunReproductionTest.test_actual_terminal_status_provenance_readonly  s    /H1J;>
 XXi()EF
 hKN
 
 '/nn&6 	"C""c6VR01CSXvr2CEF		
s   B#N)
rr   rs   rt   ru   rv   r=   r   r   r   r   r1   r2   r   r   r      s/    N	
 	
E
	K,Zr2   r   __main__   )	verbosity)+ru   builtins@py_builtins_pytest.assertion.rewrite	assertionrewrite
@pytest_arr   r!   r*   importlib.utilr   r'   unittestr   abspathrR   dirname__file__	REPO_ROOTr   rS   r8   r:   RESULTr-   r)   r}   rF   rz   r~   rP   r   r   r%   r3   TestCaser5   rx   r   r   rr   mainr1   r2   r   <module>r     s  "  
     	 GGOOBGGLL)BD$OP		i8	4ggll9h0ABWW\\&"HI
77<< <=	f8	9.ggll9h0JKggll;(NOPSF 
 'P(SA9	 'C(F?,	
5
+
** +
\D** D+H-- +6@8#4#4 @F zHMMA r2   