
     im                        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Ze
j                  j                  ed      Zd Z	  e       Zej$                  Zej&                  Zej(                  Zej*                  Zej,                  Zej.                  ZdZej4                  j7                  e d	      Zd
ZdZdZdZ dZ!dZ"dZ#dZ$dZ%dZ&ejN                  d        Z(ejN                  d        Z)ejN                  d        Z*ejN                  d        Z+ejN                  d        Z,ejN                  d        Z-ejN                  d        Z.ejN                  d        Z/ejN                  d        Z0 G d d      Z1 G d d       Z2 G d! d"      Z3 G d# d$      Z4 G d% d&      Z5 G d' d(      Z6 G d) d*      Z7 G d+ d,      Z8 G d- d.      Z9y# e$ r dZY 9w xY w)/uT   
TDD 단위 테스트: meeting-audit.py
작성자: 하누만 (개발4팀 테스터)
    Nz/home/jay/workspace/scriptszmeeting-audit.pyc                      t         j                  j                  dt              } d }| |u}|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t               dz   d|iz  }t        t	        j                  |            d x}}t         j                  j                  |       }| j                  }d }||u}|st	        j
                  d|fd	||f      dt        j                         v st	        j                  |       rt	        j                  |       ndt	        j                  |      t	        j                  |      d
z  }t	        j                  d      dz   d|iz  }t        t	        j                  |            d x}x}}| j                  j                  |       |S )Nmeeting_auditis not)z%(py0)s is not %(py3)sspec)py0py3zCannot load spec from z
>assert %(py5)spy5)z2%(py2)s
{%(py2)s = %(py0)s.loader
} is not %(py5)s)r   py2r
   zspec.loader is Nonez
>assert %(py7)spy7)	importlibutilspec_from_file_location_MODULE_PATH
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_saferepr_format_assertmsgAssertionError_format_explanationmodule_from_specloaderexec_module)	r   @py_assert2@py_assert1@py_format4@py_format6mod@py_assert4@py_assert3@py_format8s	            //home/jay/workspace/tests/test_meeting_audit.py_load_meeting_auditr&      s%   >>11/<PDD4tDDD4tDDDDDD4DDD4DDDtDDD5l^DDDDDDD
..
)
)$
/C;;9d9;d"999;d99999949994999;999d999$99999999KKC J    TFu?   meeting-audit.py 모듈이 아직 구현되지 않았습니다.reasonzJ/home/jay/workspace/memory/meetings/2026-04-11-insuwiki-review-trust-ux.mdzC/home/jay/workspace/skills/agent-meeting/references/persona-list.mduj  # Agent 미팅: 테스트용 미팅

**날짜**: 2026-04-11
**소집 이유**: 테스트
**참여 페르소나**: 토르 (Thor), 로키 (Loki)
**미팅 모드**: sync
**토론 깊이**: normal
**총 사이클 수**: 3

## Cycle 1

내용 1

## Cycle 2

내용 2

## Cycle 3

내용 3

## 3문서 반영

계획서와 맥락노트, 체크리스트 반영 완료.
u}  # Agent 미팅: DA 포함 테스트

**날짜**: 2026-04-11
**소집 이유**: DA 테스트
**참여 페르소나**: 토르 (Thor), 로키 (Loki)
**미팅 모드**: hybrid
**토론 깊이**: thorough
**총 사이클 수**: 3

## Cycle 1

내용 1

## Cycle 2

내용 2

## Cycle 3 — Devil's Advocate

### Devil's Advocate

**지정**: 로키

1. **실패 시나리오**: 시스템 실패 가능성 분석
2. **후회 이유**: 현재 접근법의 후회 요소
3. **더 단순한 대안**: 단순한 대안 제안

**반박**: 위 우려에 대한 팀의 반박 내용.
**판정**: 반박 수용. DA 우려 대응책 설계에 포함.
u  # Agent 미팅: DA 없는 테스트

**날짜**: 2026-04-11
**소집 이유**: DA 없음 테스트
**참여 페르소나**: 토르 (Thor), 로키 (Loki)
**미팅 모드**: sync
**토론 깊이**: normal
**총 사이클 수**: 2

## Cycle 1

내용 1

## Cycle 2

내용 2
u!  # Agent 미팅: 미등록 페르소나 테스트

**날짜**: 2026-04-11
**소집 이유**: 미등록 페르소나 테스트
**참여 페르소나**: 엔키(백엔드), 이쉬타르(프론트엔드), 로키 (Loki)
**미팅 모드**: sync
**토론 깊이**: normal
**총 사이클 수**: 1
u   # Agent 미팅: 로키 없는 테스트

**날짜**: 2026-04-11
**소집 이유**: 로키 없음 테스트
**참여 페르소나**: 토르 (Thor), 미미르 (Mimir)
**미팅 모드**: sync
**토론 깊이**: normal
**총 사이클 수**: 1
u:  # Agent 미팅: 3문서 반영 테스트

**날짜**: 2026-04-11
**소집 이유**: 3문서 테스트
**참여 페르소나**: 토르 (Thor), 로키 (Loki)
**미팅 모드**: sync
**토론 깊이**: normal
**총 사이클 수**: 1

## 3문서 반영

계획서, 맥락노트, 체크리스트 모두 반영 완료.
u$  # Agent 미팅: 3문서 미언급 테스트

**날짜**: 2026-04-11
**소집 이유**: 3문서 미언급 테스트
**참여 페르소나**: 토르 (Thor), 로키 (Loki)
**미팅 모드**: sync
**토론 깊이**: normal
**총 사이클 수**: 1

## 합의 사항

아무 문서 언급 없음.
u  # 페르소나 목록

