
    u% j$                     R   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
m
Z
mZ ddlmZ ddlZej                  j!                  dd      Zee	j$                  vre	j$                  j'                  de       ddlmZ dZej.                  d	efd
       ZdedefdZd Zd Zd Zd Zd Zy)u1  task-2536 회귀: 유휴 base 명시 라벨 (회장 §결정 2026-05-10 fix D).

검증 5건:
1. _compute_team_idle_base — 가장 최근 completed end_time 기준 정확
2. get_teams_info — 유휴 dev sub_team에 idle_base 부착
3. _compute_team_idle_base — base 누락(completed 0건) 시 None graceful
4. _enrich_member_status — idle 멤버에 idle_base 부착
5. spec 박제 일관성 — traffic-light-spec.md §8 idle_base 규칙 박제

영역 격리: data_loader 시그널 병합 로직(task-2534) 절대 수정 안 함.
chat=6937032012 격리.
    N)datetime	timedelta)PathWORKSPACE_ROOTz/home/jay/workspace)
DataLoader
6937032012tmp_pathc                    | dz  }|j                          |dz  j                          ddddddd	d
ddddgdddddddddgdgdgidg idi}|dz  j                  t        j                  |d      d       |dz  j                  t        j                  dg i      d       |dz  j                  t        j                  i       d       |dz  d z  j                  t        j                  d!d"d#id"d#id$i      d       |dz  d%z  j                  t        j                  d&i i      d       |d'z  j                  t        j                  dg i      d       | S )(ug   org-structure + task-timers 최소 fixture.

    dev1-team / dev2-team 두 sub_team + members.json
    memoryevents	structureteamsdevelopment-officeu	   개발실	dev1-teamu
   개발1팀hermesu   헤르메스)idnamezdev1-m1u   팀원A)sub_team_idsub_team_nameleadmembers	dev2-teamu
   개발2팀odinu   오딘zdev2-m1u   팀원B)team_id	team_name	sub_teamscenters)columnsrowszorganization-structure.jsonFensure_asciiutf-8encodingztech-debt.jsonitemszci-status.jsonzmember-status.jsonr   statusidle)r   r   zbot-activity.jsonbotsz	todo.json)mkdir
write_textjsondumps)r	   r   orgs      @/home/jay/workspace/tests/dashboard/test_idle_base_label_2536.pyworkspace_with_orgr/      s     F
LLNh 	#7%0 0;1=/7(P3<i,P+Q	 0;1=/5x(H3<i,P+Q	&, O/
C6 ++77

3U+g 8 
 **4::wm+Dw*W**4::b>G*Lh--99

I8V*<xQWFXYZ[ :  h,,88

FB< 7 9  k%%djj'2&?'%RO    	workspacetasksc                 d    | dz  dz  j                  t        j                  d|id      d       y )Nr   ztask-timers.jsonr2   Fr    r"   r#   )r*   r+   r,   )r1   r2   s     r.   _write_tasksr4   V   s5    ..::

GU#%87 ; r0   c           	         t        j                         t        d      z
  j                         }t        j                         t        d      z
  j                         }t        j                         t        d      z
  j                         }t	        | dd|ddd|ddd|dd       t        |       }|j                          |j                  d      }d	}||u}|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}}|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   }
|
|k(  }|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   }|
|k  }d}||k  }|r|st        j                  d||fd|
||f      t        j                  |
      t        j                  |      t        j                  |      d z  }d!d"|iz  }t        t        j                  |            d	x}
