schema_version: quant_engine_qedd_refactor_todo.v1
title: 저성능 LLM 재현 가능한 퀀트투자 엔진 리팩토링 TODO
generated_at_kst: '2026-06-10T22:34:53+09:00'
language: ko-KR
source_basis:
  zip_path: data_feed.zip
  zip_sha256: ffa5d7563651b5d025ac9df0aba90740352eb5deef743789fa404b12e1186a3a
  inspected_authority_files:
  - AGENTS.md
  - runtime/active_artifact_manifest.yaml
  - spec/49_refactor_methodology_contract.yaml
  - spec/34_architecture_boundaries.yaml
  - spec/41_release_dag.yaml
  - spec/43_quant_factor_taxonomy.yaml
  - spec/45_number_provenance_contract.yaml
  - spec/46_low_capability_execution_pack.yaml
  - spec/47_packaging_policy.yaml
  - spec/48_module_io_contract_registry.yaml
  - spec/51_formula_lifecycle_registry.yaml
  - governance/adr/0011-qedd-methodology.md
  - Temp/engine_harness_gate_result.json
  - Temp/pipeline_runtime_profile_v1.json
  - Temp/formula_runtime_registry_v1.json
  - Temp/number_provenance_ledger_v4.json
  current_repository_metrics:
    total_files: 1469
    md_files: 40
    yaml_files: 182
    py_files: 849
    gs_files: 15
    json_files: 376
    jsonl_files: 2
    spec_yaml_files: 126
    tools_py_files: 370
    src_py_files: 178
    temp_json_files: 17
    md_total_lines: 2367
    yaml_total_lines: 93574
    py_total_lines: 62426
    gs_total_lines: 20538
    engine_gate_status: OK
    engine_failed_check_count: 0
    engine_total_check_count: 106
    engine_warn_only_check_count: 9
    engine_warn_failed_check_count: 1
    number_provenance_coverage_pct: 100
    runtime_profile_gate_status: SKIPPED
    runtime_profile_mode: package-only
    active_manifest_report_match_pct: 100.0
    active_manifest_authority_collision_count: 0
    active_manifest_stale_artifact_count: 0
    formula_runtime_registry_file_gate: FAIL
    formula_runtime_registry_file_coverage_pct: 77.4
    formula_runtime_registry_file_unmapped_count: 66
  diagnostic_findings:
  - '방법론의 큰 축은 이미 정답에 가깝다: QEDD, Contract-First, Python Canonical, GAS thin adapter, No LLM Math가 존재한다.'
  - 핵심 리스크는 원칙 부재가 아니라 확장 과정에서 생기는 권위 충돌, 버전 스프롤, stale runtime artifact, 도구 중복, 문서 파편화다.
  - Temp/engine_harness_gate_result.json의 로그는 formula runtime registry PASS 100%를 말하지만, Temp/formula_runtime_registry_v1.json
    파일 자체는 FAIL 77.4%와 unmapped 66을 가진다. 이는 산출물 갱신/권위/동기화 검사가 별도 hard gate가 되어야 함을 뜻한다.
  - GAS 파일 수는 적지만 총 라인 수가 크다. GAS는 thin adapter여야 하므로 신규 계산 로직은 src/quant_engine으로 이동시키는 migration ledger를 계속 유지해야 한다.
  - 문서 라인 수는 과하지 않지만 yaml 총량과 generated 파일 총량이 크므로 사람이 읽는 문서는 줄이고 기계 검증 가능한 contract와 manifest 중심으로 운영해야 한다.