| 페르소나 | 팀 | 전문성 관점 |
|---------|-----|-----------|
| 토르 (Thor) | 개발2팀 / 백엔드 | 고성능 서버 |
| 불칸 (Vulcan) | 개발1팀 / 백엔드 | API 설계 |
| 프레이야 (Freya) | 개발2팀 / 프론트 | 인터랙티브 UI |
| 이리스 (Iris) | 개발1팀 / 프론트 | 컴포넌트 설계 |
| 미미르 (Mimir) | 개발2팀 / UX | 데이터 기반 UX |
| 아테나 (Athena) | 개발1팀 / UX | 유저 플로우 |
| 헤임달 (Heimdall) | 개발2팀 / 테스트 | 보안 중심 QA |
| 아르고스 (Argos) | 개발1팀 / 테스트 | 엣지 케이스 |
| 로키 (Loki) | 레드팀 | 보안 취약점 |
| 야누스 (Janus) | DevOps 센터 | 인프라 |
| 마아트 (Ma'at) | QC 센터 | 독립 품질 검증 |
| 비너스 (Venus) | 디자인 센터 | 디자인 방향성 |
| 오딘 (Odin) | 개발2팀장 | 아키텍처 |
| 헤르메스 (Hermes) | 개발1팀장 | 풀스택 |
c                 P    | dz  }|j                  t        d       t        |      S )Nzpersona-list.mdutf-8encoding)
write_textPERSONA_LIST_CONTENTstr)tmp_pathps     r%   tmp_persona_listr3      s'    $$ALL%L8q6Mr'   c                 P    | dz  }|j                  t        d       t        |      S )Nzminimal-meeting.mdr+   r,   )r.   MINIMAL_MEETING_CONTENTr0   r1   fs     r%   minimal_meetingr8      s'    ''ALL(7L;q6Mr'   c                 P    | dz  }|j                  t        d       t        |      S )Nzda-meeting.mdr+   r,   )r.   DA_MEETING_CONTENTr0   r6   s     r%   
da_meetingr;      s&    ?"ALL#gL6q6Mr'   c                 P    | dz  }|j                  t        d       t        |      S )Nzno-da-meeting.mdr+   r,   )r.   NO_DA_MEETING_CONTENTr0   r6   s     r%   no_da_meetingr>      s'    %%ALL&L9q6Mr'   c                 P    | dz  }|j                  t        d       t        |      S )Nzunreg-persona-meeting.mdr+   r,   )r.   UNREGISTERED_PERSONA_CONTENTr0   r6   s     r%   unregistered_persona_meetingrA      s'    --ALL-L@q6Mr'   c                 P    | dz  }|j                  t        d       t        |      S )Nzno-loki-meeting.mdr+   r,   )r.   NO_LOKI_CONTENTr0   r6   s     r%   no_loki_meetingrD      s&    ''ALL7L3q6Mr'   c                 P    | dz  }|j                  t        d       t        |      S )Nzthree-docs-meeting.mdr+   r,   )r.   THREE_DOCS_CONTENTr0   r6   s     r%   three_docs_meetingrG      s'    **ALL#gL6q6Mr'   c                 P    | dz  }|j                  t        d       t        |      S )Nzno-three-docs-meeting.mdr+   r,   )r.   NO_THREE_DOCS_CONTENTr0   r6   s     r%   no_three_docs_meetingrJ     s'    --ALL&L9q6Mr'   c                 H    | dz  }|j                  dd       t        |      S )Nzempty-meeting.md r+   r,   )r.   r0   r6   s     r%   empty_meetingrM   	  s&    %%ALLgL&q6Mr'   c                   *    e Zd Zd Zd Zd Zd Zd Zy)TestParseMeetingFilec                 r
   t        t              }t        |t              }|sd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dt	        j
                         v st        j                  t              rt        j                  t              ndt        j                  |      dz  }t        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}||v }|st        j                  d|fd||f      t        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            dx}}|d   }	t        |	t              }
|
sddt	        j
                         v st        j                  t              rt        j                  t              ndt        j                  |	      dt	        j
                         v st        j                  t              rt        j                  t              ndt        j                  |
      dz  }t        t        j                  |            dx}	}
