Files
C.E.L_Slide_test2/docs/architecture/PHASE-Z-MATCHING-ARCHITECTURE.md
kyeongmin aca6a992b9 Add Phase Z matching architecture anchor doc
- consolidate evidence-based principles for Step 5/6/7 and B-axis matching layer
- record CompositionUnit, candidate-based composition, and 4-tier terminology
- defer bridge architecture and slot_payload evolution as scope-locked open items
2026-05-06 15:46:52 +09:00

12 KiB

Phase Z 매칭 아키텍처 — 원칙 anchor

22-step pipeline 의 매칭 layer (Step 5/6/7 + B-axis Step 9/10/11) 를 다루는 원칙 anchor doc.

본 문서는 새 디자인 생성 이 아니라 기존 코드 / 과거 docs / 관찰 사례 / session 인사이트 를 근거로 한 forward improvement consolidation.

관련 anchors :

  • docs/architecture/PHASE-Z-PIPELINE-OVERVIEW.md (D1, 22-step pipeline)
  • docs/architecture/PHASE-Z-CONTENT-OBJECT-SUBZONE-SPEC.md (D2, Layer A/B SPEC)
  • docs/architecture/PHASE-Z-CONTENT-OBJECT-SUBZONE-PLAN.md (D3, schema completion plan)
  • docs/architecture/PHASE-Z-PIPELINE-STATUS-BOARD.md (D4, 현재 status)

§0. 본 문서의 작성 방법론 (P0)

evidence-based forward improvement — 매번 4 source 를 거쳐 도출 :

  1. 과거 docs (D1 / D2 / D3 / D4) — 원래 의도
  2. 현재 코드 (src/phase_z2_*.py / templates/phase_z2/catalog/frame_contracts.yaml) — 실제 동작
  3. 관찰된 혼선 / 실패 사례 — 경험적 evidence
  4. session 인사이트 — 최근 정리된 mental model

이걸 관찰 → 혼선 → 도출 원칙 → 개선 방향 form 으로 표면화. 과거 회귀 가 아니라 과거를 근거로 한 개선. 감으로 결정 / 가장 쉬운 선택 금지.

§1. 현재 코드 상태 (관찰)

1.1 매칭 단위 — CompositionUnit

매칭의 atomic unit 은 section 이 아니라 CompositionUnit. src/phase_z2_composition.pycollect_candidates3 종 candidate type 을 동시 생성 :

  • singlesrc/phase_z2_composition.py:230-243 (1 section 단독)
  • parent_mergedsrc/phase_z2_composition.py:260-273 (parent 자체가 V4 매칭, children 묶음)
  • parent_merged_inferredsrc/phase_z2_composition.py:352-368 (children rep_match 기반 inferred merge)

각 candidate 는 source_section_ids[] + merge_type (line 232 / 262 / 354) 로 어떤 section 들을 어떻게 묶었는지 표현.

1.2 frame 선택 — render path authority = V4 rank-1

현재 render path 의 frame_template_id 는 composition planner 의 V4 rank-1 기반 :

  • lookup_v4_match() in src/phase_z2_pipeline.py (D1:212 명시) — rank-1 만 반환
  • composition planner 가 V4 결과로 candidate 생성

B4 (src/phase_z2_placement_planner.py:90-107_select_frame) 도 frame selection 을 수행 하지만 trace-only — render path authority 는 V4 rank-1.

V4 = top-k 선언만 됐고 rank-1 사용 만 활성. D4 의 ⚠ partial.

1.3 binding — phase_z2_mapper.map_with_contract (Layer 1)

src/phase_z2_mapper.py:584-609map_with_contract(section, contract) 는 contract 에서 오직 두 field 만 read :

  • contract["source_shape"] (split 규칙)
  • contract["payload"]["builder"] (named PAYLOAD_BUILDERS dispatch)

accepted_content_types / sub_zones 등 Layer 2 field 는 접근 X. 즉 mapper 는 Layer 1 binder 로 격리.

1.4 placement — phase_z2_placement_planner (Layer 2 reader, trace-only)

src/phase_z2_placement_planner.py :

  • _select_frame (90-107) — accepted_content_types ⊇ content_type_set cover + declaration order first
  • _assign_region_to_sub_zone (113-151) — sub_zones 의 narrowest-accepts first
  • plan_placement (157+) — Stage A (B2 internal regions) + Stage B (region ↔ sub_zone) 통합

B4 는 Layer 2 reader 이지만 src/phase_z2_pipeline.py:1060-1145 에서 trace-only 로만 호출. render path (slot_payload 생성) 미연결. D4:78-83 의 render path placement_trace 미사용 과 일치.

1.5 capacity / fit — classifier (post-render telemetry)

