
    =R4jrG                     ~   d Z ddlZ G d d      Z eej                  ej
                  ej                  ej                  ej                  ej                  ej                  ej                  ej                  ej                  g
      Zd Zddddddd	dd	dddddd	d
Zg dZd Zd Zd ZddZdZ	 	 ddZg dZdZd Zy)u  
v2_13_gate.py — ANU v2.13 Phase 1 얇은 gate 최소 구현 (순수 함수, stdlib only)

★ non-matching thin gate 분리 구성 (task-2758, 회장 결정 2026-06-17):
  matching 축(allowlist axis 텍스트 검출)은 4회차 종료·보류되어 이 모듈에서
  완전히 제거되었다. diff/tool_calls 비정형 텍스트에서 위험 축을 추출하던
  detect_allowlist_axis 및 그 보조 함수(_extract_touched_files/_glob_match/
  _match_forbidden_paths/_match_forbidden_ops/_is_word_form_op/_phrase_in_tokens/
  _normalize/_flatten_tool_calls/_AXIS_PATTERNS)는 전부 삭제됐다.
  gate 판정은 이제 runtime_state(rs) 의 명시적 flag 와 contract 메타데이터,
  그리고 Step5 goal expansion 의 구조화 입력(rs.touched_files vs
  contract.expected_files) set membership 비교에만 의존한다.

ESCALATION_PACKET_FIELDS 결정 근거:
  doctrine §13.1 에스컬레이션 패킷 15 필드
  + §13 budget 카운터 2 필드(same_signature_retry_count, same_goal_correction_count)
  = 총 17 필드.

절대 제약:
  - daemon/socket/API/external probe/key custody/DB permission/systemd 변경 0건.
  - budget reset / promotion APPROVED 부여 / goal_id 생성 금지 (Chair 권한).
  - 코드는 검사만 수행함.
    Nc                   4    e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
Zy)GateVerdict GOAL_ENABLING_CORRECTION_ALLOWEDGOAL_EXPANSION_BLOCKEDSEMANTIC_RESIDUE_CHAIR_DEFAULTALLOWLIST_AXIS_CHAIR_REQUIREDBUDGET_EXCEEDED_CHAIR_REQUIREDROLLBACK_COST_FLOOR_VIOLATIONINVALID_CONTRACT_PROVENANCEEXTERNAL_PROBE_REQUIREDCONTROL_DB_DIRECT_WRITE_BLOCKEDPROMOTION_SELF_APPROVAL_BLOCKEDN)__name__
__module____qualname__r   r   r   r   r	   r
   r   r   r   r        */home/jay/workspace/dispatch/v2_13_gate.pyr   r      sA    )K$)A)I"
 *I!)I")H!)F)B)J#)J#r   r   c                     | syt        |       j                  dd      }t        j                  dd|      }|j	                  d      r|dd }|j	                  d      r|j                  d      S )u  파일 경로 형식 정규화 (Step5 goal expansion set membership 비교 전용).

    안전 정규화만 수행한다:
    - OS separator(``\``) → posix(``/``) 통일
    - leading ``./`` 반복 제거
    - 중복 slash 축약
    - 대소문자는 **보존** (대소문자 구분 파일시스템 — 경로 소문자화 금지)

    ★ matching 보류(task-2758)에 따른 안전 제약:
    - ``a/``·``b/`` 접두사를 **무조건 strip 하지 않는다**. 실제 repo 경로가
      ``a/...``·``b/...`` 일 수 있으므로 보존한다.
    - substring 매칭에 쓰지 않는다. rs.touched_files 와 contract.expected_files
      양쪽을 동일하게 normalize 한 뒤 **set membership** 비교에만 사용한다.
    - 소문자화 금지.
     \/z/+z./   N)strreplaceresub
startswithstrip)pss     r   normalize_pathr"   @   sc      AtS!A
uc1A
,,t
abE ,,t
773<r   LOWMEDIUMIRREVERSIBLEHIGH)docs_report_onlyexpected_files_reversible_codetest_fixture_onlylocal_runner_wiringruntime_config_touchcontrol_db_writeheartbeat_direct_updatepromotion_approvedsystemd_unit_editsystemd_enable_installcredential_owner_key_secretproduction_writemerge_push_releaseexternal_sendforbidden_path)r#   r$   r&   r%   c                     	 t         j                  t        |       j                         j	                               S # t
        t        f$ r Y yw xY w)u=   비용 문자열 → 정수 순위. 알 수 없으면 0(LOW).r   )