|d   }	t        |	      }d}||k\  }|st        j                  d|fd||f      dt	        j
                         v st        j                  t              rt        j                  t              ndt        j                  |	      t        j                  |      t        j                  |      d z  }d!d"|iz  }t        t        j                  |            dx}	x}x}}y)#uB   실제 미팅 파일을 파싱하여 메타데이터 추출 확인5assert %(py4)s
{%(py4)s = %(py0)s(%(py1)s, %(py2)s)
}
isinstanceresultdictr   py1r   py4Ntotal_cycles   ==z%(py1)s == %(py4)srV   rW   assert %(py6)spy6modehybriddepththoroughcontentinz%(py1)s in %(py3)srV   r	   assert %(py5)sr
   personas5assert %(py5)s
{%(py5)s = %(py0)s(%(py2)s, %(py3)s)
}listr   r   r	   r
      >=z0%(py4)s
{%(py4)s = %(py0)s(%(py2)s)
} >= %(py7)slenr   r   rW   r   assert %(py9)spy9)parse_meeting_fileREAL_MEETING_FILErR   rT   r   r   r   r   r   r   r   r   rl   rr   )selfrS   r#   @py_format5@py_assert0r   @py_format7r   r    r   r"   @py_assert6@py_assert5r$   @py_format10s                  r%   test_parse_real_meeting_filez1TestParseMeetingFile.test_parse_real_meeting_file  s   #$56&$''''''''z'''z''''''&'''&''''''$'''$''''''''''n%**%****%***%**********f~))~))))~)))~))))))))))g,*,*,,,,*,,,,,,*,,,,,,,"yF""""yF"""y""""""F"""F""""""" ,3z,d33333333z333z333,333333d333d3333333333*%+s%&+!+&!++++&!++++++s+++s+++%+++&+++!+++++++r'   c                    t        |      }dD ]  }||v }|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      nddt        j                         v st        j
                  |      rt        j                  |      nddz  }t        j                  d|       dz   d	|iz  }t        t        j                  |            d
} y
)u9   파싱 결과에 필수 키가 모두 포함되어야 함rX   rj   r`   rb   rd   re   z%(py0)s in %(py2)skeyrS   r   r      필수 키 누락: 
>assert %(py4)srW   N)
rv   r   r   r   r   r   r   r   r   r   )rx   r8   rS   r   r   @py_format3ry   s          r%    test_parse_returns_required_keysz5TestParseMeetingFile.test_parse_returns_required_keys"  s    #O4K 	>C&====3&======3===3======&===&====$7u"=======	>r'   c                    t        |      }|d   }t        |t              }|sddt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dz  }t        t        j                  |            d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)u2   총 사이클 수가 정수로 파싱되어야 함rX   rk   rR   intrm   N   rZ   r\   r]   r^   r_   )rv   rR   r   r   r   r   r   r   r   r   r   )rx   r8   rS   r   r"   r    rz   r#   r   ry   r{   s              r%   test_parse_cycle_count_integerz3TestParseMeetingFile.test_parse_cycle_count_integer(  s    #O4 06z0#66666666z666z6660666666#666#6666666666n%**%****%***%**********r'   c                    t        |      }|d   }t        |t              }|sddt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dz  }t        t        j                  |            dx}}y)u)   personas가 리스트 타입이어야 함rj   rk   rR   rl   rm   N)
rv   rR   rl   r   r   r   r   r   r   r   )rx   r8   rS   r   r"   r    s         r%   test_parse_personas_listz-TestParseMeetingFile.test_parse_personas_list.  s    #O4 ,3z,d33333333z333z333,333333d333d3333333333r'   c                     t        |      }|d   }|s8ddt        j                  |      iz  }t        t        j                  |            d}y)u-   content 필드가 비어 있지 않아야 함rd   zassert %(py1)srV   N)rv   r   r   r   r   )rx   r8   rS   rz   @py_format2s        r%   test_parse_content_not_emptyz1TestParseMeetingFile.test_parse_content_not_empty3  s8    #O4i             r'   N)__name__
__module____qualname__r   r   r   r   r    r'   r%   rO   rO     s    
,>+4
!r'   rO   c                   @    e Zd ZdedefdZd Zd Zd Zd Z	d Z
d	 Zy
)TestCheckCycleCountcyclesreturnc                     |g ddddS )NsyncnormalrL   r   r   )rx   r   s     r%   _make_parsedz TestCheckCycleCount._make_parsed?  s    "
 	
r'   c                 @   | j                  d      }t        |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}}y
)u   Lv.2 + 2사이클 → PASSrY   levelstatusPASSrZ   r\   r]   r^   r_   Nactualexpected_minrn   r   check_cycle_countr   r   r   r   r   rx   parsedrS   rz   r#   r   ry   r{   s           r%   test_check_cycle_count_passz/TestCheckCycleCount.test_check_cycle_count_passH  s   ""1%"63h)6)6))))6))))))6)))))))h$1$1$$$$1$$$$$$1$$$$$$$n%**%****%***%**********r'   c                    | j                  d      }t        |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}||v }|st        j                  d|fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }	t        t        j                  |	            dx}}y)u+   Lv.4 + 2사이클 → FAIL (expected_min=3)rY      r   r   FAILrZ   r\   r]   r^   r_   Nr   r   r   messagere   rg   rS   rh   ri   r
   )
r   r   r   r   r   r   r   r   r   r   )
rx   r   rS   rz   r#   r   ry   r{   r   r    s
             r%   test_check_cycle_count_failz/TestCheckCycleCount.test_check_cycle_count_failQ  sm   ""1%"63h)6)6))))6))))))6)))))))h$1$1$$$$1$$$$$$1$$$$$$$n%**%****%***%**********"yF""""yF"""y""""""F"""F"""""""r'   c                 @   | j                  d      }t        |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}}y)u7   Lv.1 → 사이클 수 체크 안 함 → PASS (스킵)r   rn   r   r   r   rZ   r\   r]   r^   r_   Nr   r   s           r%   test_check_cycle_count_lv1_skipz3TestCheckCycleCount.test_check_cycle_count_lv1_skip[  sp    ""1%"63h)6)6))))6))))))6)))))))r'   c                 @   | j                  d      }t        |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}}y)uA   Lv.3 + 2사이클 (경계값) → PASS (expected_min=2, actual=2)rY   r   r   r   r   rZ   r\   r]   r^   r_   Nr   r   r   r   s           r%   )test_check_cycle_count_lv3_exact_boundaryz=TestCheckCycleCount.test_check_cycle_count_lv3_exact_boundaryb     ""1%"63h)6)6))))6))))))6)))))))n%**%****%***%**********h$1$1$$$$1$$$$$$1$$$$$$$r'   c                 @   | j                  d      }t        |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}}y)u5   Lv.3 + 1사이클 → FAIL (expected_min=2, actual=1)rn   r   r   r   r   rZ   r\   r]   r^   r_   Nr   rY   r   r   r   s           r%   'test_check_cycle_count_lv3_insufficientz;TestCheckCycleCount.test_check_cycle_count_lv3_insufficientk  r   r'   c                    | j                  d      }t        |d      }d}||v }|st        j                  d|fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }d	d
|iz  }t        t        j                  |            dx}}y)u3   결과에 message 키가 항상 포함되어야 함rn   rY   r   r   re   rg   rS   rh   ri   r
   N)
r   r   r   r   r   r   r   r   r   r   )rx   r   rS   rz   r   r   r    s          r%   )test_check_cycle_count_result_has_messagez=TestCheckCycleCount.test_check_cycle_count_result_has_messaget  sw    ""1%"63"yF""""yF"""y""""""F"""F"""""""r'   N)r   r   r   r   rT   r   r   r   r   r   r   r   r   r'   r%   r   r   >  s3    
3 
4 
+#*%%#r'   r   c                   @    e Zd ZdedefdZd Zd Zd Zd Z	d Z
d	 Zy
)TestCheckPersonaValidationrj   r   c                     d|ddddS )Nrn   r   r   rL   r   r   )rx   rj   s     r%   r   z'TestCheckPersonaValidation._make_parsed  s     
 	
r'   c                    | j                  ddg      }t        ||      }|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   }g }||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd	|iz  }t        t        j                  |            d
x}x}}|d   }	t        |	t              }
|
sddt        j                         v st        j                  t              rt        j                  t              ndt        j                  |	      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |
      dz  }t        t        j                  |            d
x}	}
|d   }	t        |	      }d}||k\  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |	      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d
x}	x}x}}y
)u=   등록된 페르소나만 → PASS, unregistered 비어있음   토르 (Thor)   로키 (Loki)r   r   rZ   r\   r]   r^   r_   Nunregistered
registeredrk   rR   rl   rm   rn   ro   rq   rr   rs   rt   ru   )r   check_persona_validationr   r   r   r   r   rR   rl   r   r   r   rr   )rx   r3   r   rS   rz   r#   r   ry   r{   r   r"   r    r|   r}   r$   r~   s                   r%   test_check_persona_registeredz8TestCheckPersonaValidation.test_check_persona_registered  s   ""O_#EF)&2BCh)6)6))))6))))))6)))))))n%++%++++%+++%++++++++++ .5z.55555555z555z555.5555555555555555555,'-s'(-A-(A----(A------s---s---'---(---A-------r'   c                    | j                  ddg      }t        ||      }|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   }	t        |	      }d}
||
k\  }|st        j                  d|fd||
f      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |	      t        j                  |      t        j                  |
      dz  }dd|iz  }t        t        j                  |            d
x}	x}x}}
g }	d}d}|j                  }|d   } ||      }||v }|}|sd |d   D        }t        |      }|}|sct        j                  d|fd||f      t        j                  |      t        j                  |      t        j                  |      t        j                  |      t        j                  |      dz  }dd|iz  }|	j                  |       |sddt        j                         v st        j                  t              rt        j                  t              ndt        j                        t        j                        dz  }|	j                  |       t        j                  |	d      i z  }dd|iz  }t        t        j                  |            d
x}x}	x}x}x}x}x}x}x}}y
) u&   미등록 페르소나 존재 → WARNu   엔키(백엔드)r   r   WARNrZ   r\   r]   r^   r_   Nr   rn   ro   rq   rr   rs   rt   ru      엔키 c              3   $   K   | ]  }d |v  
 yw)r   Nr   ).0us     r%   	<genexpr>zMTestCheckPersonaValidation.test_check_persona_unregistered.<locals>.<genexpr>  s     BqUV8q=Bq   re   )zM%(py3)s in %(py12)s
{%(py12)s = %(py8)s
{%(py8)s = %(py6)s.join
}(%(py10)s)
})r	   r_   py8py10py12%(py14)spy14z)%(py20)s
{%(py20)s = %(py16)s(%(py18)s)
}any)py16py18py20zassert %(py23)spy23)r   r   r   r   r   r   r   rr   r   r   r   joinr   append_format_boolop)rx   r3   r   rS   rz   r#   r   ry   r{   r   r|   r}   r$   r~   @py_assert7@py_assert9@py_assert11r"   @py_assert17@py_assert19@py_format13@py_format15@py_format21@py_format22@py_format24s                            r%   test_check_persona_unregisteredz:TestCheckPersonaValidation.test_check_persona_unregistered  s	   ""$7#IJ)&2BCh)6)6))))6))))))6))))))).)/s)*/a/*a////*a//////s///s///)///*///a///////qxq3q388qF>$:q8$:;qx;;qBqZ`aoZpBqqsBq?qq?qqqqx;qqqxqqq3qqq8qqq$:qqq;qqqqqqqqqqsqqqsqqqBqqqq?qqqqqqqqqqqqqqqr'   c                 @   | j                  ddg      }t        ||      }|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}||u }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd	|iz  }t        t        j                  |            d
x}x}}y
)u   로키 미참석 → FAILr   u   미미르 (Mimir)r   r   rZ   r\   r]   r^   r_   Nloki_presentFisz%(py1)s is %(py4)sr   r   r   r   r   r   r   	rx   r3   r   rS   rz   r#   r   ry   r{   s	            r%   test_check_persona_loki_missingz:TestCheckPersonaValidation.test_check_persona_loki_missing  s    ""O5H#IJ)&2BCh)6)6))))6))))))6)))))))n%..%....%...%..........r'   c                 @   | j                  ddg      }t        ||      }|d   }d}||u }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd	|iz  }t        t        j                  |            d
x}x}}y
)u#   로키 참석 → loki_present=Truer   r   r   Tr   r   r]   r^   r_   Nr   r   s	            r%   test_check_persona_loki_presentz:TestCheckPersonaValidation.test_check_persona_loki_present  sv    ""O_#EF)&2BCn%--%----%---%----------r'   c                    | j                  ddg      }t        ||      }dD ]  }||v }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      nddt	        j
                         v st        j                  |      rt        j                  |      nddz  }t        j                  d	|       d
