
    j0                       d Z ddlmZ ddlZddlmZ ddlmZ g dZ ej                  d       ej                  d	       ej                  d
       ej                  d       ej                  d       ej                  d       ej                  d       ej                  d       ej                  d       ej                  d       ej                  d       ej                  d       ej                  d      gZ
 ej                  d       ej                  d       ej                  d       ej                  d       ej                  d       ej                  d       ej                  d       ej                  d      gZ ej                  d       ej                  d       ej                  d       ej                  d        ej                  d!       ej                  d"       ej                  d#       ej                  d$       ej                  d%       ej                  d&       ej                  d'       ej                  d(      gZ ej                  d)       ej                  d*       ej                  d+       ej                  d,       ej                  d-       ej                  d.      gZ ej                  d/       ej                  d0ej                         ej                  d1ej                         ej                  d2ej                         ej                  d3ej                        gZ ej                  d4       ej                  d5       ej                  d6       ej                  d7       ej                  d8       ej                  d9       ej                  d:       ej                  d;       ej                  d<      g	Z ej                  d=      Z ej                  d>      Z ej                  d?      Z ej                  d@      Z ej                  dA      ZdHdBZdIdCZdJdDZdKdEZdKdFZ	 dL	 	 	 	 	 dMdGZy)Nu  v3.6 Runtime Harness — finish-task profile task_mode classifier (P1-B §9).

chair_authorization_id=CHAIR-AUTH-TASK-2706-V36-FINISH-TASK-PROFILE-LAYER-P1B-260529

Implements §9 six task_mode automatic classification from task md signal.

Auto-classification priority (§9):
    code > system_hook > local_runtime > closeout_marker_only > callback_only > read_only > UNKNOWN

Public API
----------
- ``classify_task_mode(task_md_text, task_md_path)``
  Returns a dict:
  {
    "task_mode": str,
    "signal": str,
    "priority_applied": str,
    "confidence": "HIGH" | "MEDIUM" | "LOW" | "UNKNOWN",
  }

Safe-fail: never raises; any exception returns UNKNOWN with LOW confidence.
    )annotationsN)Optional   )VALID_TASK_MODES)codesystem_hooklocal_runtimecloseout_marker_onlycallback_only	read_onlyUNKNOWNz\bsrc/z\bapp/z\blib/z\bapi/z	\bmodels/z\bcontrollers/z\bservices/z\bviews/z\btests/(?!harness)z\btest_(?!v36)z
