
    (<iP                        d Z ddlZddlZddlZddlmZ ddlZddlZ eej                  j                  dd            Z
e
dz  dz  dz  Zg d	Zd
edej                  fdZ ej                         d
edej                  fd       Z G d d      Z G d d      Zej&                  j)                  dd       ddlmZ d&dededefdZd'dededefdZd(dedededefdZdedededededefd Z G d! d"      Ze
dz  d#z  Z  G d$ d%      Z!y))u  
test_3docs_e2e.py — 3문서 2유형 체계 End-to-End 통합 테스트

Phase 1~5 구현 완료된 3문서 체계(plan.md / context-notes.md / checklist.md)의
전체 흐름을 4개 그룹으로 검증한다:
  1. dispatch → 3문서 자동 생성
  2. team_prompts 3문서 지침 포함 여부
  3. QC verifier 3문서 검증 (PASS / WARN / SKIP / FAIL 시나리오)
  4. DIRECT-WORKFLOW.md 3문서 단계 존재 확인

기존 tests/test_dispatch_task_docs.py 와 독립 파일로 작성되어 충돌 없이 병렬 실행 가능.
    N)PathWORKSPACE_ROOT/home/jay/workspaceprompts	templates	task-docs)zplan.template.mdzcontext-notes.template.mdzchecklist.template.mdtmp_pathreturnc                    t        t        j                  j                  dd            }t	        |      t
        j                  vr)t
        j                  j                  dt	        |             ddl}t        t
        j                  j                               D ]  }|dk(  s	t
        j                  |=  ddl}| |_        |S )uM   dispatch 모듈을 tmp_path를 WORKSPACE로 설정하여 격리 로드한다.r   r   r   Ndispatch)r   osenvirongetstrsyspathinsertprompts.team_promptslistmoduleskeysr   	WORKSPACE)r	   	workspacer   mod_name	_dispatchs        E/home/jay/workspace/.worktrees/task-2057-dev2/tests/test_3docs_e2e.py_load_dispatch_with_workspacer   '   s    RZZ^^$46KLMI
9~SXX%3y>*   ))+, &z!H%& ! #I    c              #   $  K   | dz  j                  dd       | dz  dz  j                  dd       | dz  dz  dz  }|j                  dd       t        D ]B  }t        |z  }|j                         s||z  j	                  |j                  d	      d	       D t        t        j                  j                  d
d            }t        j                  j                  d      }t        |       }| ||_        ||t        j                  d<   yyw)uU   격리된 WORKSPACE를 사용하는 dispatch 모듈 반환 + 템플릿 파일 복사.memoryTparentsexist_oktasksr   r   r   utf-8encodingr   r   r   N)mkdirTEMPLATE_FILESREAL_TEMPLATE_DIRexists
write_text	read_textr   r   r   r   r   r   r   r   )r	   tmpl_dirfnamesrcreal_workspace_original_dispatchmods          r   dispatch_modr4   A   s
     t<7"))$)F )#k1K?HNN4$N/ ]%'::<))#---*IT[)\]
 "**..)9;PQRN4
'
1C
I"CM%"4J &s   A0D3BDc                       e Zd ZdZdej
                  deddfdZdej
                  deddfdZdej
                  deddfdZ	y)	TestDispatchCreateTaskDocsu1   dispatch._create_task_docs() E2E 통합 테스트r4   r	   r
   Nc                 8   d}|j                  |d      }|J d       t        |t              sJ d       |dz  dz  d	z  |z  }|j                         s
J d
|        |j	                         sJ d       dD ]!  }||z  }|j                         rJ d|         y)u#  level=3(critical)에서 tasks/{task_id}/ 디렉토리와 3문서 파일이 생성된다.

        _create_task_docs(task_id, level=3) 호출 후
        memory/plans/tasks/{task_id}/ 경로에 plan.md, context-notes.md,
        checklist.md 세 파일이 모두 존재해야 한다.
        	task-9001   levelNu>   _create_task_docs가 None을 반환했다 (Path 반환 기대)u(   반환값이 Path 타입이어야 한다r    plansr$   u(   디렉토리가 생성되지 않았다: u4   디렉토리가 파일이 아닌 폴더여야 한다plan.mdcontext-notes.mdchecklist.mdu*   3문서 파일이 생성되지 않았다: )_create_task_docs
isinstancer   r+   is_dir)selfr4   r	   task_idresultexpected_dirr/   fpaths           r   5test_critical_level_creates_directory_and_three_fileszPTestDispatchCreateTaskDocs.test_critical_level_creates_directory_and_three_filesd   s     //q/A!c#cc!&$'S)SS'(*W4w>H""$_(PQ]P^&__$""$\&\\$D 	XE 5(E<<>W%OPUw#WW>	Xr   c                     d}|j                  |d       |dz  dz  dz  |z  }dD ]  }||z  }|j                         s
J d|        |j                  d	
      }|j                  d      s