z   d|iz  }t        t        j                  |            d} y)"   결과에 필수 키 포함 확인r   r   )r   r   r   r   re   r   r   rS   r   r   r   rW   N)r   r   r   r   r   r   r   r   r   r   r   )rx   r3   r   rS   r   r   r   ry   s           r%   +test_check_persona_result_has_required_keyszFTestCheckPersonaValidation.test_check_persona_result_has_required_keys  s    ""O_#EF)&2BCK 	>C&====3&======3===3======&===&====$7u"=======	>r'   c                    t        t              }t        |t              }|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
}||u }|slt	        j
                  d|fd||f      t	        j                  |      t	        j                  |      dz  }dd|iz  }t        t	        j                  |            dx}x}}|d   }t        |      }d}	||	k\  }
|
st	        j
                  d|
fd||	f      dt        j                         v st	        j                  t              rt	        j                  t              ndt	        j                  |      t	        j                  |      t	        j                  |	      dz  }dd|iz  }t        t	        j                  |            dx}x}x}
}	y)uH   실제 미팅 파일: 로키 미참석 + 미등록 페르소나 → FAILr   r   rZ   r\   r]   r^   r_   Nr   Fr   r   r   rn   ro   rq   rr   rs   rt   ru   )rv   rw   r   DEFAULT_PERSONA_LISTr   r   r   r   r   rr   r   r   r   )rx   r   rS   rz   r#   r   ry   r{   r   r|   r}   r$   r~   s                r%   $test_check_persona_real_meeting_filez?TestCheckPersonaValidation.test_check_persona_real_meeting_file  sF   #$56)&2FGh)6)6))))6))))))6)))))))n%..%....%...%...........)/s)*/a/*a////*a//////s///s///)///*///a///////r'   N)r   r   r   rl   rT   r   r   r   r   r   r   r   r   r'   r%   r   r     s4    
T 
d 
.r/.>0r'   r   c                   B    e Zd Zd Zd Zd Zd Zd Zd Zd Z	d Z
d	 Zy
)TestCheckDAc                 4   t        |      }t        |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}}y
)u   Lv.3 + DA 존재 → PASSr   r   r   r   rZ   r\   r]   r^   r_   Nda_sections_foundrn   ro   z%(py1)s >= %(py4)srv   check_dar   r   r   r   r   	rx   r;   r   rS   rz   r#   r   ry   r{   s	            r%   test_check_da_required_presentz*TestCheckDA.test_check_da_required_present  s    #J/&*h)6)6))))6))))))6))))))))*/a/*a////*a///*///a///////r'   c                 4   t        |      }t        |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}}y
)u   Lv.3 + DA 미존재 → FAILr   r   r   r   rZ   r\   r]   r^   r_   Nr   r   r   	rx   r>   r   rS   rz   r#   r   ry   r{   s	            r%   test_check_da_required_missingz*TestCheckDA.test_check_da_required_missing  s    #M2&*h)6)6))))6))))))6))))))))*/a/*a////*a///*///a///////r'   c                 4   t        |      }t        |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}}y
)u(   Lv.2 + DA 미존재 → PASS (선택적)rY   r   r   r   rZ   r\   r]   r^   r_   Nr   r   s	            r%   test_check_da_optional_lv2z&TestCheckDA.test_check_da_optional_lv2  j    #M2&*h)6)6))))6))))))6)))))))r'   c                 4   t        |      }t        |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}}y
)u(   Lv.1 + DA 미존재 → PASS (선택적)rn   r   r   r   rZ   r\   r]   r^   r_   Nr   r   s	            r%   test_check_da_optional_lv1z&TestCheckDA.test_check_da_optional_lv1  r  r'   c                 2   t        |      }t        |d      }|d   }d}||u }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd	|iz  }t        t        j                  |            d
x}x}}y
)u=   DA 3대 질문 (실패/후회/단순한 대안) 존재 확인r   r   three_questionsTr   r   r]   r^   r_   Nr   r   s	            r%   test_check_da_three_questionsz)TestCheckDA.test_check_da_three_questions  sk    #J/&*'(0D0(D0000(D000(000D0000000r'   c                 2   t        |      }t        |d      }|d   }d}||u }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd	|iz  }t        t        j                  |            d
x}x}}y
)u   반박 존재 확인r   r   rebuttal_foundTr   r   r]   r^   r_   Nr   r   s	            r%   test_check_da_rebuttal_foundz(TestCheckDA.test_check_da_rebuttal_found  sk    #J/&*&'/4/'4////'4///'///4///////r'   c                 2   t        |      }t        |d      }|d   }d}||u }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd	|iz  }t        t        j                  |            d
x}x}}y
)u   판정 존재 확인r   r   verdict_foundTr   r   r]   r^   r_   Nr   r   s	            r%   test_check_da_verdict_foundz'TestCheckDA.test_check_da_verdict_found  sj    #J/&*o&.$.&$....&$...&...$.......r'   c                    t        |      }t        |d      }dD ]  }||v }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      nddt	        j
                         v st        j                  |      rt        j                  |      nddz  }t        j                  d	|       d