COST_ORDERindexr   r   upper
ValueErrorAttributeError)cs    r   
_cost_rankr=   u   sD     A 4 4 677' s   9< AAc                     d}| xs g D ]-  }t         j                  |      }|t        |      }||kD  s,|}/ t        |   S )u  
    touched_axes(list[str]) 중 ROLLBACK_FLOOR_TABLE에 있는 축들의
    floor 중 최대값 반환. 비어있거나 매칭 없으면 "LOW".

    ★ task-2758: classify_gate 는 touched_axes 를 항상 [] 로 전달한다
      (matching 축 검출 제거). 단 이 순수 함수는 명시적 축 리스트(예: contract
      가 제공하는 축, 테스트)로 직접 호출될 수 있어 테이블 로직을 유지한다.
    r   )ROLLBACK_FLOOR_TABLEgetr=   r7   )touched_axesmax_rankaxis	floor_valranks        r   rollback_floorrF      sV     H#  (,,T2	 i(Dh  hr   c                 T    t        |       }t        |      }t        t        ||         S )uG   COST_ORDER 기준 max(reported, floor). 잘못된 값은 LOW로 간주.)r=   r7   max)reportedfloorrfs       r   max_rollback_costrM      s'    8A5Ac!Qi  r   c                     t        t        |             }t        |t              r(|j	                  d      }|rt        |t        |            }|rt        |t        |            }t        |   S )u  축 테이블 floor / contract.rollback_floor / forced floor 중 최댓값.

    classify_gate 가 contract 의 rollback_floor 를 무시하던 결함을 닫는다.
    - touched_axes → ROLLBACK_FLOOR_TABLE 기반 floor (task-2758: 항상 [] 전달)
    - contract["rollback_floor"] → Chair 가 contract 에 명시한 하한
    - forced → 분기별 강제 하한 (control_db=HIGH, promotion=IRREVERSIBLE)
    셋 중 COST_ORDER 최댓값을 반환.
    rF   )r=   rF   