\.ts[\"' ]z
\.js[\"' ]z
\.go[\"' ]z\.claude/hooks/zsettings\.jsonzfinish[-_]task\.shzscripts/finishzhooks/z	\.claude/zsession[-_]watchdogztask[-_]scope[-_]guardzscripts/harness/z	dispatch/watchdogtaskctlztask[-_]timercronzscripts/harness/v\d+/dispatch_markerspawn_detectorcloseout_marker_watcherztests/harness/	test_v36_new_marker_artifactscloseoutzmemory/events/.*\.donezmemory/events/.*\.ackedzmemory/events/.*\.notifiedzmemory/events/.*\.escalatedr   zANU.*callback.*envelopezenvelope.*onlyzcollector_key.*ANUzanu_action.*PROCEEDzread[-_]onlyaudit	diagnosiszmemory/reports/zmemory/specs/
diagnosticzreport[-_]onlyzedits_existing.*\[\]znew_modules.*\[\]zedits_existing:\s*\n\s*-\s+zedits_existing:\s*\[\]znew_modules:\s*\n\s*-\s+path:znew_marker_artifacts:znew_modules:c                ,     t         fd|D              S )zACount how many patterns match the text (each pattern 0 or 1 hit).c              3  F   K   | ]  }|j                        sd   yw)r   N)search).0ptexts     I/home/jay/workspace/scripts/harness/v36/finish_task_profile_classifier.py	<genexpr>z&_count_pattern_hits.<locals>.<genexpr>   s     5Qahhtnq5s   !!)sum)r   patternss   ` r    _count_pattern_hitsr$      s    5(555    c           	         t        | t              t        | t              t        | t              t        | t              t        | t
              t        | t              dS )z$Return hit count for each task_mode.)r   r   r	   r
   r   r   )r$   _CODE_PATTERNS_SYSTEM_HOOK_PATTERNS_LOCAL_RUNTIME_PATTERNS_CLOSEOUT_PATTERNS_CALLBACK_PATTERNS_READ_ONLY_PATTERNS)r   s    r    _score_moder-      sO     $D.9*41FG,T3JK 3D:L M,T3EF(/BC r%   c                v    t         j                               }|dk(  ryt        t              D ]  \  }}|dk(  r y j	                  |d      }|dk  r%|dkD  r||z  nd}|dk(  r0t         fdt        |dz   d D        d      }|d	k  r||k  r|d
k  rf|dk\  r|d
k\  rd}n|d	k\  s|dk\  rd}nd}|||fc S  y)aq  Apply priority order with dominance check.

    Priority: code > system_hook > local_runtime > closeout_marker_only > callback_only > read_only.
    A higher-priority mode wins ONLY if its score is meaningfully present.
    For code: must have score >= 2, or score >= 1 AND no stronger competing mode signal.

    Returns (task_mode, priority_applied, confidence).
    r   )r   r   r   r   r   c              3  L   K   | ]  }|d k7  rj                  |d        yw)r   r   N)get)r   mscoress     r    r!   z)_pick_mode_by_priority.<locals>.<genexpr>   s*      $aN Aq! $s   !$r   N)default   g      ?   HIGHgffffff?MEDIUMLOW)r"   values	enumerate_PRIORITY_ORDERr0   max)r2   totalidxmodescoredominant_ratiocompeting_max
confidences   `       r    _pick_mode_by_priorityrD      s      Ez. / &	T9< +; 

4#A:*/!) 6>$?3q56+B $M qyUm38L A:.C/JaZ>T1!JJT:%%=&@ +r%   c                
   g }t        j                  d| t         j                        }|rY|j                  d      }t        j                  d|      }|t        j                  d|      z  }|t        j                  d|      z  }|S )z:Extract path strings from allowed_resources.paths section.z allowed_resources:.*?(?=\n\w|\Z)r   	"([^"]+)"	'([^']+)'z)- (scripts/\S+|tests/\S+|src/\S+|app/\S+)rer   DOTALLgroupfindall)r   pathsallowed_sectionsection_texts       r    _extract_allowed_pathsrP      su    Eii+T299O &,,Q/

<6L,77H,WWLr%   c                    t        j                  d| t         j                        }|rB|j                  d      }t        j                  d|      }|t        j                  d|      z  }|S g S )z1Extract path strings from expected_files section.z"expected_files:.*?(?=\n#{1,3} |\Z)r   rF   rG   rH   )r   expected_sectionrO   rM   s       r    _extract_expected_pathsrS      s`    yy-tRYY '--a0

<6L,77Ir%   c                   	 | rt        | t              sdddddS | }t        t        j	                  |            }t        t
        j	                  |            }t        t        j	                  |            }t        t        j	                  |            }t        |      }t        |      }|dz   dj                  |      z   dj                  |      z   }	t        |	      }
||z   D cg c]  }d|v sd|v r| }}|rt        |
d   d	      |
d<   ||z   D cg c]  }d
|v sd|v sd|v r| }}|rt        |
d   d	      |
d<   ||z   D cg c])  t        fddD              sj                  d      r+ }}|rt        |
d   d	      |
d<   |r|st        |
d   dz   d      |
d<   |r'|s%|s#|r!t        |
d   dz   d      |
d<   dD ]  }d|
|<   	 t        j                  d|      r|s|rt        |
d   dz   d      |
d<   |r|s|st        |
d   d	z   d	      |
d<   t!        |
      \  }}}g }t"        dd D ]0  }|