J | d       |j	                  dd      }|d| j                         }	t        j                  |	      }
dD ]  }||
v rJ | d| d        |
d   |k(  sJ | d| d|
d           d|vs
J | d       d|vrJ | d        y)u   생성된 3문서 각각의 YAML frontmatter에 필수 필드 4개가 존재한다.

        task_id, type, scope, status 필드가 있어야 하며,
        {task_id} / {date} 플레이스홀더가 실제 값으로 치환되어야 한다.
        z	task-9002r9   r:   r    r<   r$   r=   u   파일이 없다: r%   r&   z---u   : YAML frontmatter(---) 없음)rE   typescopestatusu   : 필수 YAML 필드 'u   ' 없음rE   u$   : task_id 치환 실패 — 기대: u
   , 실제: z	{task_id}u(   : {task_id} 플레이스홀더 미치환z{date}u%   : {date} 플레이스홀더 미치환N)rA   r+   r-   
startswithindexstripyaml	safe_load)rD   r4   r	   rE   rG   r/   rH   contentend_idx	yaml_textdatafields               r   )test_yaml_frontmatter_has_required_fieldszDTestDispatchCreateTaskDocs.test_yaml_frontmatter_has_required_fields{   so    &&wa&8(*W4w>HD 	^E 5(E<<>?%7w#??>oowo7G%%e,V7U.VV,mmE1-G'*002I>>),D? V}U/EeWH&UU}V 	?g- '=gYjQUV_Q`Pab- g-c%8b/cc-7*]ug5\,]]*%	^r   c                   	 d}dddd}|j                  dd      }g |j                  	dt        dt        d	t        f	fd
}t        |d|       	 |dk\  r|j                  ||       t        |d	       t              dk(  sJ d       |dz  dz  dz  |z  }|j                         r
J d|        y# t        |d	       w xY w)u  dispatch 내부 로직에서 level=2(normal)일 때는 _create_task_docs가 호출되지 않는다.

        dispatch()는 내부 레벨 정수가 3 이상일 때만 _create_task_docs를 호출한다.
        level<3 조건을 재현하여 호출 횟수가 0임을 검증한다.
        z	task-9003   r9      )normalcriticalsecurityr\   tidlvr
   c                 <    j                  | |f        | |      S )N)append)r_   r`   calledoriginal_fns     r   _tracking_fnzaTestDispatchCreateTaskDocs.test_normal_level_does_not_call_create_task_docs.<locals>._tracking_fn   s     MM3)$sB''r   rA   r   uF   normal(Lv.2) 레벨에서 _create_task_docs가 호출되면 안 된다r    r<   r$   uE   normal 레벨에서 3문서 디렉토리가 생성되면 안 된다: N)r   rA   r   intobjectsetattrlenr+   )
rD   r4   r	   rE   _level_to_int
docs_levelre   rG   rc   rd   s
           @@r   0test_normal_level_does_not_call_create_task_docszKTestDispatchCreateTaskDocs.test_normal_level_does_not_call_create_task_docs   s     #$!C"&&x3
(*"44	(c 	(s 	(v 	( 	1<@	DQ..w
CL"5{C6{ai!ii  (*W4w>H&&( 	
ST`Sab	
(( L"5{Cs   B4 4C)
__name__
__module____qualname____doc__types
ModuleTyper   rI   rX   rl    r   r   r6   r6   a   sw    ;X!,,X8<X	X.^!,,^8<^	^B!
!,,!
8<!
	!
r   r6   c                   \    e Zd ZdZ ej
                  d      d	d       Zd	dZd	dZd	dZ	y)
TestTeamPromptsThreeDocsSectionu=   team_prompts._build_three_docs_section() E2E 통합 테스트TautouseNc                     t        t        j                  j                  dd            }t	        |      t
        j                  vr)t
        j                  j                  dt	        |             ddlm	} || _
        y)u4   _build_three_docs_section 함수를 임포트한다.r   r   r   )_build_three_docs_sectionN)r   r   r   r   r   r   r   r   r   ry   _build)rD   r   ry   s      r   _import_build_fnz0TestTeamPromptsThreeDocsSection._import_build_fn   sO     (8:OPQ	y>)HHOOAs9~.B/r   c                 >    | j                  dd      }d|v sJ d       y)u  level='critical'이면 반환 문자열에 '3문서 활용 지침' 텍스트가 포함된다.

        _build_three_docs_section("task-9001", "critical") 호출 결과에
        '3문서 활용 지침' 문자열이 반드시 포함되어야 한다.
        r8   r]   u   3문서 활용 지침uA   critical 레벨에서 '3문서 활용 지침' 텍스트가 없다Nrz   rD   rF   s     r   4test_critical_level_contains_three_docs_guide_headerzTTestTeamPromptsThreeDocsSection.test_critical_level_contains_three_docs_guide_header   s,     [*5&&0 	
O	
0r   c                 >    | j                  dd      }d|v sJ d       y)u  level='critical'이면 '보고서 작성 전 3문서 업데이트' 문구가 포함된다.

        _build_three_docs_section("task-9001", "critical") 호출 결과에
        보고서 작성 전 3문서 업데이트를 안내하는 텍스트가 포함되어야 한다.
        r8   r]   u)   보고서 작성 전 3문서 업데이트uY   critical 레벨에서 '보고서 작성 전 3문서 업데이트' 안내 문구가 없다Nr}   r~   s     r   1test_critical_level_contains_update_before_reportzQTestTeamPromptsThreeDocsSection.test_critical_level_contains_update_before_report   s,     [*5:fD 	
g	
Dr   c                 X    | j                  dd      }|dk(  sJ dt        |              y)u   level='normal'이면 빈 문자열('')을 반환한다.

        normal(Lv.2) 수준 작업에서는 3문서 지침이 불필요하므로
        _build_three_docs_section 이 빈 문자열을 반환해야 한다.
        z	task-9004r\    uE   normal 레벨에서 빈 문자열이 반환되어야 한다. 실제: N)rz   reprr~   s     r   &test_normal_level_returns_empty_stringzFTestTeamPromptsThreeDocsSection.test_normal_level_returns_empty_string   s9     [(3| 	
STXY_T`Sab	
|r   r
   N)
rm   rn   ro   rp   pytestfixturer{   r   r   r   rs   r   r   ru   ru      s1    GV^^D!0 "0	
	
	
r   ru   z+/home/jay/workspace/teams/dev6/qc/verifiers)verifyrE   rM   c                     d|  d| d|  dS )u,   테스트용 plan.md 내용을 생성한다.---
task_id: zH
type: plan
scope: task
created: 2026-04-16
updated: 2026-04-16
status: u   
---

# 계획서: uR   

## 목표

E2E 통합 테스트 완성

## 범위

3문서 체계 전체 검증
rs   )rE   rM   s     r   _make_plan_mdr      s1    9 
 ( y !)	*r   placeholderc                 &    |sdnd}d|  d|  d| dS )u5   테스트용 context-notes.md 내용을 생성한다.u   실제 결정 근거 내용u!   결정 근거: [미입력 내용]r   um   
type: context
scope: task
created: 2026-04-16
updated: 2026-04-16
status: in-progress
---

# 맥락 노트: u   

## 결정 근거


rs   )rE   r   bodys      r   _make_context_notes_mdr     s9    0;(AdD9  $9 %&
	r   	completedtotalc                     g }t        |      D ]6  }||k  r|j                  d|dz            |j                  d|dz           8 dj                  |      }d|  d|  d| dS )u]   테스트용 checklist.md 내용을 생성한다. completed/total 비율로 완료율 설정.u   - [x] 항목    u   - [ ] 항목 r   r   uq   
type: checklist
scope: task
created: 2026-04-16
updated: 2026-04-16
status: in-progress
---

# 체크리스트: z

)rangerb   join)rE   r   r   linesichecklist_bodys         r   _make_checklist_mdr   "  s    E5\ 2y=LL=Q01LL=Q01	2
 YYu%N9  &Yd
"		r   r   plan_contentcontext_contentchecklist_contentc                     | dz  dz  dz  |z  }|j                  dd       |dz  j                  |d       |d	z  j                  |d       |d
z  j                  |d       |S )uT   tmp workspace에 3문서 파일을 기록하고 디렉토리 경로를 반환한다.r    r<   r$   Tr!   r>   r%   r&   r?   r@   )r(   r,   )r   rE   r   r   r   docs_dirs         r   _write_three_docsr   9  s|     8#g-7'AHNN4$N/	%%lW%E""...Q**+<w*OOr   c                   `    e Zd ZdZdeddfdZdeddfdZdeddfdZdeddfdZdeddfd	Z	y)
TestQcVerifierThreeDocsuY   three_docs_check.verify() E2E 통합 테스트 — PASS / WARN / SKIP / FAIL 시나리오r	   r
   Nc                     d}t        ||t        |d      t        |d      t        |dd      	       t	        |t        |      
      }|d   dk(  sJ d|d    d|d           y)u[  PASS 시나리오: 3문서 존재 + YAML 유효 + status!=draft + 체크리스트 50%+.

        3문서가 모두 존재하고, YAML frontmatter 필수 필드가 있으며,
        plan.md status가 draft가 아니고, checklist 완료율이 50% 이상이고,
        플레이스홀더가 없으면 결과 status가 'PASS'여야 한다.
        ztask-e2e-passin-progressrM   Fr   r9   r[   r   r   r   rE   r   r   r   rE   r   rM   PASSu=   PASS 시나리오에서 상태가 PASS여야 한다. 실제:    
메시지: messageNr   r   r   r   _three_docs_verifyr   rD   r	   rE   rF   s       r   test_pass_scenarioz*TestQcVerifierThreeDocs.test_pass_scenarioL  s     "&w}E27N0AQO	
 $Gs8}Mh6) 	
