
     jj+                       d Z ddlmZ ddlZddlmc mZ ddl	Z	ddl
mZ ddlZ ee      j                         j                  j                  j                  Z ee      e	j$                  v r!e	j$                  j'                   ee             e	j$                  j)                  d ee             ddlmZmZmZmZmZmZmZ ddlmZmZm Z m!Z!m"Z" d Z#d Z$d	 Z%d
 Z&d Z'y)u  tests/regression/test_composite_v3_cross_cutting_2530.py

회귀 테스트 — task-2530 composite ③ 카테고리 dispatch 코드 정식 구현.

회장 §본질 (2026-05-10):
  composite 작업 3종 분류 중 ③ 카테고리(개발팀 물리봇 + 여러 팀 + 횡단조직 agent
  복합)가 미구현 상태였음. dispatch 코드를 정식 구현하여 cross-cutting agent를
  composite member로 합법적으로 받아들이고 페르소나를 합성한다.

회장 §명시 5 회귀 (정확히 5개):
  1. ① logical 1팀 회귀 — 기존 `--team marketing` 단일 경로 유지 (composite 미진입)
  2. ② logical 2~3팀 복합 회귀 — `--composite marketing,design` ②_logical_only 분류
  3. ③ logical + cross-cutting mix success — `--composite marketing,loki` → ③_mixed + 페르소나 합성
  4. ③ 잘못된 cross-cutting ID rejection — `--composite marketing,nonexistent` → ValueError
  5. ③ 페르소나 합성 검증 + trigger gate — prompt OFF/agent 라벨 + bot_status COMPOSITE_TRIGGER_KEYWORDS 동작
    )annotationsN)Path)COMPOSITE_ALL_ALLOWEDCOMPOSITE_ALLOWED_TEAMSCOMPOSITE_CROSS_CUTTING_AGENTSCOMPOSITE_TRIGGER_KEYWORDSCROSS_CUTTING_AGENT_LABELSHANDOFF_REQUIRED_FIELDSMAX_COMPOSITE_TEAMS)_build_composite_iii_prompt_build_persona_prompt_classify_composite_pattern_validate_composite_members_validate_composite_teamsc                 	   t        j                  t        d      5  t        d       ddd       d} | t        v }|st        j                  d|fd| t        f      t        j                  |       dt        j                         v st        j                  t              rt        j                  t              nddz  }d	d
|iz  }t        t        j                  |            dx} }d} | t        v }|st        j                  d|fd| t        f      t        j                  |       dt        j                         v st        j                  t              rt        j                  t              nddz  }d	d
|iz  }t        t        j                  |            dx} }d} | t        v }|st        j                  d|fd| t        f      t        j                  |       dt        j                         v st        j                  t              rt        j                  t              nddz  }d	d
|iz  }t        t        j                  |            dx} }d} | t        v }|st        j                  d|fd| t        f      t        j                  |       dt        j                         v st        j                  t              rt        j                  t              nddz  }d	d
|iz  }t        t        j                  |            dx} }t        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                  t              rt        j                  t              ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}d}t        |k(  }|st        j                  d|fdt        |f      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dz  }d	d
|iz  }t        t        j                  |            dx}}y# 1 sw Y   xY w)uh   ① logical 1팀: --team marketing 단일 위임 경로는 변경 없음 + composite 4팀 박제 유지.   2개 이상match	marketingNinz%(py1)s in %(py3)sr   py1py3assert %(py5)spy5design
consulting
publishing   ==z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)slenpy0r   r   py6assert %(py8)spy8   z%(py0)s == %(py3)sr   r'   r   )pytestraises
ValueErrorr   r   
@pytest_ar_call_reprcompare	_saferepr@py_builtinslocals_should_repr_global_nameAssertionError_format_explanationr%   r   )	@py_assert0@py_assert2@py_format4@py_format6@py_assert5@py_assert4@py_format7@py_format9@py_assert1s	            L/home/jay/workspace/tests/regression/test_composite_v3_cross_cutting_2530.py!test_legacy_single_team_unchangedrC   5   s    
z	7 1#K01 1;11111;1111;111111111111111111.8.....8....8..................2<22222<2222<2222222222222222222<22222<2222<222222222222222222&',1,'1,,,,'1,,,,,,3,,,3,,,,,,&,,,&,,,',,,1,,,,,,, #$#!####!############!#######1 1s   SS!c                 X	   t        d      } ddg}| |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}}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        d      }	g 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}}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                  t        d      5  t        d       d
d
d
       d}t        |      }
