
    4jXG                       d Z ddlmZ ddlZddlZddlZddlZddlmZm	Z	m
Z
 ej                  j                  ej                  j                  ej                  j                  e                  Zeej                  vrej                  j!                  de       ddZ edd       dZd	Zd
ZdZdZdZdZdZddZddZd dZddZd dZd dZd dZ ddZ!d dZ"d dZ#d!dZ$e%dk(  r e& e$ejN                  dd             y)"u  scripts/diag_team_lead_subagent_contract_2553plus56.py

task-2553+56 TRACK A — TEAM_LEAD_SUBAGENT_USAGE_CONTRACT_DIAGNOSIS.

READ-ONLY static diagnostic. Imports the REAL runtime modules and
introspects whether the team-lead / subagent external boundary
(result schema · evidence-vs-authoritative · proposed verdict ·
independent-ANU-only authoritative · subagent direct ANU guard ·
team-lead normal callback owner · expected/forbidden/regression/
unresolved recording · concealment WARN/HOLD) is enforced by
code/schema or only by free-text prompt guidance.

Zero side effects: no write, no cron, no dispatch, no subprocess,
no cokacdir. The function ``run_diagnosis()`` returns a structured
dict; ``main()`` prints it as JSON to stdout. Artifact files are
written by the orchestrating executor, never by this module — so the
script stays a pure read-only probe (회장 §3 정적 점검).

Verdict vocabulary per check:
  PASS    — boundary is enforced by code/schema (fail-closed).
  PARTIAL — enforced transitively (via self-chain / self-key guards)
            but no explicit subagent-scoped construct.
  GAP     — only free-text prompt guidance; no code/schema enforcement.
    )annotationsN)AnyDictListc                   ddl }| t        j                  v rt        j                  |    S |j                  j	                  | t
        j                  j                  t        |            }||j                  J |j                  j                  |      }|t        j                  | <   |j                  j                  |       |S )u  Hermetic file-path import — collision-proof vs the ``dispatch.py``
    shim that otherwise shadows the real ``dispatch/`` package under
    pytest (identical strategy to the +49 regression suites). Read-only:
    loads the genuine workspace module, no write.r   N)importlib.utilsysmodulesutilspec_from_file_locationospathjoin
_REPO_ROOTloadermodule_from_specexec_module)modnamerelpath	importlibspecmods        J/home/jay/workspace/scripts/diag_team_lead_subagent_contract_2553plus56.py_hermetic_loadr   *   s    
 #++{{7##>>11j'2D  777
..
)
)$
/CCKKKKC J    z dispatch.callback_owner_enforcerz#dispatch/callback_owner_enforcer.pyz#diag.team_lead_subagent_contract.v1ztask-2553+56APASSPARTIALGAP)subagents_usedsubagent_rolessubagent_outputs_summary)expected_filesforbidden_files
regressionunresolved_findingsc                 r    ddl m}   | dt        ddiddi i i i i d      }t        |j	                               S )z|Build a representative team-result packet from the REAL builder and
    return its top-level keys (read-only introspection).r   )build_final_packetz1970-01-01T00:00:00ZgoaldiagN)tstask_idgoal_contractderived_contractgate_decisionactivation_decisionactivation_resultcallback_contractadjudicationcodex_audit_resulthold_packet)anu_v3.goal_result_plannerr(   TASK_IDsortedkeys)r(   pkts     r   _packet_keysr;   [   sJ     >
!v&C #((*r   c                    t         D cg c]	  }|| v s| }}t         D cg c]	  }|| vs| }}|st        nt        }dd|||dddS c c}w c c}w )N   u]   team result에 subagents_used / subagent_roles / subagent_outputs_summary 필드가 있는가-anu_v3.goal_result_planner.build_final_packetu   16-field final packet has NO subagent-result fields; team prompt only carries a free-text '서브에이전트(Task tool) 결과 규칙' (≤500자 요약) — not a code/schema-enforced structured field set.)idquestionverdictpresent_fieldsmissing_fields
entrypointevidence)SUBAGENT_RESULT_FIELDSr   r   )r9   fpresentmissingrA   s        r   _check1_result_schemarJ   p   sj    0>QAIq>G>0BQATMqBGB!dsG; !!E  ?Bs   	A	A		AAc            
        ddl m} m}m}m}  |ddt
        ddddd	      } ||gt
        d