KFS[L\K] ^ +,.	
)r   c                     d}t        ||t        |d      t        |d      t        |dd      	       t	        |t        |      
      }|d   dk(  sJ d|d    d|d           y)u   WARN 시나리오: plan.md status=draft면 WARN이 반환된다.

        3문서가 모두 존재하더라도 plan.md의 status 필드가 'draft'이면
        결과 status가 'WARN'이어야 한다.
        ztask-e2e-warn-draftdraftr   Fr   r9   r[   r   r   r   rM   WARNu9   plan.md status=draft이면 WARN이어야 한다. 실제: r   r   Nr   r   s       r   test_warn_scenario_draft_statusz7TestQcVerifierThreeDocs.test_warn_scenario_draft_statusb  s     (&ww?27N0AQO	
 $Gs8}Mh6) 	
GxHXGY Z +,.	
)r   c                     d}t        ||t        |d      t        |d      t        |dd      	       t	        |t        |      
      }|d   dk(  sJ d|d    d|d           y)u   WARN 시나리오: 플레이스홀더 미치환 잔존 시 WARN이 반환된다.

        context-notes.md 본문에 '[미입력 내용]' 형태의 플레이스홀더가 남아 있으면
        결과 status가 'WARN'이어야 한다.
        ztask-e2e-warn-phr   r   Tr   r9   r[   r   r   r   rM   r   u<   플레이스홀더 잔존 시 WARN이어야 한다. 실제: r   r   Nr   r   s       r   %test_warn_scenario_placeholder_existsz=TestQcVerifierThreeDocs.test_warn_scenario_placeholder_existsw  s     %&w}E27M0AQO	
 $Gs8}Mh6) 	