target_methodology:
  name: 'QEDD-R: Quant Evidence-Driven Deterministic Refactoring'
  one_sentence: 투자 판단은 YAML 계약과 Python canonical 산출물로만 결정하고, GAS와 LLM은 계산하지 않는 입출력/렌더 계층으로 고정한다.
  core_equations:
    decision_equation: Decision = f(DataContract, FormulaRegistry, RiskPolicy, StrategyDAG, ExecutionContract, ProvenanceLedger)
    report_equation: Report = copy(FinalDecisionPacket, NumberProvenanceLedger, ShadowLedger)
    release_equation: Release_PASS = all(strict_gates) AND active_artifact_count_per_formula == 1 AND number_provenance_coverage_pct
      == 100 AND architecture_boundary_violations == 0
    new_rule_equation: NewRule = Contract + Schema + PythonImplementation + GoldenCases + ShadowLedger + Owner + RetirementCondition
  non_negotiable_locks:
  - spec/*.yaml이 최상위 source of truth다.
  - runtime/active_artifact_manifest.yaml은 현재 운영 권위의 라우터다.
  - Temp/final_decision_packet_active.json은 LLM과 리포트가 읽는 유일한 판단 패킷이다.
  - 모든 가격, 수량, TP, SL, 점수, 비중, 현금 부족액은 provenance가 있어야 한다.
  - D+2 현금은 즉시현금 방어선 충족으로 간주한다.
  - 매주 토/일은 rebalance_required=true, 매월 1일/11일/21일은 mid_check_required=true로 고정한다.
  - replay 성과와 live 성과는 절대 혼합하지 않는다.
  - blocked/limited 상태에서도 산출된 손절가, 익절가, 수량은 shadow ledger에 남긴다.
  anti_goals:
  - 문서 추가로 문제를 해결하지 않는다. 기존 권위 파일에 병합하거나 redirect-only index로 만든다.
  - 저성능 LLM에게 해석 재량을 주지 않는다. fixed-order context pack과 copy-only 템플릿만 제공한다.
  - GAS를 엔진으로 키우지 않는다. GAS는 수집, 시트 입출력, 어댑터로만 남긴다.
  - 실패한 검증을 예외 처리로 숨기지 않는다. shadow, review_only, blocked 중 하나로 명시한다.
  architecture_layers:
  - layer: 00_constitution
    canonical_path: AGENTS.md
    role: 운영 헌법 인덱스. 세부 규칙을 직접 품지 않고 권위 파일로 라우팅한다.
  - layer: 10_contracts
    canonical_path: spec/**/*.yaml
    role: 공식, 필드, 위험, 전략, 실행, 출력 계약의 원본 권위.
  - layer: 20_governance
    canonical_path: governance/**/*.yaml|md
    role: ADR, owner, rule lifecycle, change request, hash migration 관리.
  - layer: 30_python_canonical
    canonical_path: src/quant_engine/**/*.py
    role: 계산과 판단의 유일한 구현 계층.
  - layer: 40_tools_cli
    canonical_path: tools/**/*.py
    role: 검증/빌드/렌더 CLI wrapper. 핵심 로직 보유 금지.
  - layer: 50_gas_adapter
    canonical_path: gas_*.gs|src/gas_adapter_parts/*.gs
    role: 데이터 수집, 시트 I/O, Python 산출물 전달 어댑터.
  - layer: 60_runtime
    canonical_path: Temp/*.json|runtime/*.yaml|jsonl
    role: 빌드 산출물. 사람이 직접 편집하지 않는 읽기/검증 대상.
  - layer: 70_renderer
    canonical_path: prompts/*.md|Temp/operational_report.*
    role: copy-only 렌더. 숫자 계산과 판단 번복 금지.
  change_control_flow:
  - 'CR 작성: governance/change_requests/CR-YYYYMMDD-<slug>.yaml'
  - '권위 파일 결정: ownership_map과 xref_matrix로 owns/must_not_own 확인'
  - '계약 작성: spec에 입력/출력/단위/결측/임계값/우선순위 명시'
  - '스키마 작성 또는 갱신: schemas/*.schema.json'
  - 'Python canonical 구현: src/quant_engine에 순수 함수로 구현'
  - 'GAS 어댑터 연결: 계산하지 않고 산출물 전달만 수행'
  - golden/property/replay 테스트 추가
  - shadow ledger로 최소 1회 이상 운영 관측
  - '승격: active manifest에 단일 활성 버전만 등록'
  - '은퇴: 이전 버전은 archive 또는 deprecated index로 이동'
governance_scorecard:
  purpose: 리팩토링 품질을 주관이 아니라 수식으로 관리한다.
  score_formula: QEDD_R_Score = 0.20*Authority + 0.20*Coverage + 0.15*Provenance + 0.15*Boundary + 0.10*LowCapability + 0.10*Entropy
    + 0.10*Lifecycle
  component_formulas:
    Authority: 100 - 25*authority_collision_count - 10*stale_artifact_count - 10*active_version_collision_count
    Coverage: min(100, runtime_adjusted_coverage_pct) - 2*unmapped_formula_count
    Provenance: number_provenance_coverage_pct - 10*stale_critical_number_count - 10*unproven_report_number_count
    Boundary: 100 - 20*renderer_calculation_count - 20*reverse_dependency_count - 10*gas_business_logic_violation_count
    LowCapability: 100 - 10*missing_required_context_section_count - 10*freeform_number_count - 10*llm_math_violation_count
    Entropy: 100 - max(0,total_files-entropy_budget)*0.05 - 2*duplicate_active_family_count - 1*orphan_tool_count
    Lifecycle: 100 - 10*formula_without_owner_count - 10*formula_without_golden_case_count - 10*formula_without_retirement_condition_count
  minimum_release_thresholds:
    QEDD_R_Score: '>= 95'
    Authority: '>= 100 for release; any collision blocks release'
    Coverage: '>= 100 and unmapped_formula_count == 0'
    Provenance: == 100
    Boundary: == 100
    LowCapability: '>= 95'
    Entropy: '>= 85'
    Lifecycle: '>= 95'
  current_red_flags_to_resolve_first:
  - Temp/formula_runtime_registry_v1.json과 engine gate log의 coverage/gate 불일치
  - measure_yaml_gs_ps_coverage가 warn_only 실패로 존재함. release 모드에서는 fail-fast 여부를 결정해야 함
  - tools/*.py가 370개로 많다. core logic과 wrapper의 경계를 자동 감사해야 함
target_repository_shape:
  file_type_policy:
    .yaml: 계약, 설정, governance, todo, manifest 전용. 수치/공식 권위는 반드시 formula_id와 owner를 가진다.
    .md: 사람용 설명, ADR, runbook 전용. 중복 규칙/공식 기입 금지.
    .py: canonical 계산, 검증, CLI wrapper. 계산 로직은 src 우선, tools는 thin wrapper.
    .gs: Google Sheets/Apps Script 어댑터. 핵심 계산과 판단 금지.
  directory_policy:
    spec/: source of truth. 새 규칙은 이곳에 먼저 들어간다.
    src/quant_engine/: 계산 엔진. 데이터 입력을 받아 결정 패킷을 생성한다.
    tools/: 검증/빌드/렌더 실행기. 중복 build_*는 release_train으로 통합한다.
    governance/: ADR, change request, lifecycle, authority matrix.
    runtime/: active manifest, baseline, migration ledger, lineage.
    Temp/: 산출물. 직접 편집 금지. stale이면 clean/build로 재생성.
    prompts/: copy-only renderer prompt. 계산/판단/랭킹 금지.
    docs/: 최소 runbook과 doctrine. spec와 중복된 규칙 금지.
  diet_targets:
    max_total_files_release_budget: 2000
    target_spec_yaml_files_after_merge: <= 90 unless generated/registry reason exists
    target_tools_py_files_after_wrapper_merge: <= 180 active tools; archive or consolidate older build variants
    target_active_formula_versions: 1 active + 1 shadow maximum per formula family
    target_docs: AGENTS.md + doctrine + runbook + ADR only; repeated rules removed
refactor_waves:
- wave_id: W0
  name: 동결 및 단일 권위 확정
  goal: 지금부터 새 로직을 추가하기 전에 active source와 stale source를 분리한다.
  exit_gate: authority_collision_count == 0 AND stale_runtime_conflict_count == 0
- wave_id: W1
  name: 공식/팩터/필드 정규화
  goal: spec/13, field dictionary, formula lifecycle, factor lifecycle을 한 줄로 연결한다.
  exit_gate: formula_id, input_fields, output_fields, owner, golden_cases, retirement_condition 누락 0건
- wave_id: W2
  name: Python canonical 고정
  goal: 모든 계산 로직을 src/quant_engine 순수 함수로 귀속하고 tools/GAS 계산을 제거한다.
  exit_gate: gas_business_logic_violation_count == 0 AND tools_core_logic_violation_count == 0
- wave_id: W3
  name: 릴리즈 DAG 단일화
  goal: package.json 스크립트를 ops:*와 full-gate 중심으로 묶고, release DAG를 source of truth로 삼는다.
  exit_gate: release_dag_run returncode all 0 AND skipped_strict_gate_count == 0
- wave_id: W4
  name: 저성능 LLM 실행팩 완성
  goal: LLM에게 final_context와 fixed section만 주면 동일한 보고서가 나오도록 한다.
  exit_gate: missing_required_context_section_count == 0 AND freeform_number_count == 0
- wave_id: W5
  name: 성과/예측/팩터 생명주기
  goal: 팩터를 draft-shadow-candidate-active-retired로 관리하고 live/replay를 분리한다.
  exit_gate: live_replay_mix_count == 0 AND factor_without_shadow_evidence_count == 0
- wave_id: W6
  name: 문서/파일 다이어트
  goal: 중복 문서와 이전 버전 산출물을 정리해 저성능 LLM의 읽기 경로를 짧게 만든다.
  exit_gate: AGENTS routing length stable AND deprecated active references == 0
implementation_todo:
- phase_id: P0
  title: Freeze, inventory, authority lock
  why: 확장 전에 어떤 파일이 권위이고 어떤 파일이 산출물인지 고정하지 않으면 모든 개선이 파편화된다.
  tasks:
  - id: P0-T01
    priority: P0
    title: 현재 ZIP 스냅샷 고정
    owner: architect
    objective: 리팩토링 전 기준점을 만들고 모든 변경을 이 해시 기준으로 비교한다.
    files_to_touch:
    - runtime/refactor_baseline_v3.yaml
    - runtime/lineage_events.jsonl
    execution_steps_for_low_capability_llm:
    - data_feed.zip SHA256을 기록한다.
    - 총 파일 수, 확장자별 파일 수, Temp JSON 수, package scripts 수를 기록한다.
    - 기록 파일에 generated_at, source_zip_sha256, counts, tool_version을 남긴다.
    commands:
    - python tools/audit_repository_entropy_v2.py --out runtime/refactor_baseline_v3.yaml
    acceptance_criteria:
    - runtime/refactor_baseline_v3.yaml 존재
    - source_zip_sha256이 현재 zip hash와 일치
    - total_files가 release budget 이하
    forbidden_actions: &id001
    - Temp/*.json을 직접 편집하지 말 것
    - LLM이 가격/수량/점수/임계값을 즉석 계산하지 말 것
    - GAS에 신규 투자판단 비즈니스 로직을 추가하지 말 것
    - active artifact가 2개 이상 존재하도록 방치하지 말 것
    - 검증 실패를 warn_only로 낮춰 release 통과 처리하지 말 것
  - id: P0-T02
    priority: P0
    title: active artifact와 stale artifact 충돌 제거
    owner: architect
    objective: 운영 권위 파일과 stale Temp 파일이 서로 다른 PASS/FAIL을 말하지 않도록 한다.
    files_to_touch:
    - runtime/active_artifact_manifest.yaml
    - Temp/formula_runtime_registry_v1.json
    - Temp/engine_harness_gate_result.json
    execution_steps_for_low_capability_llm:
    - active manifest의 source_precedence를 읽는다.
    - 각 Temp artifact의 formula_id, generated_at, gate, input_hash를 표로 만든다.
    - 같은 formula_id 또는 같은 의미의 산출물이 서로 다른 gate를 보이면 stale_runtime_conflict로 기록한다.
    - stale 파일은 직접 수정하지 말고 재빌드 또는 archive 대상으로 표시한다.
    commands:
    - python tools/validate_active_manifest.py --manifest runtime/active_artifact_manifest.yaml --strict
    - python tools/build_formula_runtime_registry_v1.py --audit Temp/harness_coverage_audit.json --out Temp/formula_runtime_registry_v1.json
    acceptance_criteria:
    - active_count_per_formula == 1
    - stale_runtime_conflict_count == 0
    - engine gate log와 runtime file의 gate/coverage 불일치 0건
    blocks_release_when:
    - engine log PASS인데 artifact file FAIL인 경우 release block
    forbidden_actions: *id001
    target_metrics:
      stale_runtime_conflict_count: 0
  - id: P0-T03
    priority: P0
    title: warn_only 실패 정책 결정
    owner: qa
    objective: warn_only 실패가 운영결정에 영향을 주는지 분류하고 release에서는 fail-fast로 바꿀 대상을 결정한다.
    files_to_touch:
    - spec/41_release_dag.yaml
    - tools/run_release_dag_v3.py
    - Temp/engine_harness_gate_result.json
    execution_steps_for_low_capability_llm:
    - engine_harness_gate_result의 warn_only 체크를 모두 나열한다.
    - 투자판단/수치/권위/데이터정합성 관련이면 release mode에서 strict=true로 승격한다.
    - 단순 진단이면 advisory로 남기되 보고서에는 advisory로 표시한다.
    commands:
    - python tools/run_release_dag_v3.py --mode release --strict
    acceptance_criteria:
    - release_critical_warn_only_count == 0
    - advisory_warn_only_count는 별도 section으로 출력
    - measure_yaml_gs_ps_coverage의 처리정책 명시
    forbidden_actions: *id001
  - id: P0-T04
    priority: P0
    title: 읽기 순서 2단계로 축소
    owner: pm
    objective: 저성능 LLM이 AGENTS → active manifest → final context만 읽도록 경로를 줄인다.
    files_to_touch:
    - AGENTS.md
    - spec/46_low_capability_execution_pack.yaml
    - Temp/final_context_for_llm_v5.yaml
    execution_steps_for_low_capability_llm:
    - AGENTS.md에 긴 규칙을 추가하지 않는다.
    - 저성능 LLM용 읽기 순서를 1) AGENTS 2) active manifest 3) final_context로 제한한다.
    - final_context 안에 필요한 blockers/action_table/shadow_ledger/data_missing을 모두 포함한다.
    commands:
    - python tools/build_final_context_for_llm_v5.py
    - python tools/validate_low_capability_pack_v1.py --context Temp/final_context_for_llm_v5.yaml --contract spec/46_low_capability_execution_pack.yaml
    acceptance_criteria:
    - required_sections 모두 존재
    - LLM이 spec 전체를 재탐색하지 않아도 보고 가능
    - freeform number field 없음
    forbidden_actions: *id001
- phase_id: P1
  title: Contract-first normalization
  why: 공식, 필드, 위험, 실행, 보고 계약이 분리되어 있어도 formula_id와 owner가 하나로 연결되어야 판단이 흔들리지 않는다.
  tasks:
  - id: P1-T01
    priority: P1
    title: formula registry를 lifecycle registry와 1:1 연결
    owner: quant_architect
    objective: 모든 formula_id가 owner, runtime, schema, golden_case, retirement_condition을 가진다.
    files_to_touch:
    - spec/13_formula_registry.yaml
    - spec/51_formula_lifecycle_registry.yaml
    - spec/formula_lifecycle_index.yaml
    - spec/03_formulas/output_field_owner_ledger.yaml
    execution_steps_for_low_capability_llm:
    - spec/13_formula_registry.yaml의 formula_id 전체를 추출한다.
    - 각 formula_id가 lifecycle registry에 있는지 확인한다.
    - 누락된 owner, lifecycle_state, activation_threshold, retirement_condition을 TODO로 생성한다.
    - 활성 공식은 active 1개, shadow 1개 이하로 제한한다.
    commands:
    - python tools/validate_formula_lifecycle_registry_v1.py
    - python tools/validate_formula_runtime_registry_v1.py
    acceptance_criteria:
    - formula_without_owner_count == 0
    - formula_without_retirement_condition_count == 0
    - active_versions_per_formula <= 1
    - shadow_versions_per_formula <= 1
    forbidden_actions: *id001
  - id: P1-T02
    priority: P1
    title: field dictionary를 모든 입출력의 단일 사전으로 승격
    owner: data_owner
    objective: 필드명 alias/단위/결측 정책 불일치를 제거한다.
    files_to_touch:
    - spec/12_field_dictionary.yaml
    - spec/fields/field_dictionary.yaml
    - spec/14_raw_workbook_mapping.yaml
    - spec/15_account_snapshot_contract.yaml
    execution_steps_for_low_capability_llm:
    - formula registry의 input/output 필드명을 모두 수집한다.
    - field dictionary에 없는 필드를 missing_field_dictionary로 기록한다.
    - alias는 spec/aliases.yaml에만 둔다.
    - 계좌 캡처 필드는 account_snapshot_contract가 소유하게 한다.
    commands:
    - python tools/validate_field_dictionary.py
    - python tools/validate_raw_workbook_mapping_v1.py
    acceptance_criteria:
    - missing_field_dictionary_count == 0
    - unit_missing_count == 0
    - alias_collision_count == 0
    forbidden_actions: *id001
  - id: P1-T03
    priority: P1
    title: ownership_map과 xref_matrix 강제 적용
    owner: architect
    objective: 규칙 중복과 순환 참조를 빌드 단계에서 차단한다.
    files_to_touch:
    - spec/ownership_map.yaml
    - spec/xref_matrix.yaml
    - tools/validate_specs.py
    execution_steps_for_low_capability_llm:
    - 변경 대상 파일의 owns/must_not_own을 먼저 확인한다.
    - must_not_own 위반이면 변경을 중단한다.
    - xref_matrix 외 참조는 warning, critical 파일 위반은 fail로 처리한다.
    commands:
    - python tools/validate_specs.py
    acceptance_criteria:
    - must_not_own_violation_count == 0
    - critical_xref_violation_count == 0
    forbidden_actions: *id001
  - id: P1-T04
    priority: P1
    title: 공식 도메인 분할 재정렬
    owner: quant_architect
    objective: cash/risk/entry/exit/fundamental/smart_money/macro/reporting 도메인별로 공식 책임을 고정한다.
    files_to_touch:
    - spec/formulas/domains/*.yaml
    - spec/13_formula_registry.yaml
    execution_steps_for_low_capability_llm:
    - 각 formula_id에 domain을 1개만 부여한다.
    - 도메인 파일은 canonical formula registry를 재정의하지 않고 subset index 역할만 한다.
    - 동일 임계값이 여러 도메인에 반복되면 canonical owner만 남기고 나머지는 reference로 바꾼다.
    commands:
    - python tools/build_formula_registry_normalized.py
    - python tools/validate_formula_registry_sync_v1.py
    acceptance_criteria:
    - formula_domain_missing_count == 0
    - duplicate_threshold_definition_count == 0
    - registry_normalization_gate == PASS
    forbidden_actions: *id001
- phase_id: P2
  title: Python canonical engine consolidation
  why: 계산 로직의 중심이 Python package에 있어야 GAS/LLM/문서가 흔들리지 않는다.
  tasks:
  - id: P2-T01
    priority: P1
    title: tools의 핵심 로직을 src/quant_engine으로 이동
    owner: developer
    objective: tools는 wrapper, src는 business logic이라는 경계를 강제한다.
    files_to_touch:
    - src/quant_engine/**/*.py
    - tools/**/*.py
    - spec/34_architecture_boundaries.yaml
    execution_steps_for_low_capability_llm:
    - tools/build_*.py에서 순수 계산 함수가 30줄 이상이면 src/quant_engine 모듈로 이동 후보로 표시한다.
    - tools 파일은 argparse, 파일 I/O, 함수 호출만 남긴다.
    - 이동 후 import 경로와 테스트를 갱신한다.
    commands:
    - python tools/audit_tools_thin_wrapper_v1.py --out Temp/tools_thin_wrapper_audit_v1.json
    - python tools/validate_architecture_boundaries_v2.py
    acceptance_criteria:
    - tools_core_logic_violation_count == 0
    - src_owned_formula_impl_pct == 100
    - 기존 output hash 동일
    forbidden_actions: *id001
  - id: P2-T02
    priority: P1
    title: 순수 함수 계약 통일
    owner: developer
    objective: 모든 공식 구현이 같은 함수 서명을 갖도록 한다.
    files_to_touch:
    - src/quant_engine/core/formulas/**/*.py
    - spec/13_formula_registry.yaml
    - schemas/generated/*.schema.json
    execution_steps_for_low_capability_llm:
    - '각 공식 구현을 evaluate(inputs: Mapping[str, Any]) -> FormulaResult 형태로 표준화한다.'
    - FormulaResult는 value, gate, reasons, provenance, input_hash를 가진다.
    - 예외 발생 시 DATA_MISSING 또는 BLOCKED reason으로 반환하고 임의 기본값을 만들지 않는다.
    commands:
    - python tools/validate_formula_contract_signatures_v1.py
    - python tools/run_formula_golden_cases_v2.py
    acceptance_criteria:
    - signature_violation_count == 0
    - golden_case_pass_pct == 100
    - missing policy 위반 0건
    forbidden_actions: *id001
  - id: P2-T03
    priority: P1
    title: schema/model parity 자동 생성
    owner: developer
    objective: schemas와 Python models가 항상 같은 shape를 갖도록 만든다.
    files_to_touch:
    - schemas/*.schema.json
    - src/quant_engine/models/generated/*.py
    - tools/generate_models_from_schema.py
    execution_steps_for_low_capability_llm:
    - schema를 수정하면 generated model을 재생성한다.
    - generated 파일은 사람이 직접 편집하지 않는다.
    - schema hash를 model header에 기록한다.
    commands:
    - python tools/validate_schema_model_generation_v1.py
    acceptance_criteria:
    - schema_model_parity_pct == 100
    - manual_generated_edit_count == 0
    forbidden_actions: *id001
  - id: P2-T04
    priority: P1
    title: 계산 결과 패킷 하나로 병합
    owner: developer
    objective: 중간 산출물이 늘어도 최종 판단은 final_decision_packet_active 하나로 모인다.
    files_to_touch:
    - src/quant_engine/compute_formula_outputs.py
    - src/quant_engine/inject_computed_harness.py
    - tools/build_final_decision_packet_v4.py
    - Temp/final_decision_packet_active.json
    execution_steps_for_low_capability_llm:
    - Data -> Feature -> Decision -> Execution -> Report 순서로만 값을 전달한다.
    - renderer가 core를 호출하지 않도록 import graph를 검사한다.
    - final packet에 모든 report number의 source_path/json_pointer/formula_id를 포함한다.
    commands:
    - python tools/build_final_decision_packet_v4.py
    - python tools/validate_report_packet_sync_v1.py --packet Temp/final_decision_packet_active.json --report Temp/operational_report.json
    acceptance_criteria:
    - report_authority_diff_count == 0
    - renderer_calculation_count == 0
    - final_packet_schema_valid == true
    forbidden_actions: *id001
- phase_id: P3
  title: GAS thin adapter migration
  why: GAS는 운영상 필요하지만 투자 판단 로직이 들어가면 Python canonical과 충돌한다.
  tasks:
  - id: P3-T01
    priority: P1
    title: GAS business logic 감사
    owner: developer
    objective: gas_*.gs와 src/gas_adapter_parts의 계산/판단 로직을 찾고 Python으로 이동시킨다.
    files_to_touch:
    - gas_*.gs
    - src/gas_adapter_parts/*.gs
    - governance/gas_logic_migration_ledger_v1.yaml
    execution_steps_for_low_capability_llm:
    - GAS 함수 중 score, gate, risk, sizing, stop, target, rank, decision 키워드를 포함한 로직을 스캔한다.
    - 이미 Python으로 이관된 로직은 migration ledger에 migrated로 표시한다.
    - 남은 로직은 adapter_allowed 또는 migrate_required로 분류한다.
    commands:
    - python tools/audit_gas_business_logic_v1.py --out Temp/gas_business_logic_audit_v1.json
    - python tools/validate_gas_thin_adapter_v1.py
    acceptance_criteria:
    - gas_business_logic_violation_count == 0
    - migrate_required_count == 0
    - adapter_allowed_functions documented
    forbidden_actions: *id001
  - id: P3-T02
    priority: P1
    title: GAS 입출력 계약 고정
    owner: developer
    objective: GAS가 시트에서 읽고 쓰는 범위를 계약화해 시트 드리프트를 막는다.
    files_to_touch:
    - spec/14_raw_workbook_mapping.yaml
    - spec/15_account_snapshot_contract.yaml
    - schemas/generated/gas_adapter_contract.schema.json
    execution_steps_for_low_capability_llm:
    - GAS가 읽는 시트명/컬럼명/범위를 mapping에 등록한다.
    - GAS 출력 key가 final packet에 들어가는 경로를 명시한다.
    - 누락 컬럼은 DATA_MISSING으로 올리고 계산으로 보정하지 않는다.
    commands:
    - python tools/validate_gas_adapter_contract_v1.py
    acceptance_criteria:
    - unmapped_gas_read_count == 0
    - unmapped_gas_write_count == 0
    - sheet_contract_drift_count == 0
    forbidden_actions: *id001
  - id: P3-T03
    priority: P1
    title: Apps Script 배포 단위 축소
    owner: developer
    objective: 큰 GAS 파일을 기능별 adapter part로 유지하고 bundle 생성만 자동화한다.
    files_to_touch:
    - src/gas_adapter_parts/*.gs
    - tools/build_gas_bundle_v1.py
    - gas_lib.gs
    execution_steps_for_low_capability_llm:
    - src/gas_adapter_parts를 canonical으로 둔다.
    - gas_lib.gs는 generated bundle이면 header에 generated 표시를 넣는다.
    - 사람은 part 파일만 수정한다.
    commands:
    - python tools/build_gas_bundle_v1.py
    - python tools/validate_gas_bundle_sync_v1.py
    acceptance_criteria:
    - bundle_sync_hash_match == true
    - manual_edit_generated_bundle_count == 0
    forbidden_actions: *id001
- phase_id: P4
  title: Deterministic release DAG and validation harness
  why: 저성능 LLM도 명령 순서만 따라가면 같은 결과가 나오려면 release DAG가 절대 기준이어야 한다.
  tasks:
  - id: P4-T01
    priority: P1
    title: release DAG를 유일한 실행 순서로 승격
    owner: pm
    objective: package.json 스크립트와 README 명령을 spec/41_release_dag.yaml에 종속시킨다.
    files_to_touch:
    - spec/41_release_dag.yaml
    - package.json
    - README.md
    execution_steps_for_low_capability_llm:
    - README에는 npm run full-gate만 기본 명령으로 안내한다.
    - package.json의 스크립트는 DAG 노드 호출 wrapper로 유지한다.
    - 새 검증은 package.json에 먼저 넣지 말고 release_dag node로 등록한다.
    commands:
    - python tools/validate_release_dag_contract_v1.py
    - npm run full-gate
    acceptance_criteria:
    - dag_node_count == package_script_reachable_node_count
    - orphan_script_count == 0
    - release_dag_run returncode 0
    forbidden_actions: *id001
  - id: P4-T02
    priority: P1
    title: strict/review/package-only 모드 분리
    owner: qa
    objective: 운영 의사결정 모드와 단순 패키징 모드를 혼동하지 않게 한다.
    files_to_touch:
    - tools/prepare_upload_zip.py
    - spec/22_pipeline_runtime_contract.yaml
    - Temp/pipeline_runtime_profile_v1.json
    execution_steps_for_low_capability_llm:
    - release 모드는 skip_validate를 허용하지 않는다.
    - package-only는 gate_status=SKIPPED를 명시하고 투자 판단에는 사용하지 않는다.
    - runtime profile에 validation_mode와 allowed_use를 기록한다.
    commands:
    - python tools/prepare_upload_zip.py --validation-mode release --profile
    - python tools/validate_pipeline_runtime_contract.py
    acceptance_criteria:
    - release_mode_skip_validate_count == 0
    - package_only_used_for_investment_decision_count == 0
    forbidden_actions: *id001
  - id: P4-T03
    priority: P1
    title: golden/property/replay/live 4중 테스트 피라미드
    owner: qa
    objective: 공식 정확도와 투자 판단 안정성을 같은 게이트에서 본다.
    files_to_touch:
    - spec/formula_golden_cases_v4.yaml
    - spec/property_invariants.yaml
    - spec/29_backtest_harness_contract.yaml
    - spec/44_live_replay_separation.yaml
    execution_steps_for_low_capability_llm:
    - 단일 공식은 golden test로 검증한다.
    - 위험 단조성은 property invariant로 검증한다.
    - 과거 재현은 replay로 검증하되 live와 절대 섞지 않는다.
    - live sample은 최소 표본 수와 기간이 차기 전 active 승격 금지.
    commands:
    - python tools/validate_golden_coverage_100.py
    - python tools/validate_property_invariants_v1.py
    - python tools/validate_no_replay_live_mix_v2.py --json Temp/live_replay_separation_v3.json --strict
    acceptance_criteria:
    - golden_coverage_pct == 100
    - property_invariant_fail_count == 0
    - live_replay_mix_count == 0
    forbidden_actions: *id001
  - id: P4-T04
    priority: P0
    title: 산출물 동기화 강제 검사
    owner: qa
    objective: 로그는 PASS인데 파일은 FAIL인 상태를 릴리즈에서 차단한다.
    files_to_touch:
    - tools/validate_artifact_sync_v1.py
    - Temp/*.json
    - runtime/active_artifact_manifest.yaml
    execution_steps_for_low_capability_llm:
    - engine gate output에 등장한 주요 artifact path를 추출한다.
    - 각 artifact 파일의 formula_id, gate, generated_at, input_hash를 읽는다.
    - 로그 값과 파일 값이 다르면 ARTIFACT_SYNC_FAIL로 차단한다.
    commands:
    - python tools/validate_artifact_sync_v1.py --engine-result Temp/engine_harness_gate_result.json --manifest runtime/active_artifact_manifest.yaml
    acceptance_criteria:
    - artifact_sync_mismatch_count == 0
    - stale_artifact_count == 0
    forbidden_actions: *id001
- phase_id: P5
  title: Low-capability LLM execution pack
  why: LLM 성능 차이를 없애려면 모델이 생각하지 않고 체크리스트와 패킷만 복사하게 해야 한다.
  tasks:
  - id: P5-T01
    priority: P1
    title: final_context_for_llm_v5 고정 섹션 생성
    owner: pm
    objective: 저성능 LLM용 입력을 고정 순서의 작은 YAML로 만든다.
    files_to_touch:
    - spec/46_low_capability_execution_pack.yaml
    - Temp/final_context_for_llm_v5.yaml
    - tools/build_final_context_for_llm_v5.py
    execution_steps_for_low_capability_llm:
    - required_sections 순서를 executive, blockers, action_table, shadow_ledger, data_missing, education_notes로 고정한다.
    - 각 숫자에는 source_path와 json_pointer를 붙인다.
    - LLM에게 계산 지시가 필요한 문장을 제거한다.
    commands:
    - python tools/build_final_context_for_llm_v5.py
    - python tools/validate_low_capability_pack_v1.py --context Temp/final_context_for_llm_v5.yaml --contract spec/46_low_capability_execution_pack.yaml
    acceptance_criteria:
    - required_section_missing_count == 0
    - numeric_without_provenance_count == 0
    - context_size_within_budget == true
    forbidden_actions: *id001
  - id: P5-T02
    priority: P1
    title: copy-only report renderer 템플릿 잠금
    owner: pm
    objective: 보고서 문체가 달라도 결론과 숫자는 동일하게 만든다.
    files_to_touch:
    - prompts/low_capability_report_renderer.md
    - spec/31_low_capability_llm_response_contract.yaml
    - tools/validate_report_quality.py
    execution_steps_for_low_capability_llm:
    - 필수 섹션명을 고정한다.
    - blocked 상태에서는 HTS 주문표와 신규매수 추천 섹션을 금지한다.
    - 숫자는 {{json_path}} placeholder만 허용한다.
    commands:
    - python tools/validate_low_capability_report_prompt_v1.py
    - python tools/validate_report_quality.py
    acceptance_criteria:
    - freeform_number_count == 0
    - forbidden_section_when_blocked_count == 0
    - section_order_match == true
    forbidden_actions: *id001
  - id: P5-T03
    priority: P1
    title: LLM 판단 번복 방지 테스트
    owner: qa
    objective: LLM output이 final packet의 action을 바꾸면 실패시킨다.
    files_to_touch:
    - tools/validate_llm_copy_only_output_v1.py
    - Temp/operational_report.json
    - Temp/final_decision_packet_active.json
    execution_steps_for_low_capability_llm:
    - final packet의 ticker별 final_action을 읽는다.
    - operational_report.json의 ticker별 action과 비교한다.
    - LLM 문장에 완화 표현이 있어도 action 불일치면 실패한다.
    commands:
    - python tools/validate_llm_copy_only_output_v1.py --packet Temp/final_decision_packet_active.json --report Temp/operational_report.json
    acceptance_criteria:
    - action_diff_count == 0
    - numeric_diff_count == 0
    - narrative_override_count == 0
    forbidden_actions: *id001
  - id: P5-T04
    priority: P1
    title: 저성능 LLM 운영용 12단계 절차 삽입
    owner: pm
    objective: 모델이 길을 잃지 않도록 실행 순서를 TODO로 박아둔다.
    files_to_touch:
    - spec/23_low_capability_llm_pipeline_todo.yaml
    - prompts/engine_audit_master_prompt_v3.md
    execution_steps_for_low_capability_llm:
    - 1 AGENTS 읽기
    - 2 active manifest 읽기
    - 3 final_context 읽기
    - 4 engine gate status 확인
    - 5 blockers 먼저 출력
    - 6 allowed/blocked actions 복사
    - 7 shadow ledger 복사
    - 8 data_missing 복사
    - 9 숫자 provenance 확인
    - 10 자유 계산 제거
    - 11 report contract 검증
    - 12 실패 시 DATA_MISSING 또는 REVIEW_ONLY로 종료
    commands:
    - python tools/validate_low_capability_pipeline_todo_v2.py
    acceptance_criteria:
    - low_capability_step_count >= 12
    - ambiguous_instruction_count == 0
    - calculation_instruction_count == 0
    forbidden_actions: *id001
- phase_id: P6
  title: Quant factor lifecycle and anti-late-entry hardening
  why: 좋은 퀀트 엔진은 새 팩터를 많이 넣는 엔진이 아니라, 팩터의 수명과 성과증거를 냉정하게 관리하는 엔진이다.
  tasks:
  - id: P6-T01
    priority: P1
    title: 팩터 승격 기준 표준화
    owner: quant_architect
    objective: draft 팩터를 바로 active로 쓰지 못하게 막는다.
    files_to_touch:
    - spec/43_quant_factor_taxonomy.yaml
    - spec/factor_lifecycle_registry.yaml
    - tools/validate_factor_lifecycle_registry_v1.py
    execution_steps_for_low_capability_llm:
    - 각 factor에 hypothesis, horizon, decay_half_life, expected_edge_formula, conflict_precedence를 채운다.
    - golden_cases 없으면 active 불가로 둔다.
    - shadow 기간 동안 live/replay 지표를 따로 기록한다.
    commands:
    - python tools/validate_factor_lifecycle_registry_v1.py
    acceptance_criteria:
    - factor_required_field_missing_count == 0
    - active_factor_without_shadow_evidence_count == 0
    forbidden_actions: *id001
  - id: P6-T02
    priority: P0
    title: anti-late-entry를 최상위 진입 게이트로 고정
    owner: quant_architect
    objective: 뒷북 매수/설거지 매수 방지 게이트를 모든 BUY/STAGED_BUY보다 먼저 태운다.
    files_to_touch:
    - spec/strategy/anti_late_entry_pullback_gate_v5.yaml
    - spec/09_decision_flow.yaml
    - spec/routing/decision_graph.yaml
    execution_steps_for_low_capability_llm:
    - BUY 또는 STAGED_BUY 후보가 나오면 anti_late_entry gate를 먼저 평가한다.
    - gate가 FAIL이면 매수 수량은 0, action은 WATCH 또는 BLOCKED로 강등한다.
    - gate 이유와 기준값은 shadow ledger에 남긴다.
    commands:
    - python tools/validate_anti_late_entry_gate_v5.py
    - python tools/validate_decision_graph_precedence_v1.py
    acceptance_criteria:
    - buy_without_anti_late_gate_count == 0
    - late_entry_fail_quantity_nonzero_count == 0
    forbidden_actions: *id001
  - id: P6-T03
    priority: P1
    title: 분배/스마트머니/유동성 팩터 충돌 우선순위 고정
    owner: quant_architect
    objective: 상승 추세와 분배 위험이 충돌할 때 팔지/버틸지 규칙을 수치화한다.
    files_to_touch:
    - spec/strategy/pre_distribution_early_warning_v4.yaml
    - spec/strategy/smart_money_liquidity_gate_v1.yaml
    - spec/09_decision_flow.yaml
    execution_steps_for_low_capability_llm:
    - 분배 위험, 스마트머니 유입, 거래대금, 상대강도, 갭 상승/하락을 각각 factor로 유지한다.
    - 'conflict_precedence: risk_exit > cash_floor > anti_late_entry > smart_money > momentum 순으로 둔다.'
    - conflict 발생 시 final_action 변경 이유를 gate_trace에 기록한다.
    commands:
    - python tools/validate_factor_conflict_precedence_v1.py
    acceptance_criteria:
    - conflict_without_precedence_count == 0
    - gate_trace_missing_count == 0
    forbidden_actions: *id001
  - id: P6-T04
    priority: P1
    title: 성과 피드백을 팩터별로 분리
    owner: qa
    objective: 전체 승률 하나로 엔진을 평가하지 않고 팩터별 기여도를 본다.
    files_to_touch:
    - tools/build_alpha_feedback_loop_v2.py
    - spec/17_performance_contract.yaml
    - Temp/prediction_accuracy_harness_v2.json
    execution_steps_for_low_capability_llm:
    - ticker별 예측, action, horizon, factor set, outcome을 저장한다.
    - T+5/T+20/T+60 결과를 horizon별로 분리한다.
    - 표본 수 30 미만은 active 승격 근거로 쓰지 않는다.
    commands:
    - python tools/build_alpha_feedback_loop_v2.py
    - python tools/validate_honest_performance_guard_v1.py
    acceptance_criteria:
    - factor_outcome_join_rate_pct >= 95
    - live_sample_under_30_unlock_count == 0
    - replay_live_mixed_metric_count == 0
    forbidden_actions: *id001
- phase_id: P7
  title: Portfolio/risk/execution hard locks
  why: 수익률을 올리는 것보다 수익금을 지키는 엔진이 우선이다. 위험 게이트는 전략 게이트보다 앞서야 한다.
  tasks:
  - id: P7-T01
    priority: P0
    title: 현금 방어선과 D+2 cash 정책 검증
    owner: risk_officer
    objective: 현금 부족 상태에서는 신규 매수를 차단하고 매도/축소 액션만 허용한다.
    files_to_touch:
    - spec/risk/portfolio_exposure.yaml
    - spec/36_goal_risk_budget_harness.yaml
    - spec/15_account_snapshot_contract.yaml
    execution_steps_for_low_capability_llm:
    - available_cash와 D+2 cash를 분리 수집한다.
    - D+2 현금은 즉시현금 방어선 충족으로 인정한다.
    - cash_floor 미달이면 BUY/STAGED_BUY 차단, TRIM/HOLD/EXIT만 허용한다.
    commands:
    - python tools/build_goal_risk_budget_harness_v3.py
    - python tools/validate_cash_floor_policy_v1.py
    acceptance_criteria:
    - cash_floor_violation_buy_count == 0
    - d_plus_2_cash_policy_applied == true
    forbidden_actions: *id001
  - id: P7-T02
    priority: P1
    title: 목표금액 5억 기반 risk budget cascade
    owner: risk_officer
    objective: 총자산이 목표금액까지 가는 동안 포지션 사이징과 손실 허용치를 계단식으로 관리한다.
    files_to_touch:
    - spec/01_objective_profile.yaml
    - spec/05_position_sizing.yaml
    - spec/risk/aggregate_risk.yaml
    execution_steps_for_low_capability_llm:
    - objective_profile의 target_asset_krw를 500000000으로 고정한다.
    - 목표 대비 진행률 구간별 max heat, max sector exposure, max single position risk를 둔다.
    - 현금 부족 또는 drawdown 발생 시 risk budget을 자동 축소한다.
    commands:
    - python tools/build_goal_risk_budget_harness_v3.py
    - python tools/validate_position_sizing.py
    acceptance_criteria:
    - target_asset_krw == 500000000
    - risk_budget_monotonicity_pass == true
    - position_size_provenance_pct == 100
    forbidden_actions: *id001
  - id: P7-T03
    priority: P0
    title: 손절/익절/트레일링 stop 단일 waterfall
    owner: risk_officer
    objective: 다중 조건 주문문을 없애고 sell priority table로 선형화한다.
    files_to_touch:
    - spec/06_exit_policy.yaml
    - spec/exit/stop_loss.yaml
    - spec/exit/take_profit.yaml
    - spec/33_execution_precedence_lock.yaml
    execution_steps_for_low_capability_llm:
    - sell 후보가 2개 이상이면 sell priority table을 먼저 만든다.
    - STOP > CASH_FLOOR > DISTRIBUTION > VALUE_PRESERVE_TRIM > TAKE_PROFIT > HOLD 순서를 고정한다.
    - 각 매도 후보는 단일 reason_code 하나로 주문문을 만든다.
    commands:
    - python tools/validate_execution_precedence_lock_v1.py
    - python tools/validate_order_grammar_v1.py
    acceptance_criteria:
    - multi_condition_order_sentence_count == 0
    - sell_priority_missing_when_candidates_ge_2 == 0
    forbidden_actions: *id001
  - id: P7-T04
    priority: P1
    title: 운영 cadence 자동 플래그
    owner: pm
    objective: 주말 리밸런싱과 1/11/21 중간점검을 놓치지 않는다.
    files_to_touch:
    - spec/operating_cadence.yaml
    - tools/build_operating_cadence_flags_v1.py
    - Temp/final_context_for_llm_v5.yaml
    execution_steps_for_low_capability_llm:
    - Asia/Seoul 기준 날짜를 사용한다.
    - 토/일이면 rebalance_required=true를 packet에 넣는다.
    - 매월 1/11/21이면 mid_check_required=true를 packet에 넣는다.
    - 두 플래그는 보고서 상단에 표시한다.
    commands:
    - python tools/build_operating_cadence_flags_v1.py
    - python tools/validate_operating_cadence_v1.py
    acceptance_criteria:
    - weekend_rebalance_flag_accuracy_pct == 100
    - mid_check_flag_accuracy_pct == 100
    forbidden_actions: *id001
- phase_id: P8
  title: Repository diet and version retirement
  why: 파일이 많아질수록 저성능 LLM은 권위를 놓친다. active/read path를 짧게 유지해야 한다.
  tasks:
  - id: P8-T01
    priority: P1
    title: 버전 스프롤 은퇴 계획 실행
    owner: architect
    objective: v1/v2/v3가 동시에 보이는 파일군을 active/shadow/archive로 정리한다.
    files_to_touch:
    - spec/release/version_retirement_policy.yaml
    - runtime/rollback_manifest_v4.yaml
    - artifacts/archive/**
    execution_steps_for_low_capability_llm:
    - 파일명 *_vN family를 탐지한다.
    - active manifest에 없는 이전 버전은 archive 후보로 둔다.
    - generated/backtest 예외는 version_retirement_policy exceptions에 있어야 보존한다.
    commands:
    - python tools/audit_version_sprawl_v1.py --out Temp/version_sprawl_audit_v1.json
    - python tools/build_artifact_retirement_plan_v1.py
    acceptance_criteria:
    - active_versions_per_family <= 1
    - shadow_versions_per_family <= 1
    - orphan_legacy_reference_count == 0
    forbidden_actions: *id001
  - id: P8-T02
    priority: P1
    title: '문서 다이어트: AGENTS는 인덱스만'
    owner: pm
    objective: AGENTS.md를 더 길게 만들지 않고 상세 규칙은 spec/governance로 보낸다.
    files_to_touch:
    - AGENTS.md
    - docs/doctrine.md
    - docs/runbook.md
    - governance/adr/*.md
    execution_steps_for_low_capability_llm:
    - AGENTS.md에는 우선순위, 읽기 순서, hard rule summary, critical files만 둔다.
    - 중복 상세 규칙은 spec로 이동하고 AGENTS에는 링크만 둔다.
    - docs는 사람이 이해할 정도만 남기고 공식/임계값은 spec로 옮긴다.
    commands:
    - python tools/validate_agents_shrink_v1.py
    - python tools/validate_docs_no_formula_duplication_v1.py
    acceptance_criteria:
    - agents_line_count_within_budget == true
    - docs_formula_duplication_count == 0
    forbidden_actions: *id001
  - id: P8-T03
    priority: P1
    title: tools 통폐합과 CLI naming 표준화
    owner: developer
    objective: build_*.py 폭증을 줄이고 release_train으로 묶는다.
    files_to_touch:
    - tools/*.py
    - src/quant_engine/refactor_master_helpers.py
    - package.json
    execution_steps_for_low_capability_llm:
    - 같은 formula family의 build_v1/v2/v3는 active builder 1개와 archived builder로 나눈다.
    - CLI 이름은 build/validate/audit/render/clean 중 하나로 시작한다.
    - 직접 호출 대신 npm ops:* 또는 release DAG로 호출한다.
    commands:
    - python tools/audit_repository_entropy_v2.py
    - python tools/audit_orphan_tools_v1.py
    acceptance_criteria:
    - orphan_tool_count == 0
    - duplicate_builder_family_active_count == 0
    - package_script_count_within_budget == true
    forbidden_actions: *id001
  - id: P8-T04
    priority: P1
    title: zip whitelist와 packaging policy 정비
    owner: pm
    objective: 업로드 ZIP에 필요한 source/runtime/report/test만 들어가게 한다.
    files_to_touch:
    - spec/47_packaging_policy.yaml
    - tools/prepare_upload_zip.py
    - runtime/active_artifact_manifest.yaml
    execution_steps_for_low_capability_llm:
    - source_required/runtime_required/report_required/test_required 목록을 명시한다.
    - archive와 backup은 기본 제외한다.
    - include_xlsx/include_backups는 명시 옵션일 때만 허용한다.
    commands:
    - python tools/prepare_upload_zip.py --validation-mode release --profile
    - python tools/validate_packaging_policy_v1.py
    acceptance_criteria:
    - zip_contains_required_count == required_count
    - zip_contains_backup_count == 0
    - package_profile_gate == OK
    forbidden_actions: *id001
- phase_id: P9
  title: Continuous operation and PM cadence
  why: 엔진은 한 번 고치는 것이 아니라 매주 운영성과와 변경 위험을 같이 관리해야 한다.
  tasks:
  - id: P9-T01
    priority: P1
    title: 주간 엔진 리뷰 템플릿 자동화
    owner: pm
    objective: 매주 리밸런싱 때 엔진 품질, 투자 성과, 데이터 결함을 같이 점검한다.
    files_to_touch:
    - governance/weekly_engine_review_template.md
    - Temp/operational_report.json
    - Temp/engine_health_card_v2.json
    execution_steps_for_low_capability_llm:
    - portfolio health, blocked reasons, cash floor, prediction accuracy, failed gates, stale artifacts를 한 장 카드로 만든다.
    - 주말에는 rebalance_required와 함께 다음 주 액션 플레이북을 출력한다.
    commands:
    - python tools/build_engine_health_card_v2.py
    - python tools/validate_engine_health_card_v1.py
    acceptance_criteria:
    - engine_health_card_schema_valid == true
    - weekly_review_sections_complete == true
    forbidden_actions: *id001
  - id: P9-T02
    priority: P1
    title: change request SLA와 owner ledger 운영
    owner: pm
    objective: 새 요청을 바로 코드로 넣지 않고 CR, owner, impact, rollback을 먼저 만든다.
    files_to_touch:
    - governance/change_request_template.yaml
    - governance/change_requests/*.yaml
    - governance/authority_matrix.yaml
    execution_steps_for_low_capability_llm:
    - 사용자 요청을 CR로 분해한다.
    - '영향 범위: contract/schema/python/gas/report/test/package 중 체크한다.'
    - rollback 조건과 검증 명령을 적는다.
    - owner 승인 전 active 승격 금지.
    commands:
    - python tools/validate_change_requests_v1.py
    acceptance_criteria:
    - change_request_missing_owner_count == 0
    - change_request_missing_rollback_count == 0
    forbidden_actions: *id001
  - id: P9-T03
    priority: P1
    title: 라인리지 이벤트 원장화
    owner: qa
    objective: 모든 빌드와 릴리즈 결과를 jsonl로 추적한다.
    files_to_touch:
    - runtime/lineage_events.jsonl
    - tools/build_lineage_event_v1.py
    execution_steps_for_low_capability_llm:
    - 각 실행마다 event_id, input_hash, output_hash, command, gate, elapsed_sec, actor를 기록한다.
    - 동일 input hash에서 output hash가 바뀌면 nondeterminism alert를 낸다.
    commands:
    - python tools/validate_lineage_events_v1.py
    acceptance_criteria:
    - lineage_schema_valid_pct == 100
    - same_input_different_output_count == 0
    forbidden_actions: *id001
  - id: P9-T04
    priority: P1
    title: 운영 실패 triage playbook
    owner: pm
    objective: 검증 실패 때 저성능 LLM이 임의 해결하지 않고 정해진 절차로 멈춘다.
    files_to_touch:
    - docs/runbook.md
    - tools/build_failure_triage_v1.py
    - Temp/failure_triage_v1.json
    execution_steps_for_low_capability_llm:
    - 실패를 DATA, CONTRACT, FORMULA, SCHEMA, GAS, REPORT, PACKAGE, PERFORMANCE로 분류한다.
    - 각 분류별 first command, owner, rollback, allowed temporary mode를 명시한다.
    - 투자 판단에 영향 있으면 REVIEW_ONLY로 강등한다.
    commands:
    - python tools/build_failure_triage_v1.py
    - python tools/validate_failure_triage_v1.py
    acceptance_criteria:
    - unclassified_failure_count == 0
    - investment_impact_failure_review_only_count == 100%
    forbidden_actions: *id001
low_capability_llm_master_runbook:
  purpose: 저성능 LLM이 이 YAML만 보고도 고성능 LLM과 같은 리팩토링 판단을 내리기 위한 절차.
  fixed_order_steps:
  - step: 1
    instruction: AGENTS.md의 읽는 순서와 hard rule만 확인한다. 긴 해석을 하지 않는다.
  - step: 2
    instruction: runtime/active_artifact_manifest.yaml에서 canonical_source와 active_aliases를 확인한다.
  - step: 3
    instruction: Temp/engine_harness_gate_result.json의 status, failed_checks, warn_only 실패를 확인한다.
  - step: 4
    instruction: Temp/final_decision_packet_active.json과 Temp/number_provenance_ledger_v4.json만 숫자 출처로 인정한다.
  - step: 5
    instruction: spec/49_refactor_methodology_contract.yaml의 QEDD 원칙을 위반하는 변경은 거부한다.
  - step: 6
    instruction: 새 로직 요청은 반드시 Contract -> Schema -> Python -> Golden -> Shadow -> Active 순서로 TODO를 만든다.
  - step: 7
    instruction: GAS 수정 요청은 adapter인지 business logic인지 먼저 분류한다. business logic이면 Python 이동 TODO로 바꾼다.
  - step: 8
    instruction: 문서 추가 요청은 기존 권위 파일에 병합 가능한지 먼저 판단한다. 불필요하면 새 파일을 만들지 않는다.
  - step: 9
    instruction: 수치가 필요한 문장은 provenance가 없으면 DATA_MISSING으로 쓴다.
  - step: 10
    instruction: 검증 명령이 없는 TODO는 완료로 인정하지 않는다.
  - step: 11
    instruction: release 결과가 OK가 아니면 투자/운영 판단은 REVIEW_ONLY로 강등한다.
  - step: 12
    instruction: 최종 답변은 변경 파일, 실행 명령, 성공 기준, 금지 행동, rollback을 포함한다.
  response_template_for_refactor_tasks:
    sections:
    - source_summary
    - current_red_flags
    - target_architecture
    - todo_by_phase
    - commands
    - acceptance_criteria
    - rollback_plan
    forbidden:
    - 임의 점수 만들기
    - 출처 없는 숫자 만들기
    - 검증 없이 완료 선언
    - GAS에 계산 로직 추가
    - Temp 직접 편집
recommended_next_sprint:
  sprint_name: Sprint-R0 Authority Sync and Low-Capability Pack
  duration: 1주
  must_do_first:
  - P0-T02
  - P4-T04
  - P5-T01
  - P5-T03
  - P7-T03
  rationale: 현재 가장 위험한 문제는 새 알고리즘 부재가 아니라 stale artifact와 권위 불일치 가능성이다. 이 문제를 먼저 닫아야 이후 팩터/전략 고도화가 의미 있다.
  definition_of_done:
  - engine gate log와 실제 Temp artifact의 gate/coverage 불일치 0건
  - final_context_for_llm_v5.yaml 생성 및 required section 100% 충족
  - LLM copy-only output validation PASS
  - sell priority waterfall/order grammar validation PASS
  - release mode에서 skip_validate 사용 0건
rollback_policy:
  when_to_rollback:
  - release_dag_run returncode nonzero
  - number_provenance_coverage_pct < 100
  - report_authority_diff_count > 0
  - active_count_per_formula > 1
  - same_input_different_output_count > 0
  - cash_floor_violation_buy_count > 0
  rollback_steps:
  - runtime/rollback_manifest_latest.yaml을 읽는다.
  - active_artifact_manifest.yaml을 직전 PASS manifest로 되돌린다.
  - Temp 산출물은 직접 수정하지 말고 직전 PASS build command로 재생성한다.
  - lineage_events.jsonl에 rollback event를 남긴다.
  - operational report는 REVIEW_ONLY로 재렌더링한다.
final_decision:
  methodology_to_adopt: QEDD-R
  architecture_decision: spec contract first, Python canonical calculation, GAS thin adapter, deterministic release DAG, LLM
    copy-only renderer
  immediate_priority: 새 팩터 추가보다 stale artifact/authority sync/low-capability execution pack을 먼저 완성한다.
  expected_result: 저성능 LLM도 고정된 TODO와 final context만으로 동일한 투자판단 보고서를 재현한다.
