
    j"                    :   U d Z ddlmZ ddlZddlmZ ddlmZ ddlm	Z	 dZ
ded	<   d
Zded<   dZded<   dZded<   dZded<   dZdZdZdZdZ eeeeh      Z eeeh      Z ed       G d d             Zd"dZd#dZd$dZd%dZd%dZdd	 	 	 	 	 d&d Zg d!Zy)'u7  utils.prompt_byte_classifier — task-2645 cron prompt UTF-8 byte gate.

회장 verbatim policy (2026-05-24 task-2644 사고 박제 §3 정확 정책):
- ≤3200 bytes        => OK_TARGET
- 3201~3499 bytes    => OK_ABOVE_TARGET
- 3500~3900 bytes    => WARNING_BUT_ALLOWED
- >3900 bytes        => HARD_BLOCK
- 4096 bytes         => cokacdir channel absolute limit (envelope max)
- 측정 단위: ``printf '%s' "$P" | wc -c`` 와 동일 (UTF-8 bytes, NOT chars)

>3900 bytes 프롬프트는 자동 path-only compact prompt 모드로 전환되어야 한다
(task md 경로 + sha256 만 envelope에 담는다). 이 모듈은 측정/분류/compact 변환
helper 를 제공하고, dispatch 측이 fail-closed gate 에서 호출한다.

본 모듈은 ANCHOR-2 (회장 verbatim 박제 단일소스 §3 정책) 의 코드화이다.
    )annotationsN)	dataclass)Path)Optionali  intPROMPT_OK_TARGET_MAXi  PROMPT_OK_ABOVE_TARGET_MAXi<  PROMPT_WARNING_MAXPROMPT_HARD_BLOCK_THRESHOLDi   COKACDIR_CHANNEL_ABSOLUTE_LIMIT	OK_TARGETOK_ABOVE_TARGETWARNING_BUT_ALLOWED
HARD_BLOCKCHANNEL_ABSOLUTE_OVERFLOWT)frozenc                  j    e Zd ZU dZded<   ded<   ded<   ded<   ded	<   ded
<   ded<   ded<   ddZy)PromptByteClassificationu9   단일 prompt 분류 결과 (immutable; JSON schema 1:1).r   
utf8_bytesstrverdictboolallowedwarning
hard_blockchannel_overflowrequires_compact_modereasonc                    d| j                   | j                  | j                  | j                  | j                  | j
                  | j                  | j                  t        t        t        t        t        dd
S )Nz&dispatch.prompt_byte_classification.v1)ok_target_maxok_above_target_maxwarning_maxhard_block_thresholdchannel_absolute_limit)
schemar   r   r   r   r   r   r   r   policy)r   r   r   r   r   r   r   r   r   r	   r
   r   r   )selfs    M/home/jay/workspace/.worktrees/task-2645-dev2/utils/prompt_byte_classifier.pyto_jsonz PromptByteClassification.to_json;   s_    >//||||||// $ 5 5%)%?%?kk!5'A1(C*I
 	
    N)returndict)__name__
__module____qualname____doc____annotations__r)    r*   r(   r   r   .   s5    COLMMK
r*   r   c                    | yt        | t              s!t        dt        |       j                         t        | j                  d            S )u  ``printf '%s' "$prompt" | wc -c`` 와 동등한 UTF-8 byte count.

    ★ wc -c bytes — NOT wc -m chars. ANU paraphrase 사고 (≤2800자 권장을 hard limit
    으로 해석) 의 정정 doctrine이다. caller 타입 미신뢰 — None / non-str 도 안전 처리.
    r   zprompt must be str, got zutf-8)