j%                  |d      }|dkD  s|j'                  | d|        2 ddj                  |      z   dz   }|r|dt)        |       z  }|r|d t)        |       z  }||||dS c c}w c c}w c c}w # t*        $ r}dd!| dddcY d}~S d}~ww xY w)"ab  Classify a task's task_mode from its task md content.

    Args:
        task_md_text: Full text content of the task md file.
        task_md_path: Optional path for logging; not used in classification.

    Returns:
        dict with keys: task_mode, signal, priority_applied, confidence.

    Safe-fail: never raises. Returns UNKNOWN on any error.
    r   empty_or_invalid_task_md)	task_modesignalpriority_appliedrC   
 harnessdispatchr	   r   z.claudehookszsettings.jsonr   c              3  @   K   | ]  }j                  |        y wN)
startswith)r   pfxr   s     r    r!   z%classify_task_mode.<locals>.<genexpr>  s     [3Q\\#.[s   )zsrc/zapp/zlib/zapi/)z.pyz.shz.tsz.jsz.gor   r4   r
   r5   )r   r   r	   r   r   r   r   r   N:zscores=[,]z allowed_paths=z expected_paths=zclassifier_exception: )
isinstancestrbool_HAS_MARKER_ONLYr   _HAS_EDITS_EXISTING_HAS_NEW_MODULES_EMPTY_EDITSrP   rS   joinr-   r<   anyendswithrI   rD   r;   r0   appendlen	Exception)task_md_texttask_md_pathr   
has_marker	has_editshas_new_modulesempty_editsallowed_pathsexpected_pathscombinedr2   r   harness_paths
hook_paths
prod_pathskrV   rX   rC   signal_partsr?   srW   excs              `            r    classify_task_moder      s   `
:lC#@&4$-'	  
 *11$78
,33D9:	/66t<=<..t45 /t406$;-!88388N;SS X& &3^%C ?q%NjAo  ? ?&)&*A1&EF?# #0."@ QA"a7a<?a;O  Q
 Q$'}(=q$AF=! #0."@ JA[:Z[[$GH  J
 J  3F6N [ !!3Q7F6N iK-08N1ORS1SUV-WF)*[ q	 99%t,_&)&*AA*Eq&IF?# z"%f[&9A&=q"AF;2H2P/	#Z #CR( 	3D

4#A1u##tfAaSM2	3 chh|44s:M(:';<<F(^)<(=>>F # 0$	
 	
m?QJb  
".se4 )#	
 	

sU   J8 CJ8 'J)8J8 J.*J8 .J36CJ8 AJ8 )J8 8	K	K
KK)r   rg   r#   listreturnint)r   rg   r   dict[str, int])r2   r   r   ztuple[str, str, str])r   rg   r   z	list[str]r_   )rs   rg   rt   zOptional[str]r   dict)__doc__
__future__r   rI   typingr   finish_task_profile_schemar   r;   compiler'   r(   r)   r*   
IGNORECASEr+   r,   rj   rl   rk   ri   _HAS_NEW_MODULES_ONLYr$   r-   rD   rP   rS   r    r%   r    <module>r      s  , # 	  8
  BJJyBJJyBJJyBJJyBJJ|BJJ !BJJ~BJJ{BJJ%&BJJ !BJJ}BJJ}BJJ}& BJJ!"BJJ !BJJ$%BJJ !BJJyBJJ|BJJ%&BJJ()	  BJJ"#BJJ|BJJ{BJJzBJJ BJJwBJJ'(BJJ!"BJJ !BJJ)*BJJ !BJJ| " BJJ&'BJJ{BJJ()BJJ)*BJJ,-BJJ-.  BJJ BJJ)2==9BJJ "--0BJJ$bmm4BJJ%r}}5  BJJBJJxBJJ|BJJ!"BJJ BJJ}BJJ !BJJ&'BJJ#$
  !bjj!?@ rzz342::>? 2::67 "

?3 6
	.+b
 #'o
o
o
 
o
r%   