src/phase_z2_classifier.pyclassify_visual_runtime_checkrender 후 visual measurement 기반 fit 판정. Architectural reframe (D2:16-33 의 PLANNING / RENDER / POST-RENDER 3-layer) : A1~A4 = post-render telemetry layer. 덜 중요 가 아니라 위치가 다름. 매칭 결정 자체에는 직접 입력 X (현재).

§2. 확인된 혼선 (resolution)

2.1 Sub-zone 용어 4-방향 충돌 → 4-tier 분리 (P5'')

session 안 누적 혼선 :

  • D1 의 "Zone (top / bottom_l / bottom_r 등)"
  • composition.py 의 child unit 분리 (single / parent_merged 등)
  • yaml 의 sub_zones field
  • 사용자 mental model 의 "### split"

4 tier 별 명칭 lock :

Tier 명칭 위치 정체
1 Layout slide-level slide-body 안 zone topology (8-preset vocabulary)
2 Zone layout 안 콘텐츠 구역 (top / bottom_l / bottom_r 등). 1 frame 매칭 단위
3 Split Zone (Child Unit) zone 안 composition planner 가 만든 child unit (parent_merged 의 분리 단위)
4 Frame Slot frame 안 yaml 의 sub_zones = Layer B placement target. region 매칭 대상

이후 본 문서 / 후속 doc 은 위 명칭 어휘 만 사용. yaml field sub_zones기존 이름 유지하되 의미 = Frame Slot 으로 lock (mechanical rename 은 D3 plan).

2.2 composition tie-break ≠ Frame Slot tie-break

scope-lock 단계에서 D2:524-533 의 tie-breakcomposition tie-break evidence 로 잘못 분류. 실제로는 :

  • D2:524-533 = Frame Slot 단위 tie-break (Stage B 안, frame 이미 선택된 후)
  • composition tie-break = composition.py:433-441 (sort + greedy + coverage)

두 layer 가 다름. P7 evidence 는 composition layer 만, Frame Slot layer 는 별개 location.

2.3 "Layer 2 미사용" framing 오류

scope-lock 초안의 "mapper 가 Layer 2 를 consume 안 함" framing 은 암묵적으로 mapper 가 Layer 2 reader 가 돼야 한다 의 fix direction 함의. 실제 architectural intent :

  • mapper = Layer 1 binder (의도된 격리)
  • B4 = Layer 2 reader (의도된 분리)

문제Layer 2 unconsumed 가 아니라 B4 의 Layer 2 read 가 trace-only 라 render path 까지 안 닿음. bridge 가 답이지 mapper 확장 이 아님.

2.4 Step 4/5/9 분리 미완

현재 구현은 D1 이 의도한 Step 4 → Step 5 → Step 9 분리가 완성되지 않음 :

  • Step 4 (composition planning input — section_layout_signature / content_object 구조) = partial/dormant (D4:73 의 ⚠ partial transition)
  • Step 5 evidence 와 Step 9 final selection = conflate (D1:255)

D1:185 가 명시적으로 Step 4 가 frame matching 보다 먼저 와야 함 을 지적.

§3. 도출된 원칙

P1 : 매칭 단위 = CompositionUnit (section 아님)

  • 근거 : composition.py:230-243 (single) / :260-273 (parent_merged) / :352-368 (parent_merged_inferred). 각 line :232 / :262 / :354merge_type signal
  • 함의 : MDX section 을 1:1 zone 매칭 단위로 가정하는 코드 / doc 는 모두 추상화 누락. CompositionUnit 으로 통일.

P3 : frame 선택 / content binding layer 분리

  • 근거 : 현재 코드의 de facto 분리 (mapper §1.3 + placement_planner §1.4)
  • 원칙 : frame 선택 (어떤 frame 을 쓸지) 과 content binding (선택된 frame 에 콘텐츠를 어떻게 채울지) 는 별개 axis. 함께 결정하면 search space 가 곱셈으로 폭발 + 실패 격리 불가.
  • 함의 : 어떤 axis 가 frame 을 결정 하는지 + 어떤 axis 가 binding 하는지 명시적 분리 — 한 module 이 둘 다 하면 회귀 위험.

P5'' : 4-tier terminology lock

§2.1 표 그대로. 후속 doc / commit message / 코드 docstring 모두 4-tier 어휘만 사용.

P7 : candidate-based composition (sequential A/B 아님)

  • 근거 :
    • 원리 : docs/architecture/PHASE-Z-PIPELINE-OVERVIEW.md:216-218 ("child 따로 / sibling 묶기 / parent 단위" + scoring inputs)
    • 구현 : composition.py:230-243 / :260-273 / :352-368 (3 candidate type 동시 생성)
    • 선택 : composition.py:433-441 ((score desc, source_section_ids count desc) + greedy covered skip)
  • 원칙 : composition 은 "## → fail → ### split → re-merge" sequential 이 아니라 3 candidate type 을 동시 생성 → score + coverage tie-breakparallel evaluation.
  • D2:524-533 은 Frame Slot tie-break (Stage B) 로 본 P7 evidence 와 별도 layer.