z   d|iz  }t        t        j                  |            d} y)r   r   r   )r   r   r  r  r  re   r   r   rS   r   r   r   rW   N)rv   r   r   r   r   r   r   r   r   r   r   )rx   r;   r   rS   r   r   r   ry   s           r%   &test_check_da_result_has_required_keysz2TestCheckDA.test_check_da_result_has_required_keys  s    #J/&*h 	>C&====3&======3===3======&===&====$7u"=======	>r'   c                 6   t        t              }t        |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}||u }|slt        j                  d|fd||f      t        j
                  |      t        j
                  |      dz  }dd	|iz  }t        t        j                  |            d
x}x}}|d   }d}||u }|slt        j                  d|fd||f      t        j
                  |      t        j
                  |      dz  }dd	|iz  }t        t        j                  |            d
x}x}}|d   }d}||u }|slt        j                  d|fd||f      t        j
                  |      t        j
                  |      dz  }dd	|iz  }t        t        j                  |            d
x}x}}y
)uO   실제 미팅 파일: DA 섹션 존재 + 3대 질문 + 반박 + 판정 → PASSr   r   r   r   rZ   r\   r]   r^   r_   Nr   rn   ro   r   r  Tr   r   r  r  )rv   rw   r   r   r   r   r   r   r   s           r%   test_check_da_real_meeting_filez+TestCheckDA.test_check_da_real_meeting_file  s   #$56&*h)6)6))))6))))))6))))))))*/a/*a////*a///*///a///////'(0D0(D0000(D000(000D0000000&'/4/'4////'4///'///4///////o&.$.&$....&$...&...$.......r'   N)r   r   r   r   r   r   r  r  r	  r  r  r  r   r'   r%   r   r     s/    00**10/>	/r'   r   c                   6    e Zd Zd Zd Zd Zd Zd Zd Zd Z	y)	TestCheckThreeDocsc                 .   t        |      }t        |      }|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
}||u }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}y)u8   '3문서 반영' 또는 관련 키워드 언급 → PASSr   r   rZ   r\   r]   r^   r_   N	mentionedTr   r   rv   check_three_docsr   r   r   r   r   	rx   rG   r   rS   rz   r#   r   ry   r{   s	            r%   test_check_three_docs_mentionedz2TestCheckThreeDocs.test_check_three_docs_mentioned  s    #$67!&)h)6)6))))6))))))6)))))))k"*d*"d****"d***"***d*******r'   c                 .   t        |      }t        |      }|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
}||u }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}y)u   3문서 미언급 → WARNr   r   rZ   r\   r]   r^   r_   Nr  Fr   r   r  )	rx   rJ   r   rS   rz   r#   r   ry   r{   s	            r%   #test_check_three_docs_not_mentionedz6TestCheckThreeDocs.test_check_three_docs_not_mentioned  s    #$9:!&)h)6)6))))6))))))6)))))))k"+e+"e++++"e+++"+++e+++++++r'   c                 6   t        |      }d}t        ||      }|d   }d}||u }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd	|iz  }	t        t        j                  |	            d
x}x}}y
)u4   task-id 제공 + 경로 없음 → files_exist=FalsezNONEXISTENT-TASK-99999task_idfiles_existFr   r   r]   r^   r_   Nr  )
rx   rG   r   fake_task_idrS   rz   r#   r   ry   r{   s
             r%   )test_check_three_docs_with_task_id_no_dirz<TestCheckThreeDocs.test_check_three_docs_with_task_id_no_dir!  sr    #$67/!&,? m$--$----$---$----------r'   c                    d}|dz  |z  }|j                  d       |dz  j                  d       |dz  j                  d       |d	z  j                  d
       t        |      }t        ||      }|d   }d}||u}	|	slt	        j
                  d|	fd||f      t	        j                  |      t	        j                  |      dz  }
dd|
iz  }t        t	        j                  |            dx}x}	}y)uH   task-id 제공 + 경로 존재 → files_exist=True 또는 확인 가능zTEST-TASK-0013docsT)parentszplan.mdu	   계획서z
context.mdu   맥락노트zchecklist.mdu   체크리스트r  r  Nr   )z%(py1)s is not %(py4)sr]   r^   r_   )	mkdirr.   rv   r  r   r   r   r   r   )rx   rG   r1   r  docs_dirr   rS   rz   r#   r   ry   r{   s               r%   /test_check_three_docs_with_task_id_existing_dirzBTestCheckThreeDocs.test_check_three_docs_with_task_id_existing_dir*  s     "g%/t$	I	))+6	L	 ,,^<	N	"../@A#$67 "&':m$0D0$D0000$D000$000D0000000r'   c                    t        |      }t        |      }dD ]  }||v }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      nddt	        j
                         v st        j                  |      rt        j                  |      nddz  }t        j                  d|       dz   d	|iz  }t        t        j                  |            d
} y
)r   )r   r  r  re   r   r   rS   r   r   r   rW   N)rv   r  r   r   r   r   r   r   r   r   r   )rx   rG   r   rS   r   r   r   ry   s           r%   .test_check_three_docs_result_has_required_keyszATestCheckThreeDocs.test_check_three_docs_result_has_required_keys?  s    #$67!&)9 	>C&====3&======3===3======&===&====$7u"=======	>r'   c                 2   t        |      }t        |d      }|d   }d}||u }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}y)	u"   task-id 없으면 files_exist=NoneNr  r  r   r   r]   r^   r_   r  r  s	            r%   1test_check_three_docs_no_task_id_files_exist_nonezDTestCheckThreeDocs.test_check_three_docs_no_task_id_files_exist_noneG  sk    #$67!&$7m$,,$,,,,$,,,$,,,,,,,,,,r'   c                 6   t        t              }t        |      }|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
}||u }|slt        j                  d|fd||f      t        j
                  |      t        j
                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}y)u;   실제 미팅 파일: 3문서 반영 언급 없음 → WARNr   r   rZ   r\   r]   r^   r_   Nr  Fr   r   )rv   rw   r  r   r   r   r   r   r   s           r%   'test_check_three_docs_real_meeting_filez:TestCheckThreeDocs.test_check_three_docs_real_meeting_fileN  s    #$56!&)h)6)6))))6))))))6)))))))k"+e+"e++++"e+++"+++e+++++++r'   N)
