- src: phase_z2 composition/mapper/pipeline/placement_planner/retry, ai_fallback(prompts/schema/validate), mdx_text_atoms 신규 - Front: PipelineTracePanel 신규, FramePanel/SlideCanvas/Home/designAgentApi 등 갱신 + 테스트 4종 추가 - templates/phase_z2: catalog(component_expansion_registry, node_slot_mapping 신규), frames, families, slide_base 갱신 - tests/matching: phase2~26 매칭 실험 스크립트·리포트·온톨로지 전체 (미커밋 진행분) - tests: b4_v4 evidence, task5~28.5 시리즈, regression(imp95 baseline) 등 신규 테스트 대량 추가 - docs/reference: MDX 구조 인벤토리, MDX→Frame 구조 계약 문서 - scripts: mdx 계약/parity/coverage/viewport 체크, gitea comment, run sync 유틸 - .gitignore: tmp*.json, chromedriver, .orchestrator, *.pkl, Front_test* 등 임시/스냅샷 제외 미완성 작업의 보존용 스냅샷 커밋 (2026-07-02) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
145 lines
5.7 KiB
Python
145 lines
5.7 KiB
Python
"""Pipeline Step 12-promote — Frame 13 review_queue 해제 + SSOT 라벨 확정.
|
|
|
|
사용자 지시 (A 단계):
|
|
review_queue §13 에 "필수조건 → capability_requirements 여야 할 가능성" 로 이미 기록되어 있음.
|
|
V3 r4 결과에서 MDX 03-1 aff=capability_requirements 정상 / Frame 13 현재 primary 가
|
|
comparative_matrix 여서 primary 매칭 실패 → 03-1 실패 원인 확정.
|
|
|
|
**성능 맞추기 땜질 아님**. review_queue 에 남아 있던 미확정 라벨의 SSOT 정리.
|
|
|
|
원칙:
|
|
1. 원본 structure_ontology_v2_final.yaml 는 **보존**
|
|
2. 새 파일 structure_ontology_v2_final_r2.yaml 생성
|
|
3. Frame 13 entry 에 resolved_from_review_queue provenance 추가
|
|
4. meta.review_queue 에서 §13 제거하되, meta.resolved_review_items 에 이력 보존
|
|
"""
|
|
import datetime
|
|
import sys
|
|
from pathlib import Path
|
|
import yaml
|
|
|
|
HERE = Path(__file__).parent
|
|
sys.path.insert(0, str(HERE))
|
|
|
|
FINAL_PATH = HERE / 'structure_ontology_v2_final.yaml'
|
|
FINAL_R2_PATH = HERE / 'structure_ontology_v2_final_r2.yaml'
|
|
|
|
FRAME13_SHORT_ID = '13'
|
|
NEW_PRIMARY = 'capability_requirements'
|
|
|
|
PROVENANCE = {
|
|
'source_review_queue_item': {
|
|
'frame': '13',
|
|
'reason_original': '"필수조건" 이 comparative_matrix 로 잡힘 — capability_requirements 여야 할 가능성',
|
|
'queue_file': 'structure_ontology_v2_final.yaml::meta.review_queue',
|
|
},
|
|
'confirmation_evidence': {
|
|
'pipeline_step': 'V3 r4 (pipeline_08_v3_r4_structure_rerank.py)',
|
|
'mdx_section': '03-1 (DX 시행을 위한 필수 요건)',
|
|
'finding': (
|
|
'MDX 03-1 aff = capability_requirements (정상). '
|
|
'Frame 13 aff primary = comparative_matrix (오라벨) 로 primary match = 0.0. '
|
|
'Frame 20 (aff=capability_requirements) 이 1.0 으로 올라가 Frame 13 를 밀어냄. '
|
|
'B-1 + B-2 (MDX 하네스) 수정 후에도 남은 실패 → Frame 쪽 SSOT 문제 확정.'
|
|
),
|
|
'r4_result_file': 'v3_structure_rerank_r4_result.yaml',
|
|
},
|
|
'decision_rationale': (
|
|
'성능 땜질이 아니라 review_queue 에 이미 올라온 미해결 분류의 정상적 확정 단계. '
|
|
'Spec-review / SSOT 원칙에 따라 ontology 를 바로잡음.'
|
|
),
|
|
'confirmed_at': datetime.datetime.now().isoformat(timespec='seconds'),
|
|
'confirmed_by': 'pipeline_12_promote_frame13.py',
|
|
}
|
|
|
|
|
|
def main():
|
|
final = yaml.safe_load(FINAL_PATH.read_text(encoding='utf-8'))
|
|
templates = final['templates_v2']
|
|
short_to_fid = {v['short_id']: k for k, v in templates.items()}
|
|
|
|
fid = short_to_fid.get(FRAME13_SHORT_ID)
|
|
if not fid:
|
|
raise SystemExit(f"Frame {FRAME13_SHORT_ID} 를 찾지 못함.")
|
|
|
|
entry = templates[fid]
|
|
old_primary = entry['content_affinity']['primary']
|
|
if old_primary == NEW_PRIMARY:
|
|
print(f"Frame {FRAME13_SHORT_ID} 는 이미 {NEW_PRIMARY} — 변경 없음.")
|
|
return
|
|
|
|
# content_affinity 업데이트
|
|
entry['content_affinity']['primary'] = NEW_PRIMARY
|
|
# 기존 secondary 에서 new primary 제거 (있으면)
|
|
entry['content_affinity']['secondary'] = [
|
|
s for s in entry['content_affinity'].get('secondary', []) if s != NEW_PRIMARY
|
|
]
|
|
# evidence 에 기록
|
|
entry['content_affinity']['evidence']['primary'] = {
|
|
'source': 'resolved_from_review_queue',
|
|
'prior_primary': old_primary,
|
|
'new_primary': NEW_PRIMARY,
|
|
'confidence': 1.0,
|
|
'provenance': PROVENANCE,
|
|
}
|
|
|
|
# frame-level provenance
|
|
entry.setdefault('v2_meta', {})
|
|
entry['v2_meta']['resolved_from_review_queue'] = PROVENANCE
|
|
|
|
# meta 업데이트
|
|
meta = dict(final['meta'])
|
|
meta['schema_version'] = 'template-fit-v2-final-r2'
|
|
meta['generated_at'] = datetime.datetime.now().isoformat(timespec='seconds')
|
|
meta['generator'] = 'pipeline_12_promote_frame13.py'
|
|
meta['predecessor_drafts'] = meta.get('predecessor_drafts', []) + ['structure_ontology_v2_final.yaml']
|
|
|
|
# review_queue 에서 §13 제거, resolved_review_items 에 이동
|
|
remaining_queue = [q for q in meta.get('review_queue', []) if q.get('frame') != FRAME13_SHORT_ID]
|
|
moved = [q for q in meta.get('review_queue', []) if q.get('frame') == FRAME13_SHORT_ID]
|
|
meta['review_queue'] = remaining_queue
|
|
meta.setdefault('resolved_review_items', [])
|
|
for item in moved:
|
|
item_record = dict(item)
|
|
item_record['resolved_at'] = PROVENANCE['confirmed_at']
|
|
item_record['resolution'] = {
|
|
'from': old_primary,
|
|
'to': NEW_PRIMARY,
|
|
'axis': 'content_affinity.primary',
|
|
'evidence_pipeline': PROVENANCE['confirmation_evidence']['pipeline_step'],
|
|
}
|
|
meta['resolved_review_items'].append(item_record)
|
|
|
|
# manual_overrides 로그에도 추가
|
|
meta.setdefault('manual_overrides', [])
|
|
meta['manual_overrides'].append({
|
|
'frame': FRAME13_SHORT_ID,
|
|
'frame_id': fid,
|
|
'field': 'content_affinity.primary',
|
|
'from': old_primary,
|
|
'to': NEW_PRIMARY,
|
|
'reason': 'review_queue 해제 (SSOT 정리) — V3 r4 결과 기반',
|
|
})
|
|
|
|
meta['status'] = 'locked_for_v3_r5_matching'
|
|
|
|
out = {'meta': meta, 'templates_v2': templates}
|
|
FINAL_R2_PATH.write_text(
|
|
yaml.safe_dump(out, allow_unicode=True, sort_keys=False, width=1000),
|
|
encoding='utf-8',
|
|
)
|
|
|
|
print('=' * 70)
|
|
print('Frame 13 review_queue 해제 + SSOT 확정')
|
|
print('=' * 70)
|
|
print(f' 입력: {FINAL_PATH} (보존)')
|
|
print(f' 출력: {FINAL_R2_PATH}')
|
|
print()
|
|
print(f' Frame 13 content_affinity.primary: {old_primary} → {NEW_PRIMARY}')
|
|
print(f' review_queue: {len(final["meta"].get("review_queue", []))} → {len(remaining_queue)} 건')
|
|
print(f' resolved_review_items: +1 건 (Frame 13)')
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|