ddg}|
|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
# 1 sw Y   xY w)ue   ② logical 2~3팀 복합: marketing,design은 ②_logical_only로 분류되고 기존 동작 유지.zmarketing,designr   r   r"   r,   members2r-   r   r   Nu   ②_logical_onlyr$   r   r&   r)   r*   zmarketing,design,consulting)r   r   r   members3u   최대r   z&marketing,design,consulting,publishing)z0%(py4)s
{%(py4)s = %(py0)s(%(py2)s)
} == %(py7)sr   )r'   py2py4py7zassert %(py9)spy9)r   r1   r2   r4   r5   r6   r3   r7   r8   r   r.   r/   r0   r   )rE   r:   rA   r;   r<   r=   r>   r?   r@   rF   @py_assert3@py_assert6@py_format8@py_format10s                 rB   -test_logical_only_composite_pattern_unchangedrO   I   s    ++=>H#X..8.....8.......8...8...........&x0F4FF04FFFFF04FFFFFFF&FFF&FFFFFFxFFFxFFF0FFF4FFFFFFFF ++HIH<<8<<<<<8<<<<<<<8<<<8<<<<<<<<<<<&x0F4FF04FFFFF04FFFFFFF&FFF&FFFFFFxFFFxFFF0FFF4FFFFFFFF 
z	2 N#$LMN &8S$%78S[(<SS8<SSSSS8<SSSSSSS$SSS$SSS%7SSS8SSS<SSSSSSSS	N Ns   "R  R)c                    h d} t        |       }t        |k(  }|s/t        j                  d|fdt        |f      dt	        j
                         v st        j                  t              rt        j                  t              n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t        j                  |      dz  }dd	|iz  }t        t        j                  |            d