r   r   r   r  r  r   r&  r(  r*  r,  r   r'   r%   r  r    s%    +,.1*>-,r'   r  c                   $    e Zd Zd Zd Zd Zd Zy)TestRunAuditFullc                 :   t        |d      }t        |t              }|sd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dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dz  }t        t        j                  |            d}d	D ]  }||v }|st        j                  d
|fd||f      dt        j                         v st        j                  |      rt        j                  |      nddt        j                         v st        j                  |      rt        j                  |      nddz  }t        j                  d|       dz   d|iz  }t        t        j                  |            d} y)uE   전체 감사 실행 결과가 올바른 JSON 구조를 가져야 함r   r   rQ   rR   rS   rT   rU   Ncycle_countpersona_validationda_check
three_docsre   r   r   r   u   감사 결과에 키 누락: r   rW   )	run_auditrR   rT   r   r   r   r   r   r   r   r   r   )rx   r8   rS   r#   ry   r   r   r   s           r%   "test_run_audit_full_json_structurez3TestRunAuditFull.test_run_audit_full_json_structure]  s!   ?!4&$''''''''z'''z''''''&'''&''''''$'''$''''''''''R 	HC&=GGG3&GGGGGG3GGG3GGGGGG&GGG&GGGG$A#"GGGGGGG	Hr'   c                    t        |d      }dD ]>  }d}||   }||v }|st        j                  d|fd||f      t        j                  |      t        j                  |      dz  }t        j                  | d      d	z   d
|iz  }t        t        j                  |            dx}x}}||   d   }d}||v }|st        j                  d|fd||f      t        j                  |      t        j                  |      dz  }t        j                  | d||   d          d	z   d
|iz  }t        t        j                  |            dx}x}}A y)u)   각 섹션에 status 키가 있어야 함rY   r   r0  r   re   z%(py1)s in %(py4)sr]   u   에 status 누락
>assert %(py6)sr_   Nr   r   r   u    .status가 유효하지 않음: )r5  r   r   r   r   r   r   )	rx   r8   rS   sectionrz   r#   r   ry   r{   s	            r%   &test_run_audit_each_section_has_statusz7TestRunAuditFull.test_run_audit_each_section_has_statuse  sX   ?!4V 	WGMvgM8.MMM8MMM8MMMMMM7);L0MMMMMMMM'?8, W 1 W, 1  W FWEV	W, 1 W W NWY	 - W W NWY	1 W W FWEV':6'?8;T:UV	W W W DWCV	W W W	Wr'   c                 `   t        |dd      }t        |t              }|sd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dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dz  }t        t        j                  |            d	}y	)
uA   task_id 파라미터 전달 시 에러 없이 실행되어야 함rY   zTASK-TEST-001)r   r  rQ   rR   rS   rT   rU   N)
r5  rR   rT   r   r   r   r   r   r   r   )rx   r8   rS   r#   ry   s        r%   test_run_audit_with_task_idz,TestRunAuditFull.test_run_audit_with_task_idq  s    ?!_M&$''''''''z'''z''''''&'''&''''''$'''$''''''''''r'   c                 l   t        |d      }t        j                  |d      }t        |      }d}||kD  }|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}}y)u)   결과가 JSON 직렬화 가능해야 함rY   r   Fensure_asciir   >z/%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} > %(py6)srr   json_strr   rV   r	   r_   assert %(py8)sr   N)r5  jsondumpsrr   r   r   r   r   r   r   r   r   )	rx   r8   rS   rE  r   r}   r"   r{   @py_format9s	            r%   #test_run_audit_serializable_to_jsonz4TestRunAuditFull.test_run_audit_serializable_to_jsonv  s    ?!4::f598} q }q    }q      s   s      8   8   }   q       r'   N)r   r   r   r6  r<  r>  rK  r   r'   r%   r.  r.  \  s    H
W(
!r'   r.  c                       e Zd Zd Zd Zy)TestEmptyMeetingFilec           	         	 t        |      }|Fg }|j                  }d}d} |||      }d}||k(  }	|	}
|	s|j                  }d} ||      }d}||u }|}
|
st        j                  d|	fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      t        j                  |      t        j                  |      dz  }dd	|iz  }|j                  |       |	st        j                  d
fdf      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                        t        j                        t        j                  |      t        j                  |      dz  }dd|iz  }|j                  |       t        j                  |d      i z  }dd|iz  }t        t        j                  |            dx}
x}x}x}x}x}x}	x}x}x}x}x}}yy# t        t        t        f$ r Y yw xY w)u2   빈 파일 → 적절한 에러 또는 전체 FAILNrX   r   rZ   )zU%(py10)s
{%(py10)s = %(py4)s
{%(py4)s = %(py2)s.get
}(%(py6)s, %(py8)s)
} == %(py13)srS   )r   rW   r_   r   r   py13z%(py15)spy15r   )zP%(py23)s
{%(py23)s = %(py19)s
{%(py19)s = %(py17)s.get
}(%(py21)s)
} is %(py26)s)py17py19py21r   py26%(py28)spy28rn   zassert %(py31)spy31)rv   getr   r   r   r   r   r   r   r   r   r   
ValueErrorKeyErrorAttributeError)rx   rM   rS   r   r#   r}   r   r   @py_assert12r   rz   @py_assert18@py_assert20@py_assert22@py_assert25@py_assert24@py_format14@py_format16@py_format27@py_format29@py_format30@py_format32s                         r%   test_empty_meeting_filez,TestEmptyMeetingFile.test_empty_meeting_file  s   	'6F !_vzz_._!_z.!4__49_VZZ__Z=W_[__=W[_=_____4______v___v___z___.___!___4__________=W[_______V___V___Z______=W___[_________________ "Hn5 		s   II I.-I.c                 t   	 t        |d      }|t        |t              r|j                         D cg c])  }t        |t              sd|v s|j	                  d      + }}d |D        }t        |      }|sddt        j                         v st        j                  t
              rt        j                  t
              ndt        j                  |      t        j                  |      dz  }t        t        j                  |            dx}}yyyc c}w # t        t        t        t         f$ r Y yw xY w)	u5   빈 파일로 run_audit 실행 시 FAIL 또는 예외rY   r   Nr   c              3   $   K   | ]  }|d v  
 yw))r   r   Nr   )r   ss     r%   r   zDTestEmptyMeetingFile.test_empty_meeting_run_audit.<locals>.<genexpr>  s     CQ1 00Cr   z,assert %(py4)s
{%(py4)s = %(py0)s(%(py2)s)
}r   )r   r   rW   )r5  rR   rT   valuesrX  r   r   r   r   r   r   r   r   rY  rZ  r[  FileNotFoundError)rx   rM   rS   vstatusesr   r#   ry   s           r%   test_empty_meeting_run_auditz1TestEmptyMeetingFile.test_empty_meeting_run_audit  s    	}A6F!j&>5;]]_n
STVZH[`hlm`mAEE(OnnC(CCsCCCCCCCCCsCCCsCCCCCCCCCCCCCC '?!n Hn6GH 		s/   2D D
DD"B1D D D76D7N)r   r   r   rh  rp  r   r'   r%   rM  rM    s    	
r'   rM  c                       e Zd Zd Zd Zy)TestNonexistentFilec           
         d}	 t        |      }g }d}||u }|}|s g }t        |t              }|}	|rd}