g      }|j                  dk(  xr1 |j                  dk(  xr  |j                  | k(  xr |j                  |k(  }|rt        nt        }dd||dddS )Nr   )AUTHORITATIVE_VERDICT_PENDINGFAILVerdictRecordselect_authoritative_verdictcollector_resultr   EXECANUTindependent_anu)kindrA   r,   executor_keycollector_keycollector_rolesession_is_executor_selfclaimed_originANUKEYr,   anu_keysr=      uD   subagent 산출은 evidence이고 authoritative verdict가 아닌가Banu_v3.authoritative_verdict_selector.select_authoritative_verdictzsubagent output flows through the team-lead executor self-session, so derived_origin -> self_chain -> QUARANTINED and never authoritative. Enforced transitively via the self-chain rule; there is NO explicit subagent evidence kind or 'evidence-only' tag.)r?   r@   rA   self_chain_quarantinedrD   rE   )%anu_v3.authoritative_verdict_selectorrL   rM   rN   rO   r7   quarantined_countindependent_anu_countclassificationrA   r   r   )rL   rM   rN   rO   recresquarantinedrA   s           r   "_check2_evidence_not_authoritativerg      s      !%(	C '	w(C 	" 	 %%*	 "??	  KK4	  %g#GZ"-P& r   c           	         ddl m}m}m}  |ddt        dddd      } ||gt        d	g
      }|j
                  |k(  xr |j                  d u }d| v }|rt        nt        }dd|||dddS )Nr   )rM   rN   rO   rP   r   LEADrR   TrT   rA   r,   rU   rV   rW   rX   rZ   r[   proposed_verdict   u+   team lead verdict는 proposed verdict인가r^   u  team-lead (executor self-session) verdict is structurally non-authoritative (self_chain). But there is NO explicit 'proposed_verdict' field in the team-result schema and no code that labels/records the team-lead verdict as 'proposed' — it is only implied by quarantine.)r?   r@   rA   functionally_non_authoritativeexplicit_proposed_verdict_fieldrD   rE   )	r`   rM   rN   rO   r7   rA   authoritative_verdictr   r   )	r9   rM   rN   rO   rd   re   functionally_non_authhas_proposed_fieldrA   s	            r   "_check3_team_lead_verdict_proposedrr      s      !%C '	w(C  KK4/UC4M4MQU4U+t3(dgGA*?+=P4 r   c            	     X   ddl m} m}m}m}  |ddt
        dddd      } |ddt
        dd	dd
      } ||gt
        d	g      } |||gt
        d	g      }|j                  d u xr1 |j                  | k(  xr  |j                  |k(  xr |j                  dk(  }dd|rt        nt        |dddS )Nr   )AUTHORITATIVE_PASSr   rN   rO   rP   r   rQ   rR   Trj   rZ   Fr[      u0   ANU independent collector만 authoritative인가r^   u   self-chain-only -> authoritative_verdict=None (FAIL/PENDING); adding an independent-ANU record promotes it to AUTHORITATIVE_PASS. derived_origin recomputes independence from owner identity (claimed_origin ignored) — fail-closed.)r?   r@   rA   code_enforcedrD   rE   )r`   rt   r   rN   rO   r7   ro   rc   rA   authoritative_source_kindr   )	rt   A_PASSrN   rO   self_recanu_rec	only_selfwith_anuenforceds	            r   _check4_anu_only_authoritativer~      s      !%H !&G -	
GxjI ,	7WzH 	''4/ 	E##'99	E&	E ..2DD	  F#4!PL r   c            	     @   ddl m} m}m} ddlm}m} ddlm}  |ddd      } |ddd	      } |t        dddd
dd      }d}		  ||       |j                   xr |j                   xr |	}
t        |      }d}|
rt        nt        }dd||
||dddS # | $ r d}	Y Ow xY w)Nr   CallbackRegistrationBlockedassert_registration_permittedvalidate_callback_owner_runtime)guard_self_collector_sessionguard_self_dispatch)BLOCKED_TOOLSri   rR   )rU   rV   rW   T)rU   	actor_keyis_followup_dispatchc1c2c0r,   rU   rV   rW   normal_collector_cron_idfallback_callback_cron_iddispatch_cron_idF   uW   subagent가 ANU로 직접 callback/dispatch/write하지 못하도록 guard가 있는가zanu_v3.callback_owner_validator.validate_callback_owner_runtime + anu_v3.self_collector_guard.guard_self_dispatch / utils.delegate_controller.BLOCKED_TOOLSaY  A subagent uses the team-lead/executor key channel, so a direct ANU callback/self-dispatch is fail-closed via the executor-self-key guards (transitive). delegate_controller blocks {delegate,clarify,memory,send_message} on the SDK delegate path only; there is NO explicit subagent-scoped guard for direct cokacdir/ANU write on the Task-tool path.)r?   r@   rA   /executor_self_key_guard_blocks_subagent_channel!delegate_controller_blocked_tools$explicit_subagent_scoped_write_guardrD   rE   )anu_v3.callback_owner_validatorr   r   r   anu_v3.self_collector_guardr   r   utils.delegate_controllerr   r7   okr8   r   r   )r   r   r   r   r   r   colldispvalblockedself_key_guardeddelegate_blockedexplicit_subagent_write_guardrA   s                 r   !_check5_subagent_direct_anu_guardr     s     
 8
 (6%D vDD *!%"&C G%c*
 GG/DGG/ 
 m,$)!)gsG! ;K-=0M6