J6RZK[J\ ] +,.	
)r   c                 j    d}t        |t        |            }|d   dk(  sJ d|d    d|d           y)	u   SKIP 시나리오: 3문서 디렉토리 자체가 없으면 SKIP이 반환된다.

        Lv.2 이하 작업처럼 memory/plans/tasks/{task_id}/ 디렉토리가 없으면
        결과 status가 'SKIP'이어야 한다.
        ztask-e2e-skip-nodirectoryr   rM   SKIPu6   디렉토리 없을 때 SKIP이어야 한다. 실제: r   r   N)r   r   r   s       r   test_skip_scenario_no_directoryz7TestQcVerifierThreeDocs.test_skip_scenario_no_directory  sX     . $Gs8}Mh6) 	
DVHEUDV W +,.	
)r   c                 0   d}|dz  dz  dz  |z  }|j                  dd       |dz  j                  t        |d	      d
       |dz  j                  t        |d      d
       t	        |t        |            }|d   dk(  sJ d|d    d|d           y)u  FAIL 시나리오: 3문서 디렉토리는 있으나 파일 중 하나가 누락되면 FAIL이 반환된다.

        memory/plans/tasks/{task_id}/ 디렉토리는 존재하지만
        checklist.md가 없는 경우 결과 status가 'FAIL'이어야 한다.
        ztask-e2e-fail-missingr    r<   r$   Tr!   r>   r   r   r%   r&   r?   Fr   r   rM   FAILu0   파일 누락 시 FAIL이어야 한다. 실제: r   r   N)r(   r,   r   r   r   r   )rD   r	   rE   r   rF   s        r   test_fail_scenario_missing_filez7TestQcVerifierThreeDocs.test_fail_scenario_missing_file  s     *h&07:WDtd3 