isinstancedictr@   rH   r7   )rA   contractforcedrB   cfs        r   effective_floorrT      s^     .67H(D!\\*+8Z^4HxF!34hr   goal_idrequested_decisiongate_verdictsemantic_residuetrust_roots_touchedrollback_costblast_radiusbudget_remainingdiff_summaryexpected_filesoutside_expected_filesforbidden_operations_detectedexternal_probe_statusrecommended_actionsafe_defaultsame_signature_retry_countsame_goal_correction_countc                 l    i d| d|d|d|d|d|d|d|d	|d
|	d|
d|d|d|d|d|d|S )u   
    에스컬레이션 패킷 생성. 정확히 17개 키를 가진 dict 반환.
    doctrine §13.1 (15필드) + §13 budget 카운터 2필드 = 17.
    코드는 패킷을 생성만 하며 budget reset / APPROVED 부여 불가 (Chair 전용).
    rV   rW   rX   rY   rZ   r[   r\   r]   r^   r_   r`   ra   rb   rc   rd   re   rf   r   rU   s                    r   build_escalation_packetrh      s    0g&8 	l 	&6	
 	&9 	m 	l 	&6 	l 	n 	!&< 	()F 	 &; 	&8 	l  	%&@!" 	%&@# r   )
rV   scoper\   allowed_capability_deltar_   allowed_runtime_changesforbidden_operationsrF   budgetexit_criteria)chair_injectedstrict_templatec                    |xs i }t        | t              st        j                  dg ddS t        D cg c]	  }|| vs| }}|rt        j                  d| g ddS | j                  d      t        vr.t        j                  d| j                  d      dt         g ddS g }|j                  dd	      }|j                  d
d      }	|j                  d      r-t        || d      }
t        j                  d|t        |	|
      dS |j                  d      r-t        || d      }
t        j                  d|t        |	|
      dS |j                  d      r3|dk7  r.t        ||       }
t        j                  d||t        |	|
      dS t        ||       }
t        |	      t        |
      k  r%t        j                  d|	d|
|t        |	|
      dS |j                  d      }d}|	 t        |      }|(|dk  r#t        j"                  d| d|t        |	|
      dS | j                  d      xs g }|j                  d      xs g }| j                  d      xs g }|j                  d      xs g }|D ch c]  }t%        |       }}|D cg c]  }t%        |      |vr| }}|D cg c]	  }||vs| }}|s|r%t        j&                  d | d!| |t        |	|
      dS |j                  d"      rt        j(                  d#|t        |	|
      dS t        j*                  d$|t        |	|
      dS c c}w # t        t         f$ r d}Y Ww xY wc c}w c c}w c c}w )%uz  
    gate 판정 (결정론 — 위→아래 첫 매칭 반환).

    ★ non-matching thin gate (task-2758): allowlist 축 텍스트 검출
      (detect_allowlist_axis) 이 제거됐다. control_db / promotion / external_probe
      분기는 runtime_state 의 명시적 flag 단독으로만 판정한다. diff/tool_calls 는
      더 이상 위험 축 추출에 쓰이지 않으며(시그니처 호환을 위해 인자만 유지),
      Step5 goal expansion 만 구조화 입력 rs.touched_files 를 사용한다.

    Parameters
    ----------
    contract : dict   — goal_contract
    diff : str        — (호환용 인자; 위험 축 추출에 쓰지 않음)
    tool_calls : list — (호환용 인자; 위험 축 추출에 쓰지 않음)
    runtime_state : dict

    Returns
    -------
    dict {"verdict": str, "reason": str, "touched_axes": list, "rollback_cost": str}
    zcontract is not a dictr#   )verdictreasonrA   r[   z"contract missing required fields: 
provenancezinvalid provenance: z; must be one of rb   NOT_REQUIREDreported_rollback_costcontrol_db_opr&   )rR   z&control_db_op flagged in runtime_statepromotion_self_approvalr%   z0promotion_self_approval flagged in runtime_stateexternal_probe_requiredPASSz#external probe required but status=zreported rollback cost z	 < floor r]   Nr   zbudget_remaining=z <= 0r_   touched_filesrj   capability_deltazoutside_files=z, outside_caps=rY   z)semantic_residue flagged in runtime_statezall checks passed)rO   rP   r   r   _CONTRACT_REQUIREDr@   _VALID_PROVENANCESrT   r   rM   r   r   r=   r
   float	TypeErrorr:   r	   r"   r   r   r   )rQ   diff
tool_callsruntime_statersrL   missingrA   rb   rI   rD   r]   
budget_valr_   r{   allowed_cap_deltar|   expected_normoutside_filesr<   outside_capss                        r   classify_gater     s   * 
	"B h%(DD5"	
 	
 -BQ0AqBGB(DDA'K"	
 	
 ||L!);;(DD&x||L'A&D E""4!57  "
 	
 LFF#:NKvv.6H	vvo#L(6J	(HHE).xC	
 	
 
vv'(#L(>R	(HHO).xC	
 	
 
vv'(-Bf-L#L(;	(@@56K5NO).xC
 	
  h7I(j33(FF)(YymL).xC
 	
 vv01 J#	/0J */(GG01A0B%H).xC	
 	
 %LL)9:@bNFF?39rM$LL)CDJFF#56<"0>?1^A&?M? - @1&q)>  @M @ 0O1A=N4NQOLO(?? |nM).xC
 	
 
vv !(GGH).xC	
 	
 %EE,%*8Y?	 } Cd :& 	J	& @@Os4   	L0L0'L5 4MM(	M2M5M
	M
)N)r   r   )__doc__r   r   	frozensetr   r   r   r   r	   r
   r   r   r   r   GATE_VERDICTSr"   r?   r7   r=   rF   rM   rT   ESCALATION_PACKET_FIELDSrh   r}   r~   r   r   r   r   <module>r      s
  0 
K K  00&&..--..--++''//// ": ',&+&+&.&.&4&,&4&,&4&4&4&4&4&, , 7
 ,! , J  ! #*`  ; br   