
    i'                       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dl
mZmZ dd	lmZ  ed
       G d d             Z ed
       G d d             Z ed
       G d d             Z G d d      ZddZg dZy)u  cycle_advancer PoC core (Analyzer + Proposer).

task-2488 Phase B PoC. 회장-ChatGPT closed loop를 시스템화하기 위한
격리 PoC 코어. evidence → analyzer → root cause + 다음 task 제안 매핑
경로를 mock 환경에서 검증한다.

5단계 처리 로직 (task 명세 그대로 구현):

    1. gap analysis (목표 vs 실제)
    2. root cause 후보 N개 생성 (mock = 3개 stub)
    3. 마아트(facts) + 외부 AI(strategy) 비평 시뮬레이션 (mock)
    4. 합의/충돌 판정
    5. 다음 task 제안서 draft 생성

YAML frontmatter 스키마 cycle_advancer/v1
-----------------------------------------

::

    ---
    schema: cycle_advancer/v1
    source_task_id: task-2485
    proposed_task_id: task-2486
    classification: MERGE_PENDING_DEPENDENCY
    proposal_only: true
    ready_for_dispatch: false
    chairman_required: false
    conflict_summary: null
    generated_at: 2026-05-08T00:00:00Z
    generator: cycle_advancer/v1-mock
    deterministic_seed: cycle_advancer-v1-mock
    ---

합격 조건: 동일 입력 + 동일 fixed-timestamp → 동일 출력 (파일 hash 일치).

Forbidden (PoC 범위 외):
    - 실제 ``.done`` / ``.escalate`` / ``.fail`` 파일 생성 금지
    - 실제 dispatch 호출 금지
    - 외부 AI 호출 금지 (``mock_ai_adapter``만 사용)

Packaging note:
    이 모듈은 ``tools.poc.cycle_advancer`` 패키지의 코어이며,
    패키지 ``__init__``에서 public symbol을 re-export 한다.
    )annotationsN)	dataclass)Path)Any   )MockProposallookup_proposal)DraftPayloadT)frozenc                  :    e Zd ZU dZded<   ded<   ded<   ded<   y)GapAnalysisu+  단계 1: gap analysis 결과 (목표 vs 실제).

    Attributes:
        intended_outcome: 본래 의도한 결과 (예: ``MERGED_DONE``).
        actual_outcome: 실제 도달 상태 (예: ``MERGE_PENDING``).
        blocker_type: blocker 분류.
        blocker_description: blocker 설명.
    strintended_outcomeactual_outcomeblocker_typeblocker_descriptionN__name__
__module____qualname____doc____annotations__     4/home/jay/workspace/tools/poc/cycle_advancer/core.pyr   r   >   s!     r   r   c                  :    e Zd ZU dZded<   ded<   ded<   ded<   y	)
CritiqueResultu)  단계 3-4: 마아트(facts) + 외부 AI(strategy) 비평 결과.

    Attributes:
        facts_view: 마아트 관점 한 줄 요약.
        strategy_view: 외부 AI 관점 한 줄 요약.
        agreement: 합의 여부.
        conflict_summary: 충돌 시 사유 (합의 시 ``None``).
    r   