I	))'-87 	* 	
 
&	&22"7> 	3 	

 $Gs8}Mh6) 	
>vh?O>P Q +,.	
)r   )
rm   rn   ro   rp   r   r   r   r   r   r   rs   r   r   r   r   I  sd    c
4 
D 
,
 
 
*
d 
t 
*
 
 

 
 
r   r   zDIRECT-WORKFLOW.mdc                   \    e Zd ZdZ ej
                  d      d	d       Zd	dZd	dZd	dZ	y)
 TestDirectWorkflowThreeDocsStepsuV   DIRECT-WORKFLOW.md에 3문서 관련 단계 텍스트가 존재하는지 확인한다.Trv   Nc                 ~    t         j                         sJ dt                 t         j                  d      | _        y)uO   DIRECT-WORKFLOW.md 파일 내용을 읽어 인스턴스 변수에 저장한다.u%   DIRECT-WORKFLOW.md 파일이 없다: r%   r&   N)DIRECT_WORKFLOW_PATHr+   r-   _contentrD   s    r   _read_workflow_contentz7TestDirectWorkflowThreeDocsSteps._read_workflow_content  s@     $**, 	
34H3IJ	
, -666Hr   c                 .    d| j                   v sJ d       y)u  DIRECT-WORKFLOW.md에 Step 1.2 '3문서 확인' 텍스트가 존재한다.

        워크플로우 1.2단계에 '3문서 확인' 지시가 명시되어 있어야
        팀장이 작업 시작 시 3문서를 확인한다는 것을 알 수 있다.
        u   3문서 확인uC   DIRECT-WORKFLOW.md에 'Step 1.2 3문서 확인' 텍스트가 없다Nr   r   s    r   %test_step_1_2_three_docs_check_existszFTestDirectWorkflowThreeDocsSteps.test_step_1_2_three_docs_check_exists  s       4==0 	
Q	
0r   c                 .    d| j                   v sJ d       y)u  DIRECT-WORKFLOW.md에 Step 5.2 '3문서 업데이트' 텍스트가 존재한다.

        워크플로우 5.2단계에 '3문서 업데이트' 지시가 명시되어 있어야
        작업 완료 전 3문서를 갱신하는 절차가 강제된다.
        u   3문서 업데이트uI   DIRECT-WORKFLOW.md에 'Step 5.2 3문서 업데이트' 텍스트가 없다Nr   r   s    r   &test_step_5_2_three_docs_update_existszGTestDirectWorkflowThreeDocsSteps.test_step_5_2_three_docs_update_exists  s      &6 	
W	
6r   c                 .    d| j                   v sJ d       y)u  DIRECT-WORKFLOW.md에 Step 5.3 '3문서 검증 강제' 텍스트가 존재한다.

        워크플로우 5.3단계에 '3문서 검증 강제' 지시가 명시되어 있어야
        .done 생성 전 QC verifier 검증이 강제됨을 명확히 한다.
        u   3문서 검증 강제uJ   DIRECT-WORKFLOW.md에 'Step 5.3 3문서 검증 강제' 텍스트가 없다Nr   r   s    r   -test_step_5_3_three_docs_verify_forced_existszNTestDirectWorkflowThreeDocsSteps.test_step_5_3_three_docs_verify_forced_exists  s      '$--7 	
X	
7r   r   )
rm   rn   ro   rp   r   r   r   r   r   r   rs   r   r   r   r     s3    `V^^D!I "I


r   r   )r   )F)r9   r[   )"rp   r   r   rq   pathlibr   r   rQ   r   r   REAL_WORKSPACEr*   r)   rr   r   r   r4   r6   ru   r   r   three_docs_checkr   r   r   r   boolr   rf   r   r   r   r   r   rs   r   r   <module>r      s   
 
     bjjnn%57LMN"Y.<{J D U5E5E 4 54 5E$4$4 5 5>\
 \
H,
 ,
h @ A 93   &C d s $   C .  	
  
 i
 i
` &	14HH '
 '
r   