x}x}x}}y	)#uX   3개 completed task 중 end_time이 가장 최근인 것이 base로 선택돼야 한다.x   hoursU   (   r   	completedr   r&   end_time)ztask-oldztask-midtask-newNis notz%(py0)s is not %(py3)sbasepy0py3assert %(py5)spy5task_idr>   ==z%(py1)s == %(py4)spy1py4assert %(py6)spy6ts)z%(py1)s == %(py3)snewestrM   rE   '   
idle_hours)   )<=rW   )z%(py1)s <= %(py5)sz%(py5)s <= %(py7)s)rM   rG   py7zassert %(py9)spy9)r   nowr   	isoformatr4   r   
reload_all_compute_team_idle_base
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanation)r/   oldermiddlerR   loaderrB   @py_assert2@py_assert1@py_format4@py_format6@py_assert0@py_assert3@py_format5@py_format7@py_assert4@py_assert6@py_format8@py_format10s                     r.   4test_compute_team_idle_base_returns_latest_completedru   _   s>   \\^ic22==?Ellnyr22==?Fllnyr22==?F '%! '%" '%"	
( *+F
))+6D4t4t44t	?(j(?j((((?j(((?(((j(((((((::::)l#)2#))r)#r)))))2#r)))2)))#)))r))))))))r0   c                 0   t        j                         t        d      z
  j                         }t	        | ddd|di       t        |       }|j                          |j                         }t        d |D        d      }d}||u}|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 |d   D        d      }	t        d |d   D        d      }
g }d}|	|u}|}|rd}|
|u}|}|sXt        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#                  |       |rt        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#                  |       t        j$                  |d      i z  }dd|iz  }t        t        j                   |            dx}x}x}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   }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(  }|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   }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),uV   dev sub_team이 유휴(running 0)일 때 sub_info["idle_base"]가 채워져야 한다.r9   r7   z	task-2470r   r;   r<   c              3   2   K   | ]  }|d    dk(  s|  yw)r   r   N ).0ts     r.   	<genexpr>zItest_get_teams_info_attaches_idle_base_to_idle_subteam.<locals>.<genexpr>   s     PQ1Y<;O+OqPs   Nr?   rA   
dev_officerC   rF   rG   c              3   J   K   | ]  }|j                  d       dk(  s|  yw)r   r   Ngetry   ms     r.   r{   zItest_get_teams_info_attaches_idle_base_to_idle_subteam.<locals>.<genexpr>   !     ]1}9MQ\9\Q]   ##r   c              3   J   K   | ]  }|j                  d       dk(  s|  yw)r   r   Nr~   r   s     r.   r{   zItest_get_teams_info_attaches_idle_base_to_idle_subteam.<locals>.<genexpr>   r   r   )z%(py2)s is not %(py5)ssub_dev1)py2rG   %(py7)srX   )z%(py9)s is not %(py12)ssub_dev2)rY   py12%(py14)spy14r   assert %(py17)spy17	idle_baseinz%(py1)s in %(py3)srS   z%(py1)s is not %(py4)srL   rO   rP   rH   rI   rK   is)z%(py1)s is %(py4)s)r   rZ   r   r[   r4   r   r\   get_teams_infonextr^   r_   r`   ra   rb   rc   rd   re   append_format_boolop)r/   end_tsrh   r   r|   ri   rj   rk   rl   r   r   rq   rn   rm   @py_assert11@py_assert10rs   @py_format13@py_format15@py_format16@py_format18ro   rp   s                          r.   6test_get_teams_info_attaches_idle_base_to_idle_subteamr      s|   llnyr22==?F&%"	

 *+F