x}}t        d      }ddg}||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}}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        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}}| D ]  }t        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  }d!d"|iz  }t        t        j                  |            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}}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        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                  t              rt        j                  t              nd't        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            d
x}x}}y
)(ua   ③ logical + cross-cutting mix: marketing,loki → ③_mixed 분류 + 7개 cross-cutting 통과.>   lokimaatatlasjanusvenuschronos
prometheusr"   z0%(py0)s == %(py5)s
{%(py5)s = %(py2)s(%(py3)s)
}r   	frozensetexpected_agentsr'   rG   r   r   assert %(py7)srI   Nzmarketing,lokir   rQ   r,   membersr-   r   r   u	   ③_mixedr$   r   r&   r)   r*   z	maat,lokiu   ③_cross_cutting_onlycc_onlyz
marketing,r   )z%(py0)s in %(py2)sagent)r'   rG   zassert %(py4)srH   r   r      r%   r   )rY   r   r1   r2   r4   r5   r6   r3   r7   r8   r   r   r%   r   )rZ   r>   rA   r<   rM   r]   r:   r;   r=   r?   r@   r^   r_   @py_format3@py_format5r9   s                   rB   (test_mixed_logical_cross_cutting_successrc   `   s[    [O-6-GG)-GGGGG)-GGGGGGG)GGG)GGGGGGYGGGYGGGGGGGGGGGG-GGGGGGGG **:;G"F++7+++++7+++++++7+++7+++++++++++&w/>;>/;>>>>/;>>>>>>&>>>&>>>>>>w>>>w>>>/>>>;>>>>>>> *+6G&w/K3KK/3KKKKK/3KKKKKKK&KKK&KKKKKKwKKKwKKK/KKK3KKKKKKKK ! C-
5'.BCuuu%{g%%%%{g%%%{%%%%%%g%%%g%%%%%%%*73B{B3{BBBB3{BBBBBB*BBB*BBBBBB7BBB7BBB3BBB{BBBBBBB	C $%++%++++%++++++3+++3++++++$+++$+++%++++++++++    c                 R   t        j                  t        d      5  t        d       ddd       t        j                  t        d      5  t        d       ddd       t        j                  t        d      5  t        d       ddd       t        j                  t        d      5  t	        d       ddd       t        j                  t        d      5  t        d	       ddd       y# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   ]xY w# 1 sw Y   yxY w)
u[   ③ 잘못된 cross-cutting ID: marketing,nonexistent → ValueError + alias 동일 거부.u   알 수 없는 composite 멤버r   zmarketing,nonexistentNzmarketing,dev1-teamu   중복 멤버zmarketing,marketingr    )r.   r/   r0   r   r    rd   rB   test_invalid_member_rejectionrh   }   s    	z)J	K =#$;<= 
z)J	K ;#$9:; 
z	9 ;#$9:; 
z)J	K ;!"9:; 
z	7 (#B'( (!= =; ;; ;; ;( (s;   C-C9:D)DD-C69DDDD&c                6$    t        dgddg      }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}}t        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}}t        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}||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}}t        g ddg      }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}}g }d}||v }	|	}|	rd}
|
|v }|}|sXt        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                  |       |	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  }t        t        j                  |            dx}x}x}x}	x}
}t        dgdgdd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}}t        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}||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}||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}}t        d gdgd!d"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}}t        d&gdgd'd"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}}ddh}t        |      }|t        v }|st        j                  d|fd+|t        f      d,t	        j
                         v st        j                  t              rt        j                  t              nd,t        j                  |      t        j                  |      d-t	        j
                         v st        j                  t              rt        j                  t              nd-d.z  }d/d0|iz  }t        t        j                  |            dx}x}}d&dh}t        |      }|t        v }|st        j                  d|fd+|t        f      d,t	        j
                         v st        j                  t              rt        j                  t              nd,t        j                  |      t        j                  |      d-t	        j
                         v st        j                  t              rt        j                  t              nd-d.z  }d/d0|iz  }t        t        j                  |            dx}x}}d dh}t        |      }|t        v }|st        j                  d|fd+|t        f      d,t	        j
                         v st        j                  t              rt        j                  t              nd,t        j                  |      t        j                  |      d-t	        j
                         v st        j                  t              rt        j                  t              nd-d.z  }d/d0|iz  }t        t        j                  |            dx}x}}d1dh}t        |      }|t        v }|st        j                  d|fd+|t        f      d,t	        j
                         v st        j                  t              rt        j                  t              nd,t        j                  |      t        j                  |      d-t	        j
                         v st        j                  t              rt        j                  t              nd-d.z  }d/d0|iz  }t        t        j                  |            dx}x}}h d2}t        |      }	t        |	k(  }|s/t        j                  d3|fd4t        |	f      d5t	        j
                         v st        j                  t              rt        j                  t              nd5d,t	        j
                         v st        j                  t              rt        j                  t              nd,d6t	        j
                         v st        j                  |      rt        j                  |      nd6t        j                  |	      d7z  }d8d|iz  }t        t        j                  |            dx}}	| }|j!                  d9t#        |             dd:lm}  ||;      }d<gg d=d>gg d=d? |j)                  |d@ fdA       |j*                  }dB} ||      }d&}||k(  }|st        j                  d3|fdC||f      dDt	        j
                         v st        j                  |      rt        j                  |      ndDt        j                  |      t        j                  |      t        j                  |      t        j                  |      dEz  }dFdG|iz  }t        t        j                  |            dx}x}x}x}}|j*                  }dH} ||      }d}||u }|st        j                  dI|fdJ||f      dDt	        j
                         v st        j                  |      rt        j                  |      ndDt        j                  |      t        j                  |      t        j                  |      t        j                  |      dEz  }dFdG|iz  }t        t        j                  |            dx}x}x}x}}|j*                  }dK} ||      }dL}||k(  }|st        j                  d3|fdC||f      dDt	        j
                         v st        j                  |      rt        j                  |      ndDt        j                  |      t        j                  |      t        j                  |      t        j                  |      dEz  }dFdG|iz  }t        t        j                  |            dx}x}x}x}}y)MuT  ③ 페르소나 합성: prompt에 'dev 본인 페르소나 OFF' + 로키/마아트 라벨 포함.

    추가로 utils/bot_status.py:367 보강이 동작하는지 검증:
      - trigger 키워드 미포함 → composite 후보 진입 X (기존 동작)
      - trigger 키워드 포함 + composite 키워드 매칭 → 후보 진입 O
    r   rQ   rR   u   dev 본인 페르소나 OFFr   r   persona_mixedr   r   r   Npersona_cc_onlyu   로키u	   마아트)z%(py3)s in %(py5)s)r   r   z%(py7)srI   )z%(py10)s in %(py12)s)py10py12z%(py14)spy14r   zassert %(py17)spy17ztask-2530.persona-testu   redteam 검증 tasknormal)logical_memberscross_cutting_memberstask_id	task_desclevelfull_promptu   redteam 공격 시나리오r   ztask-2530.crittcriticalz
