
    i                        d Z ddlZddlmc mZ ddlZddlZddl	m
Z
 ddlZej                  j                  d e e
e      j!                         j"                  d                ej                  j                  d e e
e      j!                         j"                  d   dz               ddlZej(                  j+                  d e e
e      j!                         j"                  d   dz  dz              Zg ZdZeeuZeZerej6                  ZdZeeuZeZesB ej>                  defd	eef      d
 ej@                         v s ejB                  e      r ejD                  e      nd
 ejD                  e      dz  Z#dde#iz  Z$ejK                  e$       er ej>                  defdeef      d
 ej@                         v s ejB                  e      r ejD                  e      nd
 ejD                  e       ejD                  e      dz  Z&dde&iz  Z'ejK                  e'        ejP                  ed      i z  Z)dde)iz  Z* e+ ejX                  e*            dxZxZxZxZxZxZZej(                  j[                  e      Z.ej6                  j_                  e.       ej`                  d        Z1d dZ2d!dZ3d Z4d Z5d Z6d Z7d Z8d Z9d Z:d Z;d Z<y)"uW   tests/dev7/test_tier_classifier.py — Tier 분류 + audit log 테스트 (task-2367 P1)    N)Path   scripts
auto_mergezauto_merge.py)is not)z%(py2)s is not %(py5)sSPEC)py2py5z%(py7)spy7)z5%(py11)s
{%(py11)s = %(py9)s.loader
} is not %(py14)s)py9py11py14z%(py16)spy16zassert %(py19)spy19c                 ,   | dz  dz  j                  d       | dz  dz  j                  d       | dz  dz  j                  d       | dz  dz  j                  d       | dz  dz  j                  d       |j                  d	t        |              | S )
u   격리된 임시 workspace.memoryeventsT)parentscapabilitiesaudittasksreportsWORKSPACE_ROOT)mkdirsetenvstr)tmp_pathmonkeypatchs     6/home/jay/workspace/tests/dev7/test_tier_classifier.pytmp_workspacer       s     8#**4*8>)000>7"))$)77"))$)79$++D+9'X7O    c           
          |dd| dd|xs g |xs g g |ddd}| dz  d	z  | d
z  }|j                  t        j                  |      d       |S )u   capability snapshot 생성.z2026-05-02T00:00:00zmemory/tasks/.mdabc1230   )pathsforbidden_pathscommandsmerge_policy	ttl_hours)task_idcaptured_atsourcesource_sha256allowed_resourcesr   r   z.jsonutf-8encoding)
write_textjsondumps)	workspacer+   r&   	forbiddenr)   cap	snap_files          r   _make_capabilityr:   !   sz     ,!'#.![b(B(
C H$~57)58IIIC7;r!   c                 V    d| d| d| d}| dz  dz  | dz  j                  |       y)	u*   task md 파일 생성 (frontmatter level).z---
task_id: z
level: z
---

# 
r   r   r#   N)r3   )r6   r+   levelcontents       r   _make_task_filer?   5   s?    wiy{7)2NGG#	o5AA'Jr!   c                    d}t        | |d       t        | |dg       t        j                  t	        |       d      }|j                  |dgd	d	
      }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}y)u5   Tier 1: Lv.0 + 작은 diff + 보호 경로 미포함.ztask-test-tier1r   r=   scripts/task-scope-guard.shr7   Tworkspace_pathdry_runsrc/utils/helper.py project_pathbranchtier1==z%(py0)s == %(py3)stierpy0py3assert %(py5)sr
   Nr?   r:   r   
AutoMergerr   classify_tier
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanationr    r+   mergerrP   @py_assert2@py_assert1@py_format4@py_format6s           r   test_tier1_lv0_small_diffrf   ;   s    GM7!4]G8U7VW""#m2Dd"SF*?)@rZ\]D47?47447r!   c                    d}t        | |d       t        | |       t        j                  t	        |       d      }|j                  |dgdd      }d	}||k(  }|st        j                  d
|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}y)u)   Tier 3: Lv.3 task → 자동으로 tier3.ztask-test-tier3-lv   rA   TrD   rG   rH   rI   tier3rM   rO   rP   rQ   rT   r
   NrU   r`   s           r   test_tier3_lv3rj   F       "GM7!4]G,""#m2Dd"SF*?)@rZ\]D47?47447r!   c                    d}t        | |d       t        | |dg       t        j                  t	        |       d      }|j                  |dgdd	      }d
}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}y)u9   Tier 3: forbidden_paths에 매칭되는 변경 → tier3.ztask-test-tier3-fp   rA   rB   rC   TrD   rH   rI   ri   rM   rO   rP   rQ   rT   r
   NrU   r`   s           r   test_tier3_protected_pathrn   Q   s    "GM7!4]G8U7VW""#m2Dd"SF*G)HWYbdeD47?47447r!   c                    d}t        | |d       t        j                  t        |       d      }|j	                  |dgdd      }d	}||k(  }|st        j                  d
|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}y)uV   Tier 3: 글로벌 보호 경로(CLAUDE.md, .github/) → tier3 (capability 없어도).ztask-test-tier3-globalr   rA   TrD   z	CLAUDE.mdrH   rI   ri   rM   rO   rP   rQ   rT   r
   N)r?   r   rV   r   rW   rX   rY   rZ   r[   r\   r]   r^   r_   r`   s           r   test_tier3_global_protectedrp   ]   s    &GM7!4 ""#m2Dd"SF+RPRSD47?47447r!   c                 4   d}t        | |d       t        | |       t        j                  t	        |       d      }t        d      D cg c]  }d| d
 }}|j                  ||d	d	
      }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}}yc c}w )u   Tier 2: 다중 파일(>5).ztask-test-tier2-multirm   rA   TrD      zsrc/filez.pyrH   rI   tier2rM   rO   rP   rQ   rT   r
   N)r?   r:   r   rV   r   rangerW   rX   rY   rZ   r[   r\   r]   r^   r_   )
