wip: phase_z2 evidence 파이프라인 + matching 실험(phase2~26) + 프론트 trace 패널 진행분 스냅샷
- 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>
This commit is contained in:
@@ -8,7 +8,7 @@ NO real catalog template_id / frame_id, NO `v4_full32_result.yaml` dependency.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
from dataclasses import dataclass
|
||||
from typing import Optional
|
||||
|
||||
import pytest
|
||||
@@ -441,11 +441,13 @@ def test_integration_override_reflects_in_zones_data_step9_step20(tmp_path, monk
|
||||
not only `comp_debug.section_assignment_plan`.
|
||||
|
||||
Sample 03 MDX has 2 sections (03-1, 03-2). Auto plan = [top=03-1,
|
||||
bottom=03-2]. Override forces top=03-2 → exact-id collision with auto
|
||||
bottom (whole-skip) + previous auto top (03-1) becomes uncovered.
|
||||
bottom=03-2]. Override forces top=03-2; the no-drop fallback should keep
|
||||
the displaced real section (03-1) in the other zone rather than silently
|
||||
dropping it.
|
||||
"""
|
||||
import json
|
||||
from pathlib import Path
|
||||
from uuid import uuid4
|
||||
from src import phase_z2_pipeline as pz2
|
||||
|
||||
PROJECT_ROOT = Path(pz2.__file__).resolve().parent.parent
|
||||
@@ -453,17 +455,22 @@ def test_integration_override_reflects_in_zones_data_step9_step20(tmp_path, monk
|
||||
if not sample_path.is_file():
|
||||
pytest.skip(f"sample MDX not present: {sample_path}")
|
||||
|
||||
# Isolate run output under tmp_path so we do not pollute data/runs/.
|
||||
monkeypatch.setattr(pz2, "RUNS_DIR", tmp_path / "runs")
|
||||
# Keep the controlled integration run under the project root. Some asset
|
||||
# trace code records paths relative to PROJECT_ROOT, so pytest tmp_path
|
||||
# outside the repo is a separate path-hygiene axis rather than this
|
||||
# override/status-laundering probe.
|
||||
runs_root = PROJECT_ROOT / "data" / "test_tmp" / f"section_assignment_{uuid4().hex}"
|
||||
monkeypatch.setattr(pz2, "RUNS_DIR", runs_root)
|
||||
|
||||
run_id = "test_imp06_override_integration"
|
||||
pz2.run_phase_z2_mvp1(
|
||||
sample_path,
|
||||
run_id=run_id,
|
||||
override_layout="horizontal-2",
|
||||
override_section_assignments={"top": ["03-2"]},
|
||||
)
|
||||
|
||||
run_dir = tmp_path / "runs" / run_id / "phase_z2"
|
||||
run_dir = runs_root / run_id / "phase_z2"
|
||||
debug_path = run_dir / "debug.json"
|
||||
assert debug_path.is_file(), f"debug.json missing at {debug_path}"
|
||||
debug = json.loads(debug_path.read_text(encoding="utf-8"))
|
||||
@@ -487,14 +494,15 @@ def test_integration_override_reflects_in_zones_data_step9_step20(tmp_path, monk
|
||||
)
|
||||
|
||||
bottom = zones["bottom"]
|
||||
# Exact-id collision (override 03-2 vs auto bottom 03-2) → whole-skip.
|
||||
# The empty zone record must be present in debug_zones (zone identity preserved).
|
||||
assert bottom.get("v4_template_id") == "__empty__" or bottom.get("merge_type") == "empty", (
|
||||
f"bottom should be empty after collision; got "
|
||||
f"v4_template_id={bottom.get('v4_template_id')}, merge_type={bottom.get('merge_type')}"
|
||||
# Current no-drop policy preserves the displaced real section in the other
|
||||
# zone instead of creating an empty/collision placeholder.
|
||||
assert bottom.get("source_section_ids") == ["03-1"], (
|
||||
f"bottom should preserve displaced real section 03-1; got "
|
||||
f"{bottom.get('source_section_ids')}"
|
||||
)
|
||||
assert bottom.get("skipped_reason") == "override_collision", (
|
||||
f"bottom skipped_reason != override_collision; got {bottom.get('skipped_reason')}"
|
||||
assert bottom.get("merge_type") == "no_drop_fallback_group", (
|
||||
f"bottom merge_type should be no_drop_fallback_group; got "
|
||||
f"{bottom.get('merge_type')}"
|
||||
)
|
||||
|
||||
# ── 2) Step 20 slide_status — coverage invariant ──
|
||||
@@ -503,17 +511,16 @@ def test_integration_override_reflects_in_zones_data_step9_step20(tmp_path, monk
|
||||
step20 = json.loads(step20_path.read_text(encoding="utf-8"))
|
||||
payload = step20.get("data") if "data" in step20 else step20
|
||||
filtered_ids = payload.get("filtered_section_ids") or []
|
||||
assert "03-1" in filtered_ids, (
|
||||
f"03-1 (previous auto top displaced by override) must appear in "
|
||||
f"filtered_section_ids; got {filtered_ids}"
|
||||
assert "03-1" not in filtered_ids, (
|
||||
f"03-1 should be preserved by no-drop fallback, not filtered; got {filtered_ids}"
|
||||
)
|
||||
# full_mdx_coverage must NOT be True when override displaces a section.
|
||||
assert payload.get("full_mdx_coverage") is not True, (
|
||||
f"full_mdx_coverage should be False after override displaces 03-1; got "
|
||||
assert payload.get("full_mdx_coverage") is True, (
|
||||
f"full_mdx_coverage should remain True because 03-1 is preserved; got "
|
||||
f"{payload.get('full_mdx_coverage')}"
|
||||
)
|
||||
# Codex #10 Catch O list-shaped filtered_section_reasons must include the
|
||||
# override-uncovered entry pointing to the position whose plan dropped it.
|
||||
# override-uncovered entries should not be emitted because the displaced
|
||||
# section is preserved by no-drop fallback.
|
||||
reasons = payload.get("filtered_section_reasons") or []
|
||||
override_uncovered_reasons = [
|
||||
r for r in reasons
|
||||
@@ -521,8 +528,8 @@ def test_integration_override_reflects_in_zones_data_step9_step20(tmp_path, monk
|
||||
and r.get("source") == "section_assignment_override"
|
||||
and "03-1" in (r.get("section_ids") or [])
|
||||
]
|
||||
assert override_uncovered_reasons, (
|
||||
f"filtered_section_reasons missing override-uncovered entry for 03-1; "
|
||||
assert not override_uncovered_reasons, (
|
||||
f"filtered_section_reasons should not mark preserved 03-1 as uncovered; "
|
||||
f"got {reasons}"
|
||||
)
|
||||
|
||||
@@ -548,8 +555,8 @@ def test_integration_override_reflects_in_zones_data_step9_step20(tmp_path, monk
|
||||
# ── 4) comp_debug — pre-existing plan/summary still present (regression) ──
|
||||
cd = debug.get("composition_planner_debug") or {}
|
||||
sa_summary = cd.get("section_assignment_summary") or {}
|
||||
# uncovered_section_ids carries the displaced auto-top section.
|
||||
assert "03-1" in (sa_summary.get("uncovered_section_ids") or []), (
|
||||
# no-drop fallback keeps the displaced auto-top section covered.
|
||||
assert "03-1" not in (sa_summary.get("uncovered_section_ids") or []), (
|
||||
f"comp_debug.section_assignment_summary.uncovered_section_ids "
|
||||
f"missing 03-1; got {sa_summary.get('uncovered_section_ids')}"
|
||||
f"should not include preserved 03-1; got {sa_summary.get('uncovered_section_ids')}"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user