|
|v }|}	|	}|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  }|j                  |       |sd
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dt        j                         v st        j                  t              rt        j                  t              ndt        j                        dz  }j                  |       |rt        j                  dfd
|f      t        j                  |
      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }|j                  |       t        j                  |d      i z  }dd|iz  }|j                  |       t        j                  |d      i z  }dd|iz  }t        t        j                  |            dx}x}x}x}x}	x}x}x}
}y# t        $ r Y yt        $ r}g }d}t        |      }|j                   }	 |	       }||v }|}|s,d}t        |      }|j                   } |       }||v }|}|sd}|}|st        j                  d|fd||f      t        j                  |      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                  |	      t        j                  |      dz  }d d!|iz  } |j                  |        |s>t        j                  dfd"f      t        j                  |      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                        t        j                  |      d#z  }d$d|iz  }|j                  |       |s+d%d&t        j                        iz  }!|j                  |!       t        j                  |d      i z  }"d'd(|"iz  }#t        t        j                  |#            dx}x}x}x}x}x}	x}x}x}x}x}x}}Y d}~yd}~ww xY w))uJ   존재하지 않는 파일 파싱 → FileNotFoundError 또는 에러 dict(/home/jay/workspace/nonexistent-12345.mdNerrorr   z%(py2)s is %(py5)srS   r   r
   %(py7)sr   3%(py15)s
{%(py15)s = %(py11)s(%(py12)s, %(py13)s)
}rR   rT   py11r   rO  rP  re   z%(py18)s in %(py20)sr   r   %(py22)spy22r   %(py25)spy25rn   assert %(py28)srV  z	not foundzno such fileT)zf%(py3)s in %(py12)s
{%(py12)s = %(py10)s
{%(py10)s = %(py8)s
{%(py8)s = %(py5)s(%(py6)s)
}.lower
}()
}r0   e)r	   r
   r_   r   r   r   r   r   )zk%(py17)s in %(py26)s
{%(py26)s = %(py24)s
{%(py24)s = %(py22)s
{%(py22)s = %(py19)s(%(py20)s)
}.lower
}()
})rQ  rR  r   r  py24rT  rU  z%(py31)srW  zassert %(py34)spy34)rv   rR   rT   r   r   r   r   r   r   r   r   r   r   rm  	Exceptionr0   lower)$rx   	fake_pathrS   r   r"   r#   rz   @py_assert10@py_assert14r   r   r   r    r$   rc  r   @py_format23r   @py_format26rd  re  r  r   r   r   @py_assert16@py_assert21@py_assert23r`  r]  @py_assert30r   r   rg  @py_format33@py_format35s$                                       r%   test_nonexistent_file_parsez/TestNonexistentFile.test_nonexistent_file_parse  s5   >		]'	2FUTU6T>Uj&>U&>U&>7U7fCTUUUU6TUUUUUU6UUU6UUUTUUUUUUUUUUjUUUjUUUUUUUUUUUUUUUUUUUUU&>UUUU&>UUU7fUUU7UUUUUUfUUUfUUUUUUUUUUUUUUUUUUUUU  	 	]\;\#a&\&,,\,.\;.0\N\c!f\fll\ln\Nn4T\X\\X\\\\;.\\\;\\\\\\#\\\#\\\\\\a\\\a\\\&\\\,\\\.\\\\\\\Nn\\\N\\\\\\c\\\c\\\\\\!\\\!\\\f\\\l\\\n\\\\\\\X\\\\\\\\\\\\\\\\	]s   KK 	W<&	W</LW77W<c                    d}	 t        |d      }g }d}||u }|}|s g }t        |t              }|}	|rd}
|
|v }|}	|	}|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  }|j                  |       |sd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dt        j                         v st        j                  t              rt        j                  t              ndt        j                        dz  }j                  |       |rt        j                  dfd
|f      t        j                  |
      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }|j                  |       t        j                  |d      i z  }dd|iz  }|j                  |       t        j                  |d      i z  }dd|iz  }t        t        j                  |            dx}x}x}x}x}	x}x}x}
}y# t        $ r Y yt        $ r Y yw xY w)uP   존재하지 않는 파일로 run_audit → FileNotFoundError 또는 에러 dictrt  rY   r   Nru  r   rv  rS   rw  rx  r   ry  rR   rT   rz  re   r|  r}  r~  r  r   r  r  rn   r  rV  )r5  rR   rT   r   r   r   r   r   r   r   r   r   r   rm  r  )rx   r  rS   r   r"   r#   rz   r  r  r   r   r   r    r$   rc  r   r  r   r  rd  re  s                        r%   test_nonexistent_file_run_auditz3TestNonexistentFile.test_nonexistent_file_run_audit  s   >		y2FUTU6T>Uj&>U&>U&>7U7fCTUUUU6TUUUUUU6UUU6UUUTUUUUUUUUUUjUUUjUUUUUUUUUUUUUUUUUUUUU&>UUUU&>UUU7fUUU7UUUUUUfUUUfUUUUUUUUUUUUUUUUUUUUU  	 		s   KK 	K3(K32K3N)r   r   r   r  r  r   r'   r%   rr  rr    s    ]r'   rr  c                   z   e Zd Zej                  j                  ej                  j                  e	       d      d        Z
ej                  j                  ej                  j                  e	       d      d        Zej                  j                  ej                  j                  e	       d      d        Zy)TestRunAuditRealFileu2   실제 미팅 파일이 존재하지 않습니다.r(   c                 8   t        t        d      }t        |t              }|sd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dt	        j
                         v st        j                  t              rt        j                  t              ndt        j                  |      dz  }t        t        j                  |            d}|d	   }|d
   }d}||k(  }|st        j                  d|fd||f      t        j                  |      t        j                  |      dz  }t        j                  d|d
          dz   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
   }d}||k(  }|st        j                  d|fd||f      t        j                  |      t        j                  |      dz  }t        j                  d|d
          dz   d|iz  }t        t        j                  |            dx}x}}|d   }d}||u }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}|d   }	t        |	      }d}