isinstancer   	TypeErrortyper-   lenencodeprompts    r(   measure_utf8_bytesr;   P   sH     ~fc"24<3H3H2IJKKv}}W%&&r*   c                .    t        |       }t        |      S )u0   회장 verbatim 4 구간 + 4096 absolute 분류.)r;   classify_byte_count)r:   ns     r(   classify_prompt_bytesr?   ]   s    6"Aq!!r*   c                   | dk  rt        d|        | t        kD  r"t        | t        dddddd|  dt         d      S | t        kD  r"t        | t
        dddddd|  dt         d	      S | d
k\  r"t        | t        dddddd|  dt         d      S | dk\  r"t        | t        dddddd|  dt         d      S t        | t        dddddd|  dt         d      S )uD   byte count 만으로 분류 (이미 측정된 값 재분류 용도).r   zbyte count must be >= 0, got FTzprompt z	 bytes > u:    (cokacdir channel absolute limit) — silent drop 위험.)r   r   r   r   r   r   r   r   u?    (HARD_BLOCK). path-only compact mode 로 자동 전환 필요.i  z bytes (3500~u#   ) — 압축 권장, 발사 허용.i  z bytes (3201~u*   ) — 권장 target 약간 초과, 안전.u    bytes ≤ u    — 권장 target.)
ValueErrorr   r   r   r   r   r   r
   r   r	   r   r   )r>   s    r(   r=   r=   c   sg   1u8<== 	**'-!"&!I&E%F GL M
 	
 	&&'""&!I&A%B CC C
 	
 	Dy''""'!M*<)==`a
 	
 	Dy'#""'QC}-G,HHrs	
 		
 $#;';&<<OP	 	r*   c                ,    t        |       j                  S )uf   발사 허용 여부 (allowed=True 이면 발사 진행, 단 warning 은 압축 권장 별도 로깅).)r?   r   r9   s    r(   
is_allowedrC      s     (000r*   c                ,    t        |       j                  S )uH   >3900 bytes 또는 4096 초과 — path-only compact mode 강제 여부.)r?   r   r9   s    r(   requires_path_only_compactrE      s     (>>>r*   )extra_contextc                  t        |       }d}	 |j                         rFt        |d      5 }t        j                  |j                               j                         }ddd       dd| d| dg}|r%|j                  d|j                         dd	         d
j                  |      S # 1 sw Y   MxY w# t        $ r d}Y ]w xY w)uX  >3900 bytes 자동 path-only compact prompt 생성.

    회장 verbatim §17 항목 7: "prompt >3900 시 자동 path-only compact prompt mode
    (task md 경로 + sha256 만)".

    Args:
        task_md_path: dispatched task md 절대/상대 경로 (문자열 또는 Path).
        extra_context: 선택. 1줄 추가 컨텍스트 (envelope 안에 헬퍼 caller 가 합쳐 넣을 때).

    Returns:
        compact prompt 문자열. envelope 합산 후에도 ≤3900 bytes 가 되도록 envelope
        caller 가 검증해야 한다 (helper 단독은 task md 경로 + sha256 + 1줄 지시).
    MISSINGrbNz[DISPATCH_PATH_ONLY_COMPACT]ztask_md_path: ztask_md_sha256: uy   instruction: 위 경로 task md 정독 후 즉시 시작. 본 envelope 은 path-only compact (>3900 bytes 자동 전환).zextra:    
)r   is_fileopenhashlibsha256read	hexdigestOSErrorappendstripjoin)task_md_pathrF   pshafliness         r(   build_path_only_compact_promptr[      s    $ 	\A
C99;a ;!nnQVVX.88:; 	'

3%  	D	E w}224Tc:;<=99U; ; s(   B5 2B)B5 )B2.B5 5CC)r   r	   r
   r   r   r   r   r   r   r   VERDICTS_ALLOWEDVERDICTS_BLOCKEDr   r;   r?   r=   rC   rE   r[   )r:   objectr+   r   )r:   r   r+   r   )r>   r   r+   r   )r:   r   r+   r   )rV   z
str | PathrF   zOptional[str]r+   r   ) r0   
__future__r   rN   dataclassesr   pathlibr   typingr   r   r1   r	   r
   r   r   r   r   r   r   r   	frozensetr\   r]   r   r;   r?   r=   rC   rE   r[   __all__r2   r*   r(   <module>re      s     #  !  
 ! c  "& C & C #' S ''+  + 	#+ 
7 i:MNO j*CDE  $
 
 
B
'"K\1
? $(## !# 		#Lr*   