Commit Graph

8 Commits

Author SHA1 Message Date
8648a468d9 feat(#69): IMP-40 u1~u6 frame contract label_default placeholder/fallback role discriminator (BIM/DX leak fix)
Some checks failed
Multi-MDX Regression (IMP-91) / multi-mdx-regression (push) Failing after 26s
- catalog (frame_contracts.yaml): F18 bim_dx_comparison_table col_a/col_b
  label_default_role=placeholder; F30 industry_current_status_three_col +
  F31 industry_characteristics_three_col col_a/col_b/col_c forward-compat
  placeholder; F33 engn_sw_three_types untouched (no label_default).
- mapper (_build_compare_table_2col): generic _resolve_label_default(col_key)
  branches on <col>_label_default_role — placeholder -> '' (Figma placeholder
  suppressed at runtime), fallback -> catalog literal (legacy default), unknown
  -> ValueError with template_id + role_key + value. Absent role defaults to
  fallback (backward compat for contracts without discriminator).
- tests (tests/phase_z2/test_imp40_label_default_role.py): u4 generic matrix
  (placeholder / fallback / absent / unknown / 3-col axis) + u5 F18-reuse
  non-BIM/DX synthetic rows asserting placeholder labels emit '' and BIM/DX
  literal tokens do not leak.
- snapshot (tests/integration/__snapshots__/slot_payload.json): mdx 01 F18
  string_slot_nonempty.col_a_label/col_b_label True -> False (u6 expected
  drift from u3 placeholder -> empty string flip). slot_names + rows + title
  preserved.

Verification:
- imp40_label_default_role: 6/6 PASSED
- phase_z2 sweep: 608/608 PASSED
- multi_mdx_regression: 50/50 PASSED
- cross-suite sweep: 662/662 PASSED
- BIM/DX literal grep on mapper + new test: 0 hits
- No mdx-specific branches (mdx 03/04/05 grep on mapper: 0 hits)

Guardrails: no MDX 03/04/05 hardcoding (catalog policy only); no spacing
shrink; no auto frame swap on reject; no AI call at Step 12; F33 untouched.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 18:53:20 +09:00
cacc5b30db feat(#85): IMP catalog builder invariant + VP runtime gate (u1~u7)
- u1: BuilderMissingError(FitError) — narrow exception aligned with pipeline catch
- u2: load_frame_contracts catalog invariant + VP skip + CatalogInvariantError
- u3a: audit CLI I1~I3 (partial existence / declared builder / registry membership)
- u3b: audit CLI I4 (slot_payload refs vs declared/generated payload keys)
- u4: lookup_v4_candidates VP filter (lookup_v4_all_judgments raw telemetry untouched)
- u5: catalog invariant regression coverage + temp non-VP failure fixtures
- u6: mdx04 VP routing fixture tests (sw_dependency_four_problems excluded from live)
- u7: tests/conftest.py env isolation + mdx03/mdx04/mdx05 subprocess smoke

Targeted 74 PASS (12.31s). Full regression 1063 PASS (87.70s). Audit CLI clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 16:56:38 +09:00
90503cadd6 feat(#67): IMP-38 V4 max_rank policy formalization (u1~u3, 4 round consensus)
- u1: separate templates/phase_z2/catalog/v4_fallback_policy.yaml + load_v4_fallback_policy() loader
  (catalog pollution prevention — Codex #1 correction)
- u2: dynamic effective max_rank in lookup_v4_match_with_fallback (3-variable ceiling min,
  Codex #2 correction: min(configured, len(judgments_full32))) + 3-tier usable predicate
  (status + catalog + optional capacity) + trace 8 fields (requested/default/configured_extended/
  judgments_count/effective_extended_ceiling/effective_max_rank/usable_count/policy_applied)
- u3: 2 production call site cleanup (max_rank=3 removed, HEAD baseline) + tracked
  Front/vite.config.ts PHASE_Z_MAX_RANK env retired + 4 regression scenarios

verified: 32 passed (IMP-38 focused scope) — IMP-05 L4 dedup / L2 schema preserved,
IMP-30 allow_provisional byte-identical, caller_override backward compat (tests)

Stage cycle (#67, 7 round Claude + 5 round Codex):
- Stage 1: Claude #1 -> Codex #1 YES + 5 corrections
- Stage 2 r1+r2: Claude #2-#4 -> Codex #2 Q2 -> Codex #3 YES (4 round consensus LOCK 23195)
- Stage 3 U1+U2+U3: Claude #5-#9 -> Codex #6 NO 4to3 correction -> Codex #7 YES -> Codex #8 YES
- Stage 4: Claude #11 -> Codex #9 (anchor attribution nuance) -> Codex #10 readiness -> Codex #11

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 22:14:05 +09:00
73a98b8ad1 IMP-04 F17 schema correction — paired_rows_4x2 + pill alternation + source-faithful theme
source = 8 atomic issues (4 paired rows × 2 cells per texts.md), 이전 strict-4
가 source 의 절반 누락. round 55~73 review-loop 의 calibration frame.

- contract : source_shape=top_bullets / layout_variant=paired_rows_4x2_alternating_pills
  / strict 8 (no pad/truncate) / role_order row_{1..4}_{left,right} / visual_hints
  pill_positions + row_gap_after / builder paired_rows_4x2_slots
- builder : new _build_paired_rows_4x2_slots — 2-axis (row × side) deterministic
  index mapping, strict 8 raises before render, quadrant_item parser 재사용
- partial : 4-row × 2-cell flex, pill alternation (row 1/3 top, row 2/4 bottom
  via column-reverse), row 2-3 visual gap, source-faithful color (rgb(204,82,0)
  →rgb(136,55,0) title + #60A451 row border + rgba(250,237,203,0.15) bg + #0c271e
  body + 2px dashed #60A451 cell 분할선), pill = CSS approximation (asset crop
  variant single-pass 비용 高 → fallback per Codex round 62/68 scope cap, pill
  shape + alternation + green/cream/brown theme 보존), no row headers (source
  부재, inference 금지)
- fixture : flat 8 top-bullet (texts.md 8 issues 그대로)
- smoke + R3 : PASS (11/11 self-check, 5535 chars partial, 8 units rendered,
  pill alternation 정합, row 2-3 gap, no invented row headers)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 15:13:46 +09:00
f7a9240fe5 fix(IMP-04): F18 F1 follow-ups — defaults + narrow alias + cardinality clarify
Same-frame F1 follow-up per Codex round 43 (#15527). matrix §4.1 Fix 7
4-class F1 path (no Track A pause, small fixes + Codex re-review).

Three fixes :

1. F1-a — explicit col_a/col_b label defaults
   - Previous (c7b0f5b) used empty defaults `col_a_label_default: ""` /
     `col_b_label_default: ""`, so an upstream MDX path without explicit
     column headers would render blank header cells.
   - Fix : set `col_a_label_default: "BIM"` and `col_b_label_default: "DX"`
     in F18 contract. Frame intent is the BIM-vs-DX comparison, so the
     headers are semantic and must not silently become blank.

2. F1-b — narrow prefix-stripping aliases (parser → builder option)
   - Previous parser used a broad regex
     `^[A-Za-z가-힣]{1,8}\s*:\s*(.+)$` to strip any short prefix before
     `:`. That could accidentally remove meaningful Korean/English
     prefixes from real cell content.
   - Fix : remove auto-stripping from `parse_compare_row_2col_item`.
     Stripping is now configurable via builder option
     `strip_col_prefix_aliases: [<list of exact aliases>]` and applied
     by `_build_compare_table_2col`. F18 contract uses `["BIM", "DX"]`,
     so only `BIM:` / `DX:` (with optional fullwidth `:`) prefixes are
     stripped; other Korean/English colons in real content stay intact.
   - Parser signature unchanged. Builder is the single place that owns
     the stripping policy.

3. F1-c — cardinality semantic clarification
   - Previous top-level `cardinality.strict: 2` was ambiguous: it could
     be read as `row strict: 2`. Rows are actually `1..12` via
     `sub_zones.rows.cardinality`.
   - Fix : add YAML comment that the top-level strict 2 = column count
     (col_a / col_b), not row count. Per-sub_zone cardinality remains
     authoritative for rows.

Verification :
- python -m py_compile src/phase_z2_mapper.py : PASS
- python scripts/smoke_frame_render.py --self-check : PASS 7/7 (F18
  fixture rendered unchanged at 4211 chars; smoke harness only loaded
  the partial, builder/parser logic not directly exercised in smoke)
- Manual builder/parser invocation test with synthetic units :
  - col_a_label / col_b_label resolve to "BIM" / "DX" defaults.
  - `BIM: Only 3D` → `Only 3D` (alias-stripped).
  - `DX: BIM << DX (ENG. 포함)` → `BIM << DX (ENG. 포함)` (alias-stripped).
  - `분야별 단절` → `분야별 단절` (no BIM/DX prefix, untouched).
  - This matches the F1-b narrow-alias intent.
- python scripts/smoke_frame_render.py bim_dx_comparison_table
  --render-to data/runs/imp04_f18_visual_r2 : PASS, R3 artifact written
  with same character count, generic viewer title.

scope-lock honored : no V4 logic, no new builder/parser added (only
behavior refinement of existing F18 builder/parser/contract), no other
partial, no Phase Z production render, no Phase R'/AI/Kei changes.

4-class status (F18 post-F1) :
- class 1 readiness : adapter cleanup complete — defaults explicit,
  aliases narrow, cardinality semantically clear.
- class 2 content-fit : still a watch item (long Korean wrapping,
  6+ rows). max_rows=12 protection unchanged.
- class 3 / 4 : N/A.

Refs Gitea #4 (IMP-04 Track A frame 4 — F1 follow-up per Codex round 43)
2026-05-13 12:21:02 +09:00
c7b0f5bde1 feat(catalog): activate bim_dx_comparison_table (IMP-04 Track A 4/16)
Reason : V4 UAI=1 (01-2 "용어간 상호관계") — UAI tier strongest after F12/F11.
Track A frame 4 per Codex round 41 V4-priority acceptance.

3-layer architecture (matrix §0) :
- V4 = matching authority — V4 ranked this frame use_as_is for 01-2.
- figma_to_html (1171281195) = source/evidence — analysis/texts/index.html/
  flat/assets all present.
- Phase Z = runtime orchestration — adds catalog + new builder + new parser +
  new partial + smoke fixture.

NEW builder + NEW parser (Codex round 41 mandatory review path) :

1. src/phase_z2_mapper.py — NEW `compare_row_2col_item` parser in ITEM_PARSERS
   - input : (top_line, nested_lines)
   - output : {label, col_a, col_b}
   - label = bold from top_line
   - col_a / col_b = first 2 nested bullets, optional prefix stripping ("BIM:"/
     "DX:" or similar ≤8-char tag with colon)
   - inline emphasis preserved as <strong>

2. src/phase_z2_mapper.py — NEW `compare_table_2col` PAYLOAD_BUILDERS entry
   - payload : title + col_a_label + col_b_label + rows[]
   - builder_options : item_parser, col_a/b_label_default, max_rows (default 999)
   - max_rows truncation tracked via _truncated_count

3. templates/phase_z2/families/bim_dx_comparison_table.html — NEW partial
   - 3-column grid (category / col_a / col_b) with header row + N data rows
   - PROMOTED CSS : title gradient (#000#883700, zone-title family), header
     brown bg (rgba(50,31,9,0.85-0.95)), zebra striping, brown family bullet
     accent, subtle border (#A5BBB4 F11 family).
   - NOT PROMOTED (P1 case-by-case + preservation guardrail) : Figma column
     header raster icons, color emphasis variants, hanja deco. figma_to_html
     source evidence remains preserved.
   - ADAPTED : Figma absolute positioning + zoom → Phase Z flex/grid 3-col
     table, typography → token-fixed, row heights auto content-fit.

4. templates/phase_z2/catalog/frame_contracts.yaml — F18 contract appended
   - frame_id=1171281195, family=table, source_shape=top_bullets, strict 2
     (2 columns), role_order=[col_a, col_b].
   - visual_hints.min_height_px = 350 (title 30 + header 30 + 6 rows×35 +
     padding 30 = 300 + 50 buffer; F14-class).
   - accepted_content_types = [text_block].
   - sub_zones : col_a_header / col_b_header (strict 1 each) + rows (min 1,
     max 12 category rows).

5. scripts/smoke_frame_render.py — bundled fixture for F18 self-check (6
   category rows : 범위 / S/W / 프로세스 / 성과물 / 활용 / 수행개념).

Verification :
- python -m py_compile src/phase_z2_mapper.py scripts/smoke_frame_render.py
  : PASS
- python scripts/smoke_frame_render.py --self-check : PASS 7/7 (F18 added
  at 4211 chars CSS-only)
- python scripts/smoke_frame_render.py bim_dx_comparison_table --render-to
  data/runs/imp04_f18_visual : PASS, R3 artifact, 0 raster refs (CSS-only)
- python run_mdx03_pipeline.py --phase-z2 --run-id imp04_f18_regression :
  PASS (MDX 03 V4 rank-1 still F13/F29; F18 only routes 01-2 per V4)

scope-lock honored (3-layer + 4-class) :
- V4 logic / V4 evidence yaml : unchanged
- Existing PAYLOAD_BUILDERS (4 builders) : unchanged. compare_table_2col added
  as NEW entry.
- Existing ITEM_PARSERS (2 parsers) : unchanged. compare_row_2col_item added
  as NEW entry.
- Existing 6 partials : unchanged.
- Composition planner / production render / Phase R' / AI/Kei : unchanged.

4-class status :
- class 1 readiness :  contract + new builder + new parser + partial +
  smoke fixture + R3 artifact aligned.
- class 2 content-fit : watch — cell content single-line; long Korean
  sentences may wrap. Row height auto handles wrap; max_rows=12 limit
  protects vertical overflow.
- class 3/4 : N/A.

Codex review mandatory per scope-lock §5 (new builder pattern first
introduction : compare_table_2col).

Refs Gitea #4 (IMP-04 Track A frame 4 — V4 UAI tier, NEW builder)
2026-05-13 12:13:11 +09:00
c67609c083 feat(catalog): activate construction_goals_three_circle_intersection (IMP-04 Track A 2/16)
Reason : V4 strongest UAI tier candidate (use_as_is=1 for 02-1, light_edit=1
for 01-1, restructure=1). Track A frame 2 per Codex rounds 30/33/35 V4-
priority rule. F14 clean pass completed at 834ed39; this is the next
Track A activation.

3-layer architecture context (matrix §0) :
- V4 = matching authority — V4 ranked this frame as use_as_is for the
  "DX의 궁극적 목표" section (02-1) and light_edit for "용어 정의" (01-1).
- figma_to_html (1171281189) = rich source/evidence — 510-line index.html
  base, full analysis/flat/texts/assets present (A+T+I+F+S).
- Phase Z = runtime orchestration — this commit adds the runtime contract,
  builder, partial, and fixture so the V4 candidate can be assembled.

New runtime additions :

1. src/phase_z2_mapper.py — new `cycle_intersect_3` PAYLOAD_BUILDERS entry
   - Reuses existing `quadrant_item` ITEM_PARSERS (label only, body
     ignored) — F16 parser reused, no new parser.
   - Produces flat keys : circle_1_label / circle_2_label / circle_3_label
     + intersection text (optional) — distinct from F16's quadrant_N_body
     structure since this frame's 3 main circles use labels only.
   - pad_to=3, truncate_at=3, configurable via builder_options.

2. templates/phase_z2/families/construction_goals_three_circle_intersection.html
   - Adapted from figma_to_html_agent/blocks/1171281189/index.html.
   - Slot mapping : title + 3 circle labels + optional intersection text.
   - PROMOTED CSS : 3 circle gradients (safety #BC652B/#A24200, productivity
     #897445/#3E3523, trust #296B55/#123328) + outer multiply blend +
     title gradient (#000#883700, F13/F14 zone-title family) + main
     label typography (white text + shadow).
   - NOT PROMOTED (P1 case-by-case, compact zone fit) : 6 accent hanja
     circles (安/質/速/利/通/信), 6 side labels (안전성 제고 etc.), 3
     decoration rects, 3 arc images, bg-texture multiply image. These
     are Figma-side decorative content not in MDX and would clutter a
     Phase Z zone of ~320 px.
   - ADAPTED : Figma 70/50/40 px → token-fixed font sizes, 350×350
     absolute-positioned overlapping circles → 110×110 flex row (cycle
     intent expressed via intersection text instead of geometric overlap).

3. templates/phase_z2/catalog/frame_contracts.yaml — append F12 contract
   - template_id, frame_id 1171281189, family=diagram, source_shape=
     top_bullets, strict cardinality 3, role_order [safety, productivity,
     trust].
   - visual_hints.min_height_px = 320, derived from 3 circle row 80 +
     title 30 + label area 60 + intersection 30 + padding 40 = 240
     + 80 safety buffer (lighter than F14's 350 since CSS-only).
   - accepted_content_types = [text_block] only.
   - 4 sub_zones declared (circle_1/2/3 main_text + intersection emphasis).

4. scripts/smoke_frame_render.py — add bundled fixture for F12 self-check.

Verification :
- python -m py_compile src/phase_z2_mapper.py scripts/smoke_frame_render.py
  : PASS
- python scripts/smoke_frame_render.py --self-check : PASS 5/5 (F12 added
  at 3691 chars CSS-only)
- python scripts/smoke_frame_render.py construction_goals_three_circle_intersection
  --render-to data/runs/imp04_f12_visual : PASS, R3 artifact written. 0
  raster refs (CSS-only partial); copy_assets ran successfully and
  produced data/runs/imp04_f12_visual/assets/construction_goals_three_circle_intersection/
  with the frame's 4 PNG files (unused since partial is CSS-only — assets
  remain available for future raster promotion if visual inspection
  flags fidelity loss).
- python run_mdx03_pipeline.py --phase-z2 --run-id imp04_f12_regression
  : PASS (MDX 03 V4 rank-1 still F13/F29, F12 not selected — F12 only
  triggered by 02-1 / 01-1 sections per V4 evidence)

scope-lock honored : V4 logic / V4 evidence / mapper existing builders /
composition planner / Phase R' / pipeline production render path / AI/Kei
all unchanged. New builder added without modifying existing 3 (mixed
strategy per scope-lock §4).

Calibration status (matrix §4.1 Fix 7 4-class) :
- class 1 adapter readiness : new builder registered, partial loadable,
  contract valid, smoke passing.
- class 2 content-fit : compact 110×110 circles + label, watch for label
  overflow if MDX bullets exceed ~12 chars.
- class 3/4 mapping/routing : not applicable for this commit.
- Codex review mandatory per scope-lock §5 (new builder pattern
  cycle_intersect_3 first introduction).

Refs Gitea #4 (IMP-04 Track A frame 2 — V4 strongest UAI tier)
2026-05-13 11:50:44 +09:00
e7848b602d Add Phase Z runtime foundation
- add visual fit classifier, router, retry, and failure routing modules
- add composition planner and catalog-driven mapper
- add Phase Z pipeline orchestration and architecture docs
2026-05-04 08:21:28 +09:00