[CRITICAL]critical_promptr   ztask-2530.secsecurityz
[SECURITY]security_prompt)z0%(py4)s
{%(py4)s = %(py0)s(%(py2)s)
} in %(py6)srY   r
   )r'   rG   rH   r(   r)   r*   r    >      감사   검증   보안검토QCredteam   복합검증r"   rX   r   expected_triggersr[   r\   WORKSPACE_ROOT)BotStatusManager)workspace_rootu	   디자인)keywordsanti_keywordsr   )r   	composite_load_logical_teamsc                      S )Nrg   )fake_logical_teamss   rB   <lambda>z9test_persona_synthesis_and_trigger_gate.<locals>.<lambda>   s    <N rd   u   디자인 작업)zR%(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.suggest_team
}(%(py4)s)
} == %(py9)smgr)r'   rG   rH   r(   rJ   zassert %(py11)spy11u   일반 작업)is)zR%(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.suggest_team
}(%(py4)s)
} is %(py9)su   복합검증 작업r   )r   r1   r2   r3   r4   r5   r6   r7   r8   r	   append_format_boolopr   rY   r
   r   setenvstrutils.bot_statusr   setattrsuggest_team)!tmp_pathmonkeypatchrj   r9   r:   r;   r<   rk   rA   r>   @py_assert9@py_assert11rM   @py_format13@py_format15@py_format16@py_format18rv   ry   r{   rK   r=   r?   r@   r   fake_workspacer   r   @py_assert8@py_assert7rN   @py_format12r   s!                                   @rB   'test_persona_synthesis_and_trigger_gater      s
    *;-&&9IJM(9(M9999(M999(999999M999M9999999%f->->>>>->>>->>>>>>>>>>>>>>>>%f->->>>>->>>->>>>>>>>>>>>>>>>';-'''';-''';''''''-'''-''''''' ,B0@AO(;(O;;;;(O;;;(;;;;;;O;;;O;;;;;;;I8I8&I;I;/+IIIII8III8IIIIIIIIIIIIIIII;/III;IIIIII/III/IIIIIIIIIIIIII .$%h('K )7(K7777(K777(777777K777K7777777%f-<-<<<<-<<<-<<<<<<<<<<<<<<<<#2#{2222#{222#222222{222{2222222(7(K7777(K777(777777K777K7777777 2%%h O *<?****<?***<******?***?*******1!
%hO *<?****<?***<******?***?******* "6*F9*+F+/FFFFF+/FFFFFFF9FFF9FFF*FFF+FFFFFF/FFFF/FFFFFFFF'C9'(C(,CCCCC(,CCCCCCC9CCC9CCC'CCC(CCCCCC,CCCC,CCCCCCCC"F+G9+,G,0GGGGG,0GGGGGGG9GGG9GGG+GGG,GGGGGG0GGGG0GGGGGGGG"F+G9+,G,0GGGGG,0GGGGGGG9GGG9GGG+GGG,GGGGGG0GGGG0GGGGGGGG ^)23D)EE%)EEEEE%)EEEEEEE%EEE%EEEEEEEEEEEEEEE3DEEE3DEEE)EEEEEEEE N'^)<=1
.
9C !,}rB#1"2RH 24NO ;.;./;8;/8;;;;/8;;;;;;3;;;3;;;;;;.;;;/;;;8;;;;;;;4O4O,44,4444,44444434443444444O444,4444444444 A1A12AkA2kAAAA2kAAAAAA3AAA3AAAAAA1AAA2AAAkAAAAAAAArd   )(__doc__
__future__r   builtinsr4   _pytest.assertion.rewrite	assertionrewriter1   syspathlibr   r.   __file__resolveparent_WORKTREE_ROOTr   pathremoveinsertutils.composite_constantsr   r   r   r   r	   r
   r   dispatchr   r   r   r   r   rC   rO   rc   rh   r   rg   rd   rB   <module>r      s     #   
  
 h'')0077>>~#(("HHOOC'( 3~& '   $(T.,:(2QBrd   