I!  ' s   B BBc            	         ddl m} m}m}  |t        dddddd      }d	}	  ||        |t        dddddd      }|j
                  xr |j                  }|xr |}dd|rt        nt        ||dddS # | $ r d
}Y Rw xY w)Nr   r   c38fb9955616e24drR   r   r   r   r   FTc119085addb0f8b7   u.   팀장 normal callback은 ANU key로 가는가z=anu_v3.callback_owner_validator.assert_registration_permittedu   executor self-key collector -> CallbackRegistrationBlocked (fail-closed, +49 코드 정본). Independent ANU-key collector -> registration allowed. Team-lead normal callback owner = ANU key is code-enforced.)r?   r@   rA   self_key_registration_blockedanu_key_registration_allowedrD   rE   )	r   r   r   r   r7   r   registration_allowedr   r   )r   r   r   self_valself_blockedanu_valanu_okr}   s           r   $_check6_team_lead_callback_owner_anur   ]  s      /'(!%"&H L%h/ .'(!%"&G ZZ8G88F&HD#4)5(.K(  ' s   A2 2A<;A<c                    t         D cg c]	  }|| v s| }}d| v xs d| v }t         D cg c]  }|| vr	|dk(  r|s| }}|st        nt        }dd|||rdgng z   |dddS c c}w c c}w )Nregression_resultr%      ue   expected_files / forbidden_files / regression / unresolved findings가 team result에 기록되는가r>   zOnly 'regression_result' exists in the 16-field packet. expected_files / forbidden_files / unresolved_findings are NOT recorded in the team-result schema by code.)r?   r@   rA   rH   rI   rD   rE   )BOUNDARY_RECORD_FIELDSr   r   )r9   rG   rH   has_regressionrI   rA   s         r   _check7_boundary_record_fieldsr     s    0>QAIq>G>(D0HLD4HN (D=!|"3 	
G 
 "dsG9 ~232NE>  ?s   	A!A!A&c                     ddl m}  ddlm} t	        j
                  |       t	        j
                  |      z   d}t        fd|D              }|rt        nt        }dd||dd	d
S )Nr   )authoritative_verdict_selector)callback_owner_enforcer)SUBAGENT_RESULT_CONCEALEDsubagent_concealedsubagent_omittedhidden_subagentc              3  &   K   | ]  }|v  
 y w)N ).0tsrcs     r   	<genexpr>z0_check8_concealment_warn_hold.<locals>.<genexpr>  s     2ac2s      u[   팀장이 subagent 결과를 숨기거나 누락했을 때 WARN/HOLD로 분류 가능한가zVanu_v3.authoritative_verdict_selector / dispatch.callback_owner_enforcer (source scan)zNo SUBAGENT_RESULT_CONCEALED / concealment classification exists in any guard or verdict module. A team-lead omitting or hiding subagent results is NOT detectable -> cannot be auto-classified WARN/HOLD by code.)r?   r@   rA   concealment_classifier_presentrD   rE   )	anu_v3r   dispatchr   inspect	getsourceanyr   r   )avscoetokenshas_classifierrA   r   s        @r   _check8_concealment_warn_holdr     so    <7


C
 7#4#4S#9
9CF 2622N$d#G" *8=1 r   c            
        t               } t        |       t               t        |       t	               t               t               t        |       t               g}t        dt        dt        di}|D ]   }|j                  |d   d      dz   ||d   <   " |d   d   t        k(  xr |d   d   t        k(  }|rdnd}t        t        t        d||||d	d
	S )z8Execute all 8 read-only checks against REAL entrypoints.r   rA   r=   rl   r   (BOUNDARY_ENFORCED_SUBAGENT_CONTRACT_GAPSBOUNDARY_NOT_ENFORCEDread_only_diagnosisu  Read-only. External boundary (ANU-only authoritative + team-lead callback owner=ANU) is code-enforced fail-closed. Subagent-specific structured contract (result schema fields, expected/forbidden/unresolved recording, concealment WARN/HOLD) is prompt-only — GAP.)	schemar,   trackmodeoverall-authoritative_callback_boundary_code_enforcedcountschecksnote)r;   rJ   rg   rr   r~   r   r   r   r   r   r   r   getSCHEMAr7   TRACK)r9   r   r   cboundary_okr   s         r   run_diagnosisr     s    >Dd#*,*40&()+,.&t,%'	F Aw3*F ?%zz!I,:Q>q|?
 )I&$.O6!9Y3G43OK  	3$  %9D1 r   c                Z    | }t        t        j                  t               dd             y)NFr]   )ensure_asciiindentr   )printjsondumpsr   )argv_s     r   mainr     s!    A	$**]_5
CDr   __main__r=   )r   strr   r   )return	List[str])r9   r   r   Dict[str, Any])r   r   )r   r   r   int)(__doc__
__future__r   r   r   r   r	   typingr   r   r   r   dirnameabspath__file__r   insertr   r   r7   r   r   r   r   rF   r   r;   rJ   rg   rr   r~   r   r   r   r   r   r   __name__
SystemExitr   r   r   r   <module>r      s  0 #   	 
 " " WW__RWW__RWW__X-FGH
SXXHHOOAz", &)
 
/

 
 *.-`&R4nCL0f8D)X z
T#((12,'
(( r   