Files
C.E.L_Slide_test2/tests/regression/scripts/capture_imp95_pre_baseline.py
T
KyeongminandClaude Opus 4.8 b836e79ee1 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>
2026-07-02 17:03:42 +09:00

191 lines
7.2 KiB
Python

"""IMP-95 u8 — capture final.html SHA baseline via the FULL Phase Z pipeline
under PHASE_Z_B4_V4_EVIDENCE=OFF (default) for mdx 01/02/04/05.
Runs ``src.phase_z2_pipeline.run_phase_z2_mvp1`` end-to-end for each mdx file
in the Stage 2 u8 scope (01/02/04/05; mdx 03 is excluded per the ``mdx 03
정비`` lock). Each run writes a real ``final.html`` to disk at the production
write site ``src/phase_z2_pipeline.py:5994-5996``; bytes are IMP-94-normalized
and SHA-256 hashed, then frozen to
``tests/regression/fixtures/imp95_pre_baseline_sha.json``.
The accompanying regression test
``tests/regression/test_b4_v4_evidence_off_sha_parity.py`` re-runs the same
pipeline shape under flag OFF and asserts SHA equality with the frozen
values. Under flag OFF, IMP-95 (u1~u7) is a strict no-op for ``final.html``
bytes — see the trace-only docstring at ``src/phase_z2_pipeline.py:86`` —
so the captured baseline IS the immediate pre-IMP-95 reference even when
captured with IMP-95 code already in tree.
Reason for a separate baseline (vs. reusing 89a_pre_baseline_sha.json)
======================================================================
The 89a baseline was captured at HEAD ``6e9e3ee`` before subsequent
working-tree changes accumulated (e.g. the Emergency P3/P4/P4b verbatim
slot_payload builders), so the 89a SHAs no longer match the current
flag-OFF pipeline output for mdx 02/04/05 — a pre-existing baseline
drift orthogonal to IMP-95. A fresh baseline keyed to the current
flag-OFF state isolates IMP-95's u8 regression axis from that upstream
drift; the 89a baseline remains the load-bearing guard for the 89-a
axis.
IMP-94 marker normalization
===========================
IMP-94 ``data-region-id`` / ``data-content-unit-id`` tokens (stamped at
``src/region_marker_stamper.py:131-135``) are stripped before hashing.
The strip is anchored on ``leading space + attr token`` shape and is
disjoint from the IMP-96 ``data-frame-slot-id`` axis by attribute name.
Run from repo root::
python tests/regression/scripts/capture_imp95_pre_baseline.py
Idempotent. Re-run only when an upstream mapper/render/template delta is
reviewed and accepted as the new pre-IMP-95 reference. Refuses to run
with PHASE_Z_B4_V4_EVIDENCE enabled (the flag-ON state is not the
baseline axis).
"""
from __future__ import annotations
import hashlib
import json
import os
import re
import sys
import tempfile
from datetime import datetime, timezone
from pathlib import Path
_REPO_ROOT = Path(__file__).resolve().parents[3]
sys.path.insert(0, str(_REPO_ROOT))
sys.path.insert(0, str(_REPO_ROOT / "src"))
import src.phase_z2_pipeline as pz2 # noqa: E402
_SAMPLES_DIR = _REPO_ROOT / "samples" / "mdx_batch"
_MDX_BATCH = ("01.mdx", "02.mdx", "04.mdx", "05.mdx") # Stage 2 u8 scope
_OUT_PATH = (
_REPO_ROOT
/ "tests"
/ "regression"
/ "fixtures"
/ "imp95_pre_baseline_sha.json"
)
# IMP-94 additive marker strip patterns — must stay in sync with
# tests/regression/test_b4_v4_evidence_off_sha_parity.py.
_STRIP_REGION_ID_RE = re.compile(rb' data-region-id="[^"]*"')
_STRIP_CONTENT_UNIT_ID_RE = re.compile(rb' data-content-unit-id="[^"]*"')
def _strip_imp94_markers(raw_bytes: bytes) -> bytes:
stripped = _STRIP_REGION_ID_RE.sub(b"", raw_bytes)
stripped = _STRIP_CONTENT_UNIT_ID_RE.sub(b"", stripped)
return stripped
def _capture_one(mdx_file: str, runs_root: Path) -> dict:
mdx_path = _SAMPLES_DIR / mdx_file
assert mdx_path.exists(), f"sample missing: {mdx_path}"
run_id = f"imp95_baseline_{mdx_path.stem}"
pipeline_exit_code: int | None = None
try:
pz2.run_phase_z2_mvp1(mdx_path, run_id=run_id)
except SystemExit as exc:
pipeline_exit_code = (
int(exc.code) if isinstance(exc.code, int) else 1
)
final_html_path = runs_root / run_id / "phase_z2" / "final.html"
assert final_html_path.exists(), (
f"final.html not written by pipeline: {final_html_path} "
f"(pipeline_exit_code={pipeline_exit_code})"
)
raw_bytes = final_html_path.read_bytes()
assert len(raw_bytes) > 0, f"final.html is empty: {final_html_path}"
normalized_bytes = _strip_imp94_markers(raw_bytes)
return {
"mdx_file": mdx_file,
"run_id": run_id,
"final_html_size_bytes": len(normalized_bytes),
"sha256": hashlib.sha256(normalized_bytes).hexdigest(),
"pipeline_exit_code": pipeline_exit_code,
}
def capture() -> dict:
assert os.environ.get("PHASE_Z_B4_V4_EVIDENCE", "") == "", (
"PHASE_Z_B4_V4_EVIDENCE must be unset when capturing baseline "
"(default-OFF state is the production-equivalent axis for u8). "
"Refusing to run with the flag enabled."
)
assert os.environ.get("PHASE_Z_B4_MAPPER_SOURCE", "") == "", (
"PHASE_Z_B4_MAPPER_SOURCE must also be unset — the u8 baseline "
"is captured under both flags OFF (full pre-IMP-89/95 path)."
)
_OUT_PATH.parent.mkdir(parents=True, exist_ok=True)
with tempfile.TemporaryDirectory(prefix="imp95_baseline_") as tmp:
runs_root = Path(tmp)
original_runs_dir = pz2.RUNS_DIR
pz2.RUNS_DIR = runs_root
try:
entries = [_capture_one(mf, runs_root) for mf in _MDX_BATCH]
finally:
pz2.RUNS_DIR = original_runs_dir
return {
"schema_version": 1,
"axis": (
"IMP-95 u8 — final.html SHA baseline captured via FULL "
"run_phase_z2_mvp1 pipeline under PHASE_Z_B4_V4_EVIDENCE=OFF "
"and PHASE_Z_B4_MAPPER_SOURCE=OFF (defaults)"
),
"description": (
"Frozen SHA-256 of `final.html` bytes (production write site "
"src/phase_z2_pipeline.py:5994-5996) for mdx 01/02/04/05 "
"under PHASE_Z_B4_V4_EVIDENCE OFF. Under flag OFF, IMP-95 "
"(u1~u7) is strictly no-op for final.html (planner branch "
"falls through to legacy _select_frame at u3; u4/u5/u6 "
"additive telemetry confined to placement_trace per the "
"trace-only docstring at src/phase_z2_pipeline.py:86). The "
"u8 regression test asserts SHA equality with these frozen "
"values, so any future code change that drifts the flag-OFF "
"render output produces a mismatch and breaks the test. "
"mdx 03 is excluded per Stage 2 u8 scope (mdx 03 정비 LOCK). "
"Regenerate only when an upstream delta is reviewed and "
"accepted as the new pre-IMP-95 reference."
),
"captured_at_utc": (
datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
),
"renderer": {
"entrypoint": "src.phase_z2_pipeline.run_phase_z2_mvp1",
"write_site": "src/phase_z2_pipeline.py:5994-5996",
"artifact_relpath": "<RUNS_DIR>/<run_id>/phase_z2/final.html",
},
"mdx_batch": list(_MDX_BATCH),
"mdx_files": {entry["mdx_file"]: entry for entry in entries},
"total_files": len(entries),
}
def main() -> None:
data = capture()
_OUT_PATH.write_text(
json.dumps(data, indent=2, ensure_ascii=False) + "\n",
encoding="utf-8",
)
print(
f"wrote {_OUT_PATH} ({data['total_files']} files: "
f"{', '.join(data['mdx_files'].keys())})"
)
if __name__ == "__main__":
main()