!!#E P%PRVWJ!!:T!!!!:T!!!!!!:!!!:!!!T!!!!!!!]
9 5]_cdH]
9 5]_cdH848848D8HD$88888848888888888888848888888HD888888H888H888D88888888888888 ";("""";(""";""""""("""("""""""K ,, ,,,, ,,, ,,,,,,,,,,K +:{:+{::::+{:::+:::{::::::: ";("""";(""";""""""("""("""""""K (D( D(((( D((( (((D(((((((r0   c                 :   t        | i        t        |       }|j                          |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                  |      dz  }dd|iz  }t        t	        j                  |            dx}x}x}x}}|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                  |      dz  }dd|iz  }t        t	        j                  |            dx}x}x}x}}|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                  |      dz  }dd|iz  }t        t	        j                  |            dx}x}x}x}}|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                  |      dz  }dd|iz  }t        t	        j                  |            dx}x}x}x}}y)uU   completed task가 0건인 팀에 대해 None 반환 (signal 병합 깨지지 않음).r   Nr   )z]%(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s._compute_team_idle_base
}(%(py4)s)
} is %(py9)srh   )rD   r   rN   rP   rY   zassert %(py11)spy11znonexistent-team )r4   r   r\   r]   r^   r_   r`   ra   rb   rc   rd   re   )	r/   rh   rj   rn   @py_assert5@py_assert8@py_assert7rt   @py_format12s	            r.   :test_compute_team_idle_base_returns_none_when_no_completedr      s   #R(*+F
))>+>)+6>$>6$>>>>6$>>>>>>6>>>6>>>)>>>+>>>6>>>$>>>>>>>))E*<E)*<=EE=EEEE=EEEEEE6EEE6EEE)EEE*<EEE=EEEEEEEEEE))7$7)$/747/47777/477777767776777)777$777/77747777777))5"5)"-55-5555-55555565556555)555"555-55555555555r0   c                 X   t        j                         t        d      z
  j                         }t	        | ddd|di       t        |       }|j                          |j                         }|j                  di       }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   }	||	v }|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}	||	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   }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)uF   team에 running 0건 + member status=idle → member.idle_base 부착.   r7   z	task-prevr   r;   r<   r   r   r   r   rS   rF   rG   Nr   )z%(py1)s in %(py4)srL   rO   rP   r?   r   rH   rI   rK   )r   rZ   r   r[   r4   r   r\   _enrich_member_statusr   r^   r_   rc   r`   ra   rb   rd   re   )r/   r   rh   enrichedr   rm   ri   rk   rl   rn   ro   rp   s               r.   ;test_enrich_member_status_attaches_idle_base_to_idle_memberr      s   llnyr22==?F&%"	
	 *+F
++-Hll9b)G 8w8w8ww+'(++;+++++;++++;+++++++++++8[)55)5555)555)55555555558[))4CC4CCCC4CCC4CCCCCCCCCCr0   c                     t        d      } | j                         st        d      } | j                  } |       }|st        j                  d|        dz   dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }t        t        j                  |            dx}}| j                  d	      }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}}g }d}||v }	|	}|	s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                  |       |	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  }|j                  |       t        j                  |d      i z  }dd|iz  }t        t        j                  |            dx}x}x}x}	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}
}g }d"}||v }	|	}|	s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                  |       |	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  }|j                  |       t        j                  |d      i z  }dd|iz  }t        t        j                  |            dx}x}x}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        |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)*u   traffic-light-spec.md에 §8 유휴 base 명시 규칙이 박제되어야 한다.

    회장 §결정 2026-05-10 fix D 박제 검증 — spec과 코드가 분리되지 않도록.
    zP/home/jay/workspace/.worktrees/task-2536-dev2/memory/specs/traffic-light-spec.mdz6/home/jay/workspace/memory/specs/traffic-light-spec.mdu   spec 파일 누락: zC
>assert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}	spec_path)rD   r   rN   Nr"   r#   u   ## 8. 유휴 base 명시 규칙r   r   bodyrS   rF   rG   z	task-2536zsince task-2470 13:59z	85h since)z%(py3)s in %(py5)s)rE   rG   r   rX   )z%(py10)s in %(py12)s)py10r   r   r      r   r   ?gracefulr   u   signal 병합 로직 수정u   병합 Xzfix Dr   rI   )z%(py0)s == %(py3)sCHAT_IDrC   )r   existsr^   _format_assertmsgr`   ra   rb   rc   rd   re   	read_textr_   r   r   r   )r   rj   rn   ro   r   rm   ri   rk   rl   rq   @py_assert9r   rs   r   r   r   r   s                    r.   %test_spec_idle_base_section_is_pinnedr      sh   
 ghIQR	AAAA!5i[AAAAAAA9AAA9AAAAAAAAAAAA0D -4,4444,444,4444444444444444;$;$;$$A"A"d*AkAkT.AAAAA"dAAA"AAAAAAdAAAdAAAAAAAkTAAAkAAAAAATAAATAAAAAAAAAAAAAA-3-3$;-:-:-----3$---3------$---$-------:---:-----------------------F(F(D0FJFJ$4FFFFF(DFFF(FFFFFFDFFFDFFFFFFFJ$FFFJFFFFFF$FFF$FFFFFFFFFFFFFF7d?7d7dd""7l""""7l""""""7"""7"""l"""""""r0   ) __doc__builtinsr`   _pytest.assertion.rewrite	assertionrewriter^   r+   ossysr   r   pathlibr   pytestenvironr   _WORKSPACE_ROOTpathinsertdashboard.data_loaderr   r   fixturer/   dictr4   ru   r   r   r   r   rx   r0   r.   <module>r      s      	 
 (   **..!13HI#(("HHOOA' ,
 3 3 3lD   *L!)N	6D8#r0   