||
k\  }|st        j                  d|fd ||
f      d!t	        j
                         v st        j                  t              rt        j                  t              nd!t        j                  |	      t        j                  |      t        j                  |
      d"z  }d#d$|iz  }t        t        j                  |            dx}	x}x}}
|d%   }|d
   }d&}||k(  }|st        j                  d|fd||f      t        j                  |      t        j                  |      dz  }t        j                  d'|d
          dz   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+}||u }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}|d,   }d+}||u }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}|d-   }d+}||u }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}|d.   }|d
   }d/}||k(  }|st        j                  d|fd||f      t        j                  |      t        j                  |      dz  }t        j                  d0|d
          dz   d|iz  }t        t        j                  |            dx}x}}|d1   }d}||u }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}y)2uX  
        실제 미팅 파일 + --level 4 기준 검증:
        - cycle_count: FAIL (actual=2, expected_min=3)
        - persona_validation: FAIL (로키 미참석 + 미등록 페르소나 존재)
        - da_check: PASS (DA 섹션, 3대 질문, 반박, 판정 모두 존재)
        - three_docs: WARN (3문서 반영 언급 없음)
        r   r   rQ   rR   rS   rT   rU   Nr1  r   r   rZ   r\   r]   z cycle_count should be FAIL, got r9  r_   r   rY   r^   r   r   r2  z'persona_validation should be FAIL, got r   Fr   r   r   rn   ro   rq   rr   rs   rt   ru   r3  r   zda_check should be PASS, got r   r   r  Tr  r  r4  r   zthree_docs should be WARN, got r  )r5  rw   rR   rT   r   r   r   r   r   r   r   r   r   rr   )rx   rS   r#   ry   ccrz   r   r{   pvr   r|   r}   r$   r~   datds                   r%   test_run_audit_real_filez-TestRunAuditRealFile.test_run_audit_real_file  su    ,A6&$''''''''z'''z''''''&'''&''''''$'''$'''''''''' M"(|XvX|v%XXX|vXXX|XXXvXXX)I"X,'XXXXXXXX(| q |q    |q   |   q       .!&Q&!Q&&&&!Q&&&!&&&Q&&&&&&& ()(|_v_|v%___|v___|___v___)PQST\Q]P^'________.!*U*!U****!U***!***U*******n%+s%&+!+&!++++&!++++++s+++s+++%+++&+++!+++++++ J(|UvU|v%UUU|vUUU|UUUvUUU)Fr(|n'UUUUUUUU%&+!+&!++++&!+++&+++!+++++++#$,,$,,,,$,,,$,,,,,,,,,,"#+t+#t++++#t+++#+++t+++++++/"*d*"d****"d***"***d******* L!(|WvW|v%WWW|vWWW|WWWvWWW)HH'WWWWWWWW+'%'%''''%''''''%'''''''r'   c                 0   t        t        d      }|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}}y)uC   실제 미팅 파일 + Lv.2: cycle_count PASS (2사이클 >= min 1)rY   r   r1  r   r   rZ   r\   r]   r^   r_   Nr   )r5  rw   r   r   r   r   r   )rx   rS   r  rz   r#   r   ry   r{   s           r%   test_run_audit_real_file_lv2z1TestRunAuditRealFile.test_run_audit_real_file_lv2  s     ,A6M"(|%v%|v%%%%|v%%%|%%%v%%%%%%%(| q |q    |q   |   q       r'   c                    t        t        d      }t        j                  |d      }t	        |      }d}||kD  }|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   d   }	d}
|	|
v }|slt        j                  d|fd|	|
f      t        j                  |	      t        j                  |
      dz  }dd|iz  }t        t        j                  |            dx}	x}}
y)uE   실제 미팅 파일 감사 결과가 JSON 직렬화 가능해야 함r   r   Fr@  r   rB  rD  rr   rE  rF  rG  r   Nr1  r   r:  re   r8  r]   r^   r_   )r5  rw   rH  rI  rr   r   r   r   r   r   r   r   r   loads)rx   rS   rE  r   r}   r"   r{   rJ  restoredrz   r#   ry   s               r%   *test_run_audit_real_file_json_serializablez?TestRunAuditRealFile.test_run_audit_real_file_json_serializable  s    ,A6::f598} q }q    }q      s   s      8   8   }   q       ::h'&x0L4LL04LLLLL04LLLL0LLL4LLLLLLLLr'   N)r   r   r   pytestmarkskipifospathexistsrw   r  r  r  r   r'   r%   r  r    s    [[BGGNN+<==Fz{#( |#(J [[BGGNN+<==Fz{! |! [[BGGNN+<==Fz{M |Mr'   r  ):__doc__builtinsr   _pytest.assertion.rewrite	assertionrewriter   importlib.utilr   rH  r  r  _SCRIPTS_DIRr  r   r   r&   r   rv   r   r   r   r  r5  _MODULE_AVAILABLEr  r  r  
pytestmarkrw   r   r5   r:   r=   r@   rC   rF   rI   r/   fixturer3   r8   r;   r>   rA   rD   rG   rJ   rM   rO   r   r   r   r  r.  rM  rr  r  r   r'   r%   <module>r     s`  
     	 
 -ww||L*<=
')M&99%77,EE%%H$55''I [[$5 5>  A

 a \ 
 6 @ &	  	   6                  !! !!R:# :#D;0 ;0FE/ E/ZD, D,X! !L < D8M 8My  s   AG GG