feat(catalog): activate dx_sw_necessity_three_perspectives (IMP-04 Track A 5/16)
Reason : V4 LE=2 (03-1 + 01-1) + RS=1 — V4 LE tier strongest remaining
after F12/F11/F18 UAI tier. Track A frame 5 per Codex round 45 V4-priority
acceptance.
3-layer architecture (matrix §0) :
- V4 = matching authority — V4 ranked this frame light_edit for 03-1 (DX 시행
필수 요건) and 01-1 (용어 정의).
- figma_to_html (1171281198) = source/evidence — 386-line index.html + assets/.
- Phase Z = runtime — this commit adds catalog + partial + smoke fixture.
Builder reuse (no new builder/parser introduced) :
- Reuses existing `quadrant_flat_slots` builder (F16/F11 pattern) with
pad_to=3 + `perspective_{n}_label` / `perspective_{n}_body` keys.
- Reuses existing `quadrant_item` parser.
- Same flat-keyed label+body grammar as F11; only N=3 + key names differ.
- mapper.py unchanged — secondary builder reuse per Codex round 45.
3 file changes :
1. templates/phase_z2/families/dx_sw_necessity_three_perspectives.html
- Adapted from figma_to_html_agent/blocks/1171281198/index.html.
- 3-column grid (BIM 전면설계 / 디지털 전환 S/W / 고부가가치 산업전환).
- PROMOTED CSS : header bar dark green (#296B55 → #123328 Figma green
family), header text white bold, title gradient (#000 → #883700
F13/F14/F12/F11/F18 zone-title family), card border + bullet markers
(green family).
- NOT PROMOTED (P1 case-by-case + preservation guardrail per Codex
round 37) : 상단 dark green banner ("디지털 전환(DX)은 S/W가 필수다"
visual block), 좌측 DX circular area (multi-image + center text +
decor — main rhetorical anchor but cannot fit compact zone),
hanmaek/한자/배경 텍스처. figma_to_html source evidence preserved.
- ADAPTED : Figma 90/65/40 px → token-fixed, 1280×426 absolute +
zoom → Phase Z 3-column grid, 3 perspective cards → flex column.
2. templates/phase_z2/catalog/frame_contracts.yaml
- F20 contract appended.
- frame_id=1171281198, family=cards, source_shape=top_bullets, strict 3,
role_order=[perspective_1, perspective_2, perspective_3].
- visual_hints.min_height_px = 320 (3 col × header 30 + body bullets ~75
+ title 30 + padding 30 = ~195 + 125 buffer for label/5+ bullet
overflow; F12/F11/F18 class).
- accepted_content_types = [text_block].
- 3 sub_zones (perspective_1/2/3 main_text).
- payload.builder = quadrant_flat_slots (reuse) with perspective_{n}_*
key patterns.
3. scripts/smoke_frame_render.py — bundled fixture for F20 self-check.
Verification :
- python scripts/smoke_frame_render.py --self-check : PASS 8/8 (F20 added
at 3160 chars CSS-only)
- python scripts/smoke_frame_render.py dx_sw_necessity_three_perspectives
--render-to data/runs/imp04_f20_visual : PASS, R3 artifact, 0 raster
refs (CSS-only)
- python run_mdx03_pipeline.py --phase-z2 --run-id imp04_f20_regression :
PASS (MDX 03 V4 rank-1 still F13/F29; F20 light_edit candidate for 03-1
but F13 was use_as_is at higher rank, so F20 not selected here)
scope-lock honored (3-layer + 4-class) :
- V4 logic / V4 evidence yaml : unchanged
- Existing PAYLOAD_BUILDERS (5 builders) : unchanged. No new builder added.
- Existing ITEM_PARSERS (3 parsers) : unchanged. No new parser added.
- Existing 7 partials : unchanged.
- Composition planner / production render / Phase R' / AI/Kei : unchanged.
4-class status :
- class 1 readiness : ✅ contract + builder reuse + partial + smoke fixture
+ R3 artifact aligned.
- class 2 content-fit : watch — header single-line, body 3-5 bullets per
column. 6+ bullets per column may overflow.
- class 3/4 : N/A.
Codex review remains useful (per scope-lock §5 "shared catalog/builder
logic" category — quadrant_flat_slots is now reused by F16/F11/F20). New
builder/parser path is NOT this commit.
Refs Gitea #4 (IMP-04 Track A frame 5 — V4 LE tier, builder reuse)
This commit is contained in:
@@ -218,6 +218,27 @@ _MOCK_BIM_DX_COMPARISON = {
|
|||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Track A frame 5 — dx_sw_necessity_three_perspectives (frame 20).
|
||||||
|
# Builder reuse = quadrant_flat_slots (F11 pattern) — pad_to=3, perspective_N keys.
|
||||||
|
_MOCK_DX_SW_NECESSITY = {
|
||||||
|
"title": "디지털 전환(DX)은 S/W가 필수다",
|
||||||
|
"perspective_1_label": "BIM 전면설계",
|
||||||
|
"perspective_1_body": [
|
||||||
|
{"text": "건설산업 생산성 향상", "indent": 0},
|
||||||
|
{"text": "고부가가치 산업 전환", "indent": 0},
|
||||||
|
],
|
||||||
|
"perspective_2_label": "디지털 전환 S/W",
|
||||||
|
"perspective_2_body": [
|
||||||
|
{"text": "노동집약형 업무 탈피", "indent": 0},
|
||||||
|
{"text": "S/W 고도화 + 투자 필요", "indent": 0},
|
||||||
|
],
|
||||||
|
"perspective_3_label": "고부가가치 산업전환",
|
||||||
|
"perspective_3_body": [
|
||||||
|
{"text": "기본기술 이해 발전 필요", "indent": 0},
|
||||||
|
{"text": "DX 통한 Process 혁신", "indent": 0},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
SELF_CHECK_FIXTURES: dict[str, dict] = {
|
SELF_CHECK_FIXTURES: dict[str, dict] = {
|
||||||
"three_parallel_requirements": _MOCK_THREE_PARALLEL,
|
"three_parallel_requirements": _MOCK_THREE_PARALLEL,
|
||||||
"process_product_two_way": _MOCK_PROCESS_PRODUCT,
|
"process_product_two_way": _MOCK_PROCESS_PRODUCT,
|
||||||
@@ -226,6 +247,7 @@ SELF_CHECK_FIXTURES: dict[str, dict] = {
|
|||||||
"construction_goals_three_circle_intersection": _MOCK_CONSTRUCTION_GOALS,
|
"construction_goals_three_circle_intersection": _MOCK_CONSTRUCTION_GOALS,
|
||||||
"construction_bim_three_usage": _MOCK_CONSTRUCTION_BIM_USAGE,
|
"construction_bim_three_usage": _MOCK_CONSTRUCTION_BIM_USAGE,
|
||||||
"bim_dx_comparison_table": _MOCK_BIM_DX_COMPARISON,
|
"bim_dx_comparison_table": _MOCK_BIM_DX_COMPARISON,
|
||||||
|
"dx_sw_necessity_three_perspectives": _MOCK_DX_SW_NECESSITY,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -451,3 +451,67 @@ bim_dx_comparison_table:
|
|||||||
- "BIM"
|
- "BIM"
|
||||||
- "DX"
|
- "DX"
|
||||||
max_rows: 12 # typical 4-8, overflow 보호
|
max_rows: 12 # typical 4-8, overflow 보호
|
||||||
|
|
||||||
|
|
||||||
|
dx_sw_necessity_three_perspectives:
|
||||||
|
# Reason : V4 LE=2 (03-1 + 01-1) + RS=1 — V4 LE tier strongest 잔여.
|
||||||
|
# Pattern : cards / cards-3-header — 3 columns horizontal (DX 필수성 3 관점).
|
||||||
|
# Track A frame 5 (Codex round 45 accepted, V4 priority strict).
|
||||||
|
# builder 재사용 = `quadrant_flat_slots` (F16/F11 pattern). 새 builder/parser 0.
|
||||||
|
template_id: dx_sw_necessity_three_perspectives
|
||||||
|
frame_id: 1171281198
|
||||||
|
family: cards
|
||||||
|
|
||||||
|
source_shape: top_bullets
|
||||||
|
cardinality:
|
||||||
|
strict: 3 # 3 perspective columns
|
||||||
|
overflow_policy: abort_or_review
|
||||||
|
|
||||||
|
# 순서 기반 role naming (3 perspective 각자 color 도 다를 수 있음 — 단순 ordering).
|
||||||
|
role_order:
|
||||||
|
- perspective_1
|
||||||
|
- perspective_2
|
||||||
|
- perspective_3
|
||||||
|
|
||||||
|
# min_height_px derivation :
|
||||||
|
# 3 column × (header 30 + body bullets ~3 × 25) + title 30 + padding 30 = ~ 195.
|
||||||
|
# safety buffer (label 길고 body 5+ bullets 보호) = 125 → **320**.
|
||||||
|
# F12/F11/F18 와 동등 class. confirm via smoke + R3.
|
||||||
|
visual_hints:
|
||||||
|
min_height_px: 320
|
||||||
|
|
||||||
|
accepted_content_types:
|
||||||
|
- text_block
|
||||||
|
|
||||||
|
# Frame Slot 선언 : 3 perspective columns (각 column = label + body).
|
||||||
|
sub_zones:
|
||||||
|
- id: perspective_1
|
||||||
|
role: main_text
|
||||||
|
accepts: [text_block]
|
||||||
|
cardinality: { strict: 1 }
|
||||||
|
partial_target_path: ".f20b__cols > .f20b__col:nth-child(1)"
|
||||||
|
- id: perspective_2
|
||||||
|
role: main_text
|
||||||
|
accepts: [text_block]
|
||||||
|
cardinality: { strict: 1 }
|
||||||
|
partial_target_path: ".f20b__cols > .f20b__col:nth-child(2)"
|
||||||
|
- id: perspective_3
|
||||||
|
role: main_text
|
||||||
|
accepts: [text_block]
|
||||||
|
cardinality: { strict: 1 }
|
||||||
|
partial_target_path: ".f20b__cols > .f20b__col:nth-child(3)"
|
||||||
|
|
||||||
|
payload:
|
||||||
|
title:
|
||||||
|
source: section.title
|
||||||
|
# Builder 재사용 = `quadrant_flat_slots` (F16/F11 pattern).
|
||||||
|
# 새 builder / 새 parser 0. F18 같은 새 builder 도입 아님 (Codex round 45 secondary reuse 허용).
|
||||||
|
builder: quadrant_flat_slots
|
||||||
|
builder_options:
|
||||||
|
item_parser: quadrant_item # F16/F11 의 parser 재사용
|
||||||
|
pad_to: 3 # 3 perspectives
|
||||||
|
truncate_at: 3
|
||||||
|
label_key_pattern: "perspective_{n}_label"
|
||||||
|
body_key_pattern: "perspective_{n}_body"
|
||||||
|
empty_label: ""
|
||||||
|
empty_body: []
|
||||||
|
|||||||
@@ -0,0 +1,158 @@
|
|||||||
|
<!-- Phase Z-2 MVP-1.5b frame-derived adapted block.
|
||||||
|
§17 룰 — Figma 시각 언어 promote, geometry 만 zone-compatible adapt. -->
|
||||||
|
{#
|
||||||
|
─────────────────────────────────────────────────────────────────────────────
|
||||||
|
Visual Provenance — figma_to_html_agent/blocks/1171281198/ (frame 20)
|
||||||
|
─────────────────────────────────────────────────────────────────────────────
|
||||||
|
Frame 20 = "디지털 전환(DX)은 S/W가 필수다" (cards-3-header). Figma 원본 =
|
||||||
|
상단 dark green banner ("디지털 전환(DX)은 S/W가 필수다" green/white mix) +
|
||||||
|
좌측 DX circular area + 우측 3 perspective cards (BIM 전면설계 / 디지털
|
||||||
|
전환 S/W / 고부가가치 산업전환).
|
||||||
|
|
||||||
|
본 partial = Track A frame 5 (Codex round 45 accepted, V4 LE tier strongest).
|
||||||
|
builder 재사용 = `quadrant_flat_slots` (F11 cards-3-category pattern). 새
|
||||||
|
builder/parser 0.
|
||||||
|
|
||||||
|
3-layer architecture (matrix §0) :
|
||||||
|
- V4 = matching authority — V4 ranked this frame light_edit for 03-1 + 01-1.
|
||||||
|
- figma_to_html (1171281198) = source/evidence — 386-line index.html + assets/.
|
||||||
|
- Phase Z = runtime — 본 commit adds catalog + partial + smoke fixture.
|
||||||
|
|
||||||
|
PROMOTED — CSS :
|
||||||
|
- 3 column header bg : dark green (`#296B55` family, Figma green theme)
|
||||||
|
- header text white bold + green accent
|
||||||
|
- title gradient (#000 → #883700, F13/F14/F12/F11/F18 zone-title family)
|
||||||
|
- card border + bullet markers (green family)
|
||||||
|
|
||||||
|
NOT PROMOTED (P1 case-by-case, compact zone fit) :
|
||||||
|
- 상단 dark green banner (Figma 의 큰 visual 영역, MDX 의 *title 만* 핵심)
|
||||||
|
- 좌측 DX circular area (multi-image + center text + decor — Figma 의 main
|
||||||
|
rhetorical anchor 단 compact zone 에서 표현 불가). title 의 gradient 로 의도 보존
|
||||||
|
- 한자/장식/배경 텍스처 — Figma source evidence 보존, 미 promote
|
||||||
|
|
||||||
|
ADAPTED :
|
||||||
|
- Figma 90/65/40px → token-fixed (zone-title 13 / sub-title 12 / caption / body 11)
|
||||||
|
- 1280×426 absolute positioning + zoom → Phase Z 3-column grid
|
||||||
|
- 3 perspective cards (header + body) → flex column
|
||||||
|
─────────────────────────────────────────────────────────────────────────────
|
||||||
|
min_height_px derivation :
|
||||||
|
3 col × (header 30 + body 3-bullets × 25) + title 30 + padding 30 = ~195
|
||||||
|
+ safety buffer (longer label / 5+ bullets) 125 = **320**. F12/F11/F18 class.
|
||||||
|
─────────────────────────────────────────────────────────────────────────────
|
||||||
|
slots :
|
||||||
|
- title : section.title
|
||||||
|
- perspective_1/2/3_label : 3 column headers
|
||||||
|
- perspective_1/2/3_body : list[{text, indent}] : 3 column bullets
|
||||||
|
─────────────────────────────────────────────────────────────────────────────
|
||||||
|
4-class failure taxonomy :
|
||||||
|
- class 1 readiness : builder reuse `quadrant_flat_slots` + `quadrant_item`.
|
||||||
|
contract + partial + smoke fixture.
|
||||||
|
- class 2 content-fit : header label 짧게 (single line). body 3-5 bullets per
|
||||||
|
column (zone fit). 6+ bullets 시 watch.
|
||||||
|
#}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.f20b {
|
||||||
|
width: 100%; height: 100%;
|
||||||
|
display: flex; flex-direction: column;
|
||||||
|
gap: 6px;
|
||||||
|
font-family: 'Noto Sans KR', 'Pretendard', sans-serif;
|
||||||
|
word-break: keep-all;
|
||||||
|
}
|
||||||
|
.f20b__title {
|
||||||
|
font-size: var(--font-zone-title);
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: var(--lh-zone-title);
|
||||||
|
background-image: linear-gradient(180deg, #000 0%, #883700 100%);
|
||||||
|
-webkit-background-clip: text; background-clip: text;
|
||||||
|
color: transparent;
|
||||||
|
flex-shrink: 0;
|
||||||
|
filter: drop-shadow(0 0 3px rgba(50,44,30,0.4));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 3-column grid — Figma cards-3-header pattern */
|
||||||
|
.f20b__cols {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr 1fr;
|
||||||
|
gap: 10px;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
.f20b__col {
|
||||||
|
display: flex; flex-direction: column;
|
||||||
|
border: 2px solid #296B55; /* PROMOTED — green family from Figma */
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
background: #fff;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* header bar (top of each card, dark green per Figma) */
|
||||||
|
.f20b__header {
|
||||||
|
background: linear-gradient(180deg, #296B55 0%, #123328 100%); /* PROMOTED — Figma green theme */
|
||||||
|
color: #fff;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: var(--font-sub-title);
|
||||||
|
line-height: 1.15;
|
||||||
|
padding: 6px 10px;
|
||||||
|
text-align: center;
|
||||||
|
flex-shrink: 0;
|
||||||
|
letter-spacing: -0.04em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* body — bullet list (CSS check marker, F14 pattern) */
|
||||||
|
.f20b__body {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 6px 10px 8px;
|
||||||
|
color: #1a1a1a;
|
||||||
|
min-height: 0;
|
||||||
|
display: flex; flex-direction: column;
|
||||||
|
gap: 3px;
|
||||||
|
}
|
||||||
|
.f20b__body .text-line {
|
||||||
|
color: inherit;
|
||||||
|
font-size: var(--font-body);
|
||||||
|
line-height: var(--lh-body);
|
||||||
|
position: relative;
|
||||||
|
padding-left: 14px;
|
||||||
|
}
|
||||||
|
.f20b__body .text-line--bullet::before {
|
||||||
|
content: "\2713"; /* ✓ check mark — green theme */
|
||||||
|
position: absolute;
|
||||||
|
left: 0; top: 0;
|
||||||
|
color: #296B55; /* PROMOTED — green family */
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="f20b" data-frame-id="1171281198" data-template-id="dx_sw_necessity_three_perspectives">
|
||||||
|
<div class="f20b__title">{{ slot_payload.title }}</div>
|
||||||
|
<div class="f20b__cols">
|
||||||
|
{# 3 columns — quadrant_flat_slots produces perspective_N_label / perspective_N_body for N=1..3 #}
|
||||||
|
<div class="f20b__col">
|
||||||
|
<div class="f20b__header">{{ slot_payload.perspective_1_label | safe }}</div>
|
||||||
|
<div class="f20b__body">
|
||||||
|
{% if slot_payload.perspective_1_body %}
|
||||||
|
{% for line in slot_payload.perspective_1_body %}<div class="text-line text-line--bullet{% if line.indent > 0 %} text-line--indent-{{ line.indent }}{% endif %}">{{ line.text | safe }}</div>{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="f20b__col">
|
||||||
|
<div class="f20b__header">{{ slot_payload.perspective_2_label | safe }}</div>
|
||||||
|
<div class="f20b__body">
|
||||||
|
{% if slot_payload.perspective_2_body %}
|
||||||
|
{% for line in slot_payload.perspective_2_body %}<div class="text-line text-line--bullet{% if line.indent > 0 %} text-line--indent-{{ line.indent }}{% endif %}">{{ line.text | safe }}</div>{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="f20b__col">
|
||||||
|
<div class="f20b__header">{{ slot_payload.perspective_3_label | safe }}</div>
|
||||||
|
<div class="f20b__body">
|
||||||
|
{% if slot_payload.perspective_3_body %}
|
||||||
|
{% for line in slot_payload.perspective_3_body %}<div class="text-line text-line--bullet{% if line.indent > 0 %} text-line--indent-{{ line.indent }}{% endif %}">{{ line.text | safe }}</div>{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
Reference in New Issue
Block a user