P8 : staged migration — frame 선택 authority + binding 진화 분리

P8-a (near-term)

  • 목표 : frame selection authority 정리 (V4 rank-1 단독 → B4 informant 또는 B4-mediated 의 어떤 형태)
  • 유지 : mapper binding channel (PAYLOAD_BUILDERS) — 현재 working channel 안전
  • open : B4 결과를 render path frame selection 에 어떻게 반영 할지의 bridge 형태 → §5 의 Q-V4B4 / Q-LB 에서 별도 scope-lock

P8-b (longer-term, 지금 결정 X)

  • region / Frame Slot-aware slot_payload 진화
  • PLACEMENT_PAYLOAD_BUILDERS 등 별도 namespace 가능성
  • DC2 Open question (Q-LB) 해결 후 결정. 본 문서 시점에서는 deferred.

§4. 코드 변경 결정 지점

DC1 : Step 4/5/9 분리 미완

  • 현 상태 : D1 의도한 Step 4 → Step 5 → Step 9 분리가 완성되지 않음. Step 4 (composition planning input — section_layout_signature / content_object 구조) 는 partial/dormant (D4:73 의 ⚠ partial), Step 5 evidence 와 Step 9 final selection 은 conflate (D1:255).
  • 결정 지점 :
    • Step 4 가 frame matching 에 composition candidate 평가 input 으로 흘러야 (D1:185 명시적 지적)
    • Step 5 evidence layer 와 Step 9 final selection layer 의 명시적 분리 필요
  • 영향 module : src/phase_z2_pipeline.py orchestrator + src/phase_z2_composition.py (input 확장)

DC2-a : phase_z2_mapper = Layer 1 working channel

  • 현 상태 : src/phase_z2_mapper.py:584-609source_shape + payload.builder 만 read. 현재 render path 의 유일 working channel.
  • 결정 지점 : Layer 1 격리 유지. mapper 에 Layer 2 read 를 추가하는 방향은 반대 — 실제 의도는 별 axis (DC2-b + Open question Q-LB).

DC2-b : phase_z2_placement_planner = Layer 2 reader, render path 미연결

  • 현 상태 : src/phase_z2_placement_planner.py:90-107 (accepted_content_types) + :113-151 (sub_zones) — Layer 2 read 활성. 그러나 src/phase_z2_pipeline.py:1060-1145 에서 trace-only. final render 미연결.
  • 결정 지점 : Layer 2 read 결과를 render path 에 어떻게 합류시킬지 의 bridge 결정 — §5 의 Q-LB 에서 별도 scope-lock.

DC3 : Internal Region runtime — trace-only partial

  • 현 상태 : SPEC v1 (D2) 가 Internal Region (Layer A) / Frame Slot (Layer B) 의 layered placement 정의. Layer A runtime 은 trace-only partialsrc/phase_z2_placement_planner.py:157+plan_placement 가 Stage A 호출 (:192-197plan_internal_regions call) 수행하지만, 결과가 render path 미합류. 부재 가 아니라 render path authority 미연결. D4:73 의 ⚠ partial 분류와 일치.
  • 결정 지점 : Layer A planning telemetry 활성 단계 → render path 합류 단계의 separate axis. P8-b 와 연관 (slot_payload 진화 이전 단계).

§5. open scope-lock questions

본 axis 범위 의 deferred 결정. 후속 axis 에서 각각 별도로 lock.

Q-FW : 4 filter score weight / threshold

  • F1 frame internal fit / F2 child frame divergence / F3 content type-structure match / F4 content loss risk 의 score weightauto vs review threshold 결정 필요.

Q-CO : candidate priority tie-break

  • composition.py:433 의 (score, source_section_ids count) 외에 추가 axis (cardinality_fit / hierarchy_coherence / density) 도입 시점.

Q-RT : review / adapter_needed threshold

  • W1/W2/W3 신호 + auto_selectable=False candidate 의 review surface 정책.

Q-V4B4 : V4 → B4 frame selection authority transition timing

  • P8-a 의 언제 — V4 단독 / B4 informant / B4-mediated 의 단계.

Q-LB : Layer 1 ↔ Layer 2 bridge architecture

  • DC2-b 의 어떻게 — mapper direct consume / B4-mediated integration / 별도 translator. Q-V4B4 와 연관되나 별개 layer (frame 선택 timing vs Layer 2 → render path bridge 구조).

Q-CE : catalog extension surface

  • frame_contracts.yaml 에 신규 frame 추가 시 어떤 layer 부터 채워야 self-consistent 인지의 declarative form.

Q-DT : decision trace 표준 form

  • composition / placement / fit_classification 의 trace 통합 schema. 현재 각각 다른 dict 구조.