r    r+   ra   idiffrP   rb   rc   rd   re   s
             r   test_tier2_multifilerw   h   s    %GM7!4]G,""#m2Dd"SF',Qx0!hqc0D0BrJD47?47447 1s   
Dc                    d}t        | |d       t        | |       t        j                  t	        |       d      }|j                  |dgdd      }d	}||k(  }|st        j                  d
|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}y)u1   Tier 2: package.json 변경 → 의존성 변경.ztask-test-tier2-deprm   rA   TrD   zpackage.jsonrH   rI   rs   rM   rO   rP   rQ   rT   r
   NrU   r`   s           r   test_tier2_dependency_changery   t   s    #GM7!4]G,""#m2Dd"SF.)9SUVD47?47447r!   c                    d}t        | |d       t        | |       t        j                  t	        |       d      }|j                  |dgdd      }d	}||k(  }|st        j                  d
|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}y)zTier 2: Lv.2 task.ztask-test-tier2-lvr   rA   TrD   rG   rH   rI   rs   rM   rO   rP   rQ   rT   r
   NrU   r`   s           r   test_tier2_lv2r{      rk   r!   c                 (   d}t        | |d       t        | |ddg       t        j                  t	        |       d      }|j                  |d	gd
d
      }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d      dz   d|iz  }t        t        j                  |            dx}}y)u_   ★ 본 task-2367 자체가 Tier 3로 분류되는지 (auto_merge.py 변경 — 보호 경로).z	task-2367rh   rA   rB   zmemory/capabilities/**rC   TrD   zscripts/auto_merge.pyrH   rI   ri   rM   rO   rP   rQ   uI   본 task가 자기 자신을 Tier 1으로 머지하면 self-bypass 사고z
>assert %(py5)sr
   N)r?   r:   r   rV   r   rW   rX   rY   rZ   r[   r\   r]   _format_assertmsgr^   r_   r`   s           r   test_self_bypass_preventionr~      s    GM7!402JK ""#m2Dd"SF*A)BQS\^_Dg47?ggg47gggggg4ggg4ggg7ggggggggggr!   c                    t         j                  t        |       d      }|j                  dddddddg d	d
dd       |j                  dddddddg d	d
dd       | dz  dz  dz  }|j                  } |       }|sddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t        t        j                  |            d
x}}|j                  d      j                         j                  d      }t        |      }d}||k(  }	|	st        j                   d|	fd||f      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }
d d!|
iz  }t        t        j                  |            d
x}x}	}t#        j$                  |d	         }t#        j$                  |d"         }|d#   }d"}||k(  }|slt        j                   d|fd$||f      t        j                  |      t        j                  |      d%z  }d&d'|iz  }
t        t        j                  |
            d
x}x}}|d#   }d}||k(  }|slt        j                   d|fd$||f      t        j                  |      t        j                  |      d%z  }d&d'|iz  }
t        t        j                  |
            d
x}x}}|d(   }d}||k(  }|slt        j                   d|fd$||f      t        j                  |      t        j                  |      d%z  }d&d'|iz  }
t        t        j                  |
            d
x}x}}|d(   }d}||k(  }|slt        j                   d|fd$||f      t        j                  |      t        j                  |      d%z  }d&d'|iz  }
t        t        j                  |
            d
x}x}}y
))u<   audit log JSONL append-only 동작 + sequence 단조 증가.TrD   t1mergedrL   passautoabcr   NrH   )r+   outcomerP   	qc_resultscope_guardra   	merge_sha
diff_filesdiff_loc	pr_numbercapability_shat2	escalatedri   skippedr   r   zauto-merge.logzAassert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}log_file)rR   r	   py4r0   r1   r<   r   rM   )z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)slenlines)rR   py1rS   py6zassert %(py8)spy8rm   sequence)z%(py1)s == %(py4)s)r   r   zassert %(py6)sr   r+   )r   rV   r   _append_auditexistsrZ   r[   rX   r\   r]   r^   r_   	read_textstripsplitr   rY   r4   loads)r    ra   r   rc   @py_assert3@py_format5r   rb   @py_assert5@py_assert4@py_format7@py_format9r1r2@py_assert0s                  r   test_audit_log_appendr      s   ""#m2Dd"SF
Th'-fPV',BA'+rC D Tk7'0V\')'+rC D
 x''14DDH???88?0668>>tDEu::?:33uu:	E!H	B	E!H	Bj>Q>Q>Q>Qj>Q>Q>Q>Qi= D =D    =D   =   D       i= D =D    =D   =   D       r!   )NNtiered)r   )=__doc__builtinsrZ   _pytest.assertion.rewrite	assertionrewriterX   r4   syspathlibr   pytestpathinsertr   __file__resolver   importlib.util	importlibutilspec_from_file_locationr   rc   r   r   r   loader@py_assert10@py_assert13@py_assert12rY   r[   r\   r]   re   @py_format8append@py_format15@py_format17_format_boolop@py_format18@py_format20r^   r_   module_from_specr   exec_modulefixturer    r:   r?   rf   rj   rn   rp   rw   ry   r{   r~   r    r!   r   <module>r      s   ]    
   3tH~--/77:; < 3tH~--/77:YFG H ~~--X ((+i7/IJ 44 3t4 3DKK 3t 3Kt3 3 3 3t4 3 3 3 3 3t 3 3 3t 3 3 34 3 3 3 3 3 3 3Kt 3 3 3 3 3D 3 3 3D 3 3 3K 3 3t 3 3 3 3 3 3 3 3 3 3 3 3 3^^,,T2
   
 #  (K		h!r!   