facts_viewstrategy_viewbool	agreementz
str | Noneconflict_summaryNr   r   r   r   r   r   O   s     OO  r   r   c                  :    e Zd ZU dZded<   ded<   ded<   ded	<   y
)AnalysisResultu&  단계 5: 다음 task 제안서 draft에 필요한 모든 분석 결과.

    Attributes:
        gap: gap analysis.
        root_cause_candidates: root cause 후보 N개.
        critique: 마아트 + 외부 AI 비평 결과.
        proposal: mock LLM이 반환한 :class:`MockProposal`.
    r   gapztuple[str, ...]root_cause_candidatesr   critiquer   proposalNr   r   r   r   r$   r$   `   s!     
**r   r$   c                  T    e Zd ZdZddZ	 	 	 	 	 	 	 	 ddZed	d       Zed
d       Zy)CycleAdvanceru=  Analyzer + Proposer 코어.

    이 클래스는 fixture로부터 evidence를 받아 5단계 분석을 수행하고
    :class:`AnalysisResult`를 반환한다. ``DraftPayload`` 변환은
    :meth:`build_draft_payload`에서 별도로 수행하여 timestamp 주입 책임을
    호출자(CLI)에 위임한다.
    c                    |d   }| j                  |      }t        |      }|j                  }| j                  |      }t	        ||||      S )u'  5단계 분석 파이프라인을 실행한다.

        Args:
            evidence: fixture에서 로드한 source task evidence dict.

        Returns:
            :class:`AnalysisResult`.

        Raises:
            KeyError: evidence의 ``task_id``가 mock 매핑에 없는 경우.
        task_id)r%   r&   r'   r(   )_gap_analysisr	   candidate_root_causes_simulate_critiquer$   )selfevidencer,   r%   r(   r&   r'   s          r   analyzezCycleAdvancer.analyze   se     9%   * #7+ ( > > **84 "7	
 	
r   c                0   |j                   }|j                  }|j                  di       xs i }|j                  d      }|j                  d      }|j                  d      }	d|j                  dd       d| d	| d
|	 d|j                   d|j                   g}
|j                  d      }|r|
j                  d|        |j                  j                  du xs |j                  }d|j                   d	|j                   dd|rd| ndg}t        |d   |j                  |j                  ||j                  j                  ||j                  |j                  t!        |
      |j                  |j"                  |j$                  t!        |            S )uJ  분석 결과 + timestamp를 결합하여 :class:`DraftPayload`를 만든다.

        Args:
            evidence: fixture에서 로드한 evidence dict.
            analysis: :meth:`analyze` 결과.
            generated_at: deterministic timestamp (ISO8601 + ``Z``).

        Returns:
            :class:`DraftPayload`.
        merge_status	pr_numberstatepr_urlzsource classification: classificationUNKNOWNzPR: #z (z) z	blocker: u    — post_resolution_chainzpost-resolution chain: Fu   제안된 다음 task: )uU   본 draft는 proposal_only=true / ready_for_dispatch=false — 실제 dispatch 금지u   체인 의존: u*   체인 의존: (evidence에 정의 없음)r,   )source_task_idproposed_task_idr8   chairman_requiredr"   generated_atconsensus_root_causer.   evidence_summaryscopeaffected_filesallowed_resources
next_steps)r(   r%   getr   r   appendr'   r!   r>   r=   rB   r
   r8   r"   r@   r&   tuplerC   rD   )r0   r1   analysisr?   r(   r%   r4   r5   pr_stater7   rA   chainr>   rE   s                 r   build_draft_payloadz!CycleAdvancer.build_draft_payload   s     $$ll||NB7=2 $$[1	##G,!!(+ &hll3CY&O%PQI;b
"VH5(()s/F/F.GH'

 45##&=eW$EF ''50('' 	
 &h&?&?%@8>>BRRSTc  "%)A!

 #I.%66#22/%..??%!)!>!>"*"@"@"#34..#22&88Z(
 	
r   c           	         | j                  di       xs i }| j                  di       xs i }|j                  d      }|rdnd}t        d||j                  dd      |j                  d	d
            S )uA   단계 1: 목표 vs 실제의 gap을 evidence에서 추출한다.r4   merge_blocker	merged_atMERGEDMERGE_PENDINGMERGED_DONEtypeunknowndescription )r   r   r   r   )rF   r   )r1   r4   rN   rO   r   s        r   r-   zCycleAdvancer._gap_analysis   sz      ||NB7=2 _b9?R $$[1	%.O*)&**69= - 1 1- D	
 	
r   c                P    | j                   du }t        dd|| j                        S )u!  단계 3-4: mock 비평 시뮬레이션.

        deterministic 매핑이므로 ``proposal.chairman_required`` 값과 그에
        대응하는 ``proposal.conflict_summary``를 그대로 critique 결과로
        승격한다. 외부 AI 호출은 절대 수행하지 않는다.
        Fu_   마아트(facts): evidence의 blocker는 essence-fail 아닌 infrastructure/lifecycle 의존성ue   외부 AI(strategy): chain 의존을 해소하는 후속 task 분리가 최소 변경 + 최단 경로)r   r   r!   r"   )r>   r   r"   )r(   r!   s     r   r/   z CycleAdvancer._simulate_critique   s9     ..%7	50  %66
 	
r   N)r1   dict[str, Any]returnr$   )r1   rX   rI   r$   r?   r   rY   r
   )r1   rX   rY   r   )r(   r   rY   r   )	r   r   r   r   r2   rL   staticmethodr-   r/   r   r   r   r*   r*   v   sa    
B=
 =
 !=
 	=

 
=
F 
 
 
 
r   r*   c                    | | dz  }|j                         st        d| d      |j                  dd      5 }t        j                  |      cddd       S # 1 sw Y   yxY w)u>  fixture 디렉토리에서 task evidence JSON을 로드한다.

    Args:
        fixture_dir: fixture 디렉토리 경로.
        task_id: 로드할 task_id (파일명은 ``{task_id}.json``).

    Returns:
        파싱된 evidence dict.

    Raises:
        FileNotFoundError: fixture 파일이 없는 경우.
    z.jsonzfixture not found: u[    (PoC는 격리 fixture만 사용하며 실제 memory/events를 직접 읽지 않습니다)rzutf-8)encodingN)is_fileFileNotFoundErroropenjsonload)fixture_dirr,   targetfhs       r   load_fixturerf     ss     gYe,,F>>!& *i j
 	
 
S7	+ ryy}  s   AA#)r*   r$   r   r   r   r
   r	   rf   )rc   r   r,   r   rY   rX   )r   
__future__r   ra   dataclassesr   pathlibr   typingr   mock_ai_adapterr   r	   output_writerr
   r   r   r$   r*   rf   __all__r   r   r   <module>rn      s   +Z #  !   : ' $    $! ! !  $  *Q
 Q
r.	r   