Add stage-based retry loop regeneration

This commit is contained in:
2026-04-02 10:55:18 +09:00
parent b864872d1a
commit 2d52427898
23 changed files with 594 additions and 377 deletions

View File

@@ -0,0 +1,44 @@
{
"concepts": [
{
"topic_id": 1,
"relation_type": "cause_effect",
"expression_hint": "오해의 원인과 그 결과를 짧고 분명하게 보여주는 문제 제기 블록이 적절하다. 사례는 전부 펼치지 말고 대표 사례만 연결한다.",
"source_data": "DX/BIM 혼용, BIM 도입을 DX 완성으로 오인, DX를 BIM 수준으로 축소하는 인식"
},
{
"topic_id": 2,
"relation_type": "definition",
"expression_hint": "DX 정의는 본심의 시작점으로 크고 선명하게 제시한다. 단순 기술 도입이 아니라 산업 전환이라는 점이 강조되어야 한다. 본문 첫 블록에서 DX는 상위 개념, BIM은 핵심 기술이라는 문구를 그대로 가시 텍스트로 노출한다.",
"source_data": "DX 정의와 상위 개념 설명",
"summary": "DX는 상위 개념이고 BIM은 핵심 기술이다."
},
{
"topic_id": 3,
"relation_type": "hierarchy",
"expression_hint": "DX가 상위, BIM/GIS/디지털 트윈이 하위 핵심기술이라는 계층 구조를 시각적으로 드러내야 한다. 이미지 참조는 반드시 유지하고, 본문 또는 캡션에 `[이미지: DX와 핵심기술간 상호관계, 경로: /assets/images/DX1.png]` 또는 `[그림 1] DX와 핵심기술간 상호관계`가 보이는 텍스트로 남아야 한다. 관계도는 팝업이나 숨김영역이 아니라 본문 중앙의 가시 다이어그램으로 렌더링한다.",
"source_data": "BIM 정의, DX와 핵심기술 상호관계, 이미지 참조, [이미지: DX와 핵심기술간 상호관계, 경로: /assets/images/DX1.png], [그림 1] DX와 핵심기술간 상호관계",
"summary": "DX와 GIS, BIM, Digital Twin의 관계를 시각적으로 드러낸다."
},
{
"topic_id": 4,
"relation_type": "definition",
"expression_hint": "정책 혼용 사례는 본문을 방해하지 않는 보조 카드 또는 사이드바 근거 리스트가 적절하다. 길게 설명하지 않는다.",
"source_data": "스마트 건설 활성화 방안, 제7차 건설기술진흥 기본계획 사례"
},
{
"topic_id": 5,
"relation_type": "comparison",
"expression_hint": "비교표 전체를 숨긴 팝업으로 처리하지 말고, 핵심 4개 비교축을 화면에 보이는 요약 리스트나 카드로 유지한다. 최소한 범위, 프로세스, 성과품, 확장성의 비교 문장은 가시 텍스트로 남겨야 한다. 범위, 프로세스, 성과품, 확장성 4개 비교축을 sidebar의 가시 요약 카드로 직접 노출한다.",
"source_data": "범위: DX는 BIM을 포함하는 상위 개념 / BIM은 Only 3D 중심. 프로세스: DX는 근본적 문제의식을 통한 개선 / BIM은 기존 2D 설계 방식 유지. 성과품: DX는 공학 정보 및 콘텐츠 연계 / BIM은 3D 모델 중심. 확장성: DX는 전 생애주기 활용 시스템 / BIM은 분야별 단절 위험.",
"summary": "범위·프로세스·성과품·확장성의 4개 비교축으로 DX와 BIM 차이를 짧고 직접적으로 보여준다."
},
{
"topic_id": 6,
"relation_type": "none",
"expression_hint": "한 줄 결론을 강하게 강조하는 footer 또는 key message 배너가 적절하다. 문구는 축약하지 않는다. footer 또는 결론 배너에서 문장을 축약하지 말고 그대로 강하게 노출한다.",
"source_data": "BIM은 DX 수행 과정의 가장 기초가 되는 일부분",
"summary": "결론: BIM은 건설산업 DX를 수행하는 과정의 가장 기초가 되는 일부분이다."
}
]
}

View File

@@ -0,0 +1,44 @@
{
"concepts": [
{
"topic_id": 1,
"relation_type": "cause_effect",
"expression_hint": "오해의 원인과 그 결과를 짧고 분명하게 보여주는 문제 제기 블록이 적절하다. 사례는 전부 펼치지 말고 대표 사례만 연결한다.",
"source_data": "DX/BIM 혼용, BIM 도입을 DX 완성으로 오인, DX를 BIM 수준으로 축소하는 인식"
},
{
"topic_id": 2,
"relation_type": "definition",
"expression_hint": "DX 정의는 본심의 시작점으로 크고 선명하게 제시한다. 단순 기술 도입이 아니라 산업 전환이라는 점이 강조되어야 한다. 본문 첫 블록에서 DX는 상위 개념, BIM은 핵심 기술이라는 문구를 그대로 가시 텍스트로 노출한다.",
"source_data": "DX 정의와 상위 개념 설명",
"summary": "DX는 상위 개념이고 BIM은 핵심 기술이다."
},
{
"topic_id": 3,
"relation_type": "hierarchy",
"expression_hint": "DX가 상위, BIM/GIS/디지털 트윈이 하위 핵심기술이라는 계층 구조를 시각적으로 드러내야 한다. 이미지 참조는 반드시 유지하고, 본문 또는 캡션에 `[이미지: DX와 핵심기술간 상호관계, 경로: /assets/images/DX1.png]` 또는 `[그림 1] DX와 핵심기술간 상호관계`가 보이는 텍스트로 남아야 한다. 관계도는 팝업이나 숨김영역이 아니라 본문 중앙의 가시 다이어그램으로 렌더링한다.",
"source_data": "BIM 정의, DX와 핵심기술 상호관계, 이미지 참조, [이미지: DX와 핵심기술간 상호관계, 경로: /assets/images/DX1.png], [그림 1] DX와 핵심기술간 상호관계",
"summary": "DX와 GIS, BIM, Digital Twin의 관계를 시각적으로 드러낸다."
},
{
"topic_id": 4,
"relation_type": "definition",
"expression_hint": "정책 혼용 사례는 본문을 방해하지 않는 보조 카드 또는 사이드바 근거 리스트가 적절하다. 길게 설명하지 않는다.",
"source_data": "스마트 건설 활성화 방안, 제7차 건설기술진흥 기본계획 사례"
},
{
"topic_id": 5,
"relation_type": "comparison",
"expression_hint": "비교표 전체를 숨긴 팝업으로 처리하지 말고, 핵심 4개 비교축을 화면에 보이는 요약 리스트나 카드로 유지한다. 최소한 범위, 프로세스, 성과품, 확장성의 비교 문장은 가시 텍스트로 남겨야 한다. 범위, 프로세스, 성과품, 확장성 4개 비교축을 sidebar의 가시 요약 카드로 직접 노출한다.",
"source_data": "범위: DX는 BIM을 포함하는 상위 개념 / BIM은 Only 3D 중심. 프로세스: DX는 근본적 문제의식을 통한 개선 / BIM은 기존 2D 설계 방식 유지. 성과품: DX는 공학 정보 및 콘텐츠 연계 / BIM은 3D 모델 중심. 확장성: DX는 전 생애주기 활용 시스템 / BIM은 분야별 단절 위험.",
"summary": "범위·프로세스·성과품·확장성의 4개 비교축으로 DX와 BIM 차이를 짧고 직접적으로 보여준다."
},
{
"topic_id": 6,
"relation_type": "none",
"expression_hint": "한 줄 결론을 강하게 강조하는 footer 또는 key message 배너가 적절하다. 문구는 축약하지 않는다. footer 또는 결론 배너에서 문장을 축약하지 말고 그대로 강하게 노출한다.",
"source_data": "BIM은 DX 수행 과정의 가장 기초가 되는 일부분",
"summary": "결론: BIM은 건설산업 DX를 수행하는 과정의 가장 기초가 되는 일부분이다."
}
]
}

View File

@@ -0,0 +1,55 @@
{
"rollback_stage": "stage_1b",
"failures": [
"Verify-ComparisonVisible",
"Verify-CoreMessage",
"Verify-DesignStructure",
"Verify-RenderZone"
],
"reasons": [
"가시 메시지/관계도/비교 요약이 부족하여 topic 표현 지시를 다시 강화해야 함",
"overflow가 발생하여 budget/문장 길이/보조 정보 밀도를 재조정해야 함"
],
"mutations": [
{
"topic_id": 2,
"change": "summary",
"strategy": "core_message_strengthen"
},
{
"topic_id": 3,
"change": "expression_hint",
"strategy": "force_relation_diagram_visible"
},
{
"topic_id": 5,
"change": "expression_hint",
"strategy": "force_visible_comparison_summary"
},
{
"topic_id": 6,
"change": "summary",
"strategy": "strong_footer_conclusion"
},
{
"role": "배경",
"change": "budget",
"strategy": "compress_visible_copy"
},
{
"role": "결론",
"change": "budget",
"strategy": "compress_visible_copy"
},
{
"area": "body_bg",
"change": "verification",
"strategy": "reduce_density_and_split_visibility"
},
{
"area": "body_core",
"change": "verification",
"strategy": "reduce_density_and_split_visibility"
}
]
}

View File

@@ -1,40 +1,44 @@
{
"concepts": [
{
"topic_id": 1,
"relation_type": "cause_effect",
"expression_hint": "오해의 원인과 그 결과를 짧고 분명하게 보여주는 문제 제기 블록이 적절하다. 사례는 전부 펼치지 말고 대표 사례만 연결한다.",
"source_data": "DX/BIM 혼용, BIM 도입을 DX 완성으로 오인, DX를 BIM 수준으로 축소하는 인식"
},
{
"topic_id": 2,
"relation_type": "definition",
"expression_hint": "DX 정의는 본심의 시작점으로 크고 선명하게 제시한다. 단순 기술 도입이 아니라 산업 전환이라는 점이 강조되어야 한다.",
"source_data": "DX 정의와 상위 개념 설명"
},
{
"topic_id": 3,
"relation_type": "hierarchy",
"expression_hint": "DX가 상위, BIM/GIS/디지털 트윈이 하위 핵심기술이라는 계층 구조를 시각적으로 드러내야 한다. 이미지 참조는 반드시 유지하고, 본문 또는 캡션에 `[이미지: DX와 핵심기술간 상호관계, 경로: /assets/images/DX1.png]` 또는 `[그림 1] DX와 핵심기술간 상호관계`가 보이는 텍스트로 남아야 한다.",
"source_data": "BIM 정의, DX와 핵심기술 상호관계, 이미지 참조, [이미지: DX와 핵심기술간 상호관계, 경로: /assets/images/DX1.png], [그림 1] DX와 핵심기술간 상호관계"
},
{
"topic_id": 4,
"relation_type": "definition",
"expression_hint": "정책 혼용 사례는 본문을 방해하지 않는 보조 카드 또는 사이드바 근거 리스트가 적절하다. 길게 설명하지 않는다.",
"source_data": "스마트 건설 활성화 방안, 제7차 건설기술진흥 기본계획 사례"
},
{
"topic_id": 5,
"relation_type": "comparison",
"expression_hint": "비교표 전체를 숨긴 팝업으로 처리하지 말고, 핵심 4개 비교축을 화면에 보이는 요약 리스트나 카드로 유지한다. 최소한 범위, 프로세스, 성과품, 확장성의 비교 문장은 가시 텍스트로 남겨야 한다.",
"source_data": "범위: DX는 BIM을 포함하는 상위 개념 / BIM은 Only 3D 중심. 프로세스: DX는 근본적 문제의식을 통한 개선 / BIM은 기존 2D 설계 방식 유지. 성과품: DX는 공학 정보 및 콘텐츠 연계 / BIM은 3D 모델 중심. 확장성: DX는 전 생애주기 활용 시스템 / BIM은 분야별 단절 위험."
},
{
"topic_id": 6,
"relation_type": "none",
"expression_hint": "한 줄 결론을 강하게 강조하는 footer 또는 key message 배너가 적절하다. 문구는 축약하지 않는다.",
"source_data": "BIM은 DX 수행 과정의 가장 기초가 되는 일부분"
}
]
{
"concepts": [
{
"topic_id": 1,
"relation_type": "cause_effect",
"expression_hint": "오해의 원인과 그 결과를 짧고 분명하게 보여주는 문제 제기 블록이 적절하다. 사례는 전부 펼치지 말고 대표 사례만 연결한다.",
"source_data": "DX/BIM 혼용, BIM 도입을 DX 완성으로 오인, DX를 BIM 수준으로 축소하는 인식"
},
{
"topic_id": 2,
"relation_type": "definition",
"expression_hint": "DX 정의는 본심의 시작점으로 크고 선명하게 제시한다. 단순 기술 도입이 아니라 산업 전환이라는 점이 강조되어야 한다. 본문 첫 블록에서 DX는 상위 개념, BIM은 핵심 기술이라는 문구를 그대로 가시 텍스트로 노출한다.",
"source_data": "DX 정의와 상위 개념 설명",
"summary": "DX는 상위 개념이고 BIM은 핵심 기술이다."
},
{
"topic_id": 3,
"relation_type": "hierarchy",
"expression_hint": "DX가 상위, BIM/GIS/디지털 트윈이 하위 핵심기술이라는 계층 구조를 시각적으로 드러내야 한다. 이미지 참조는 반드시 유지하고, 본문 또는 캡션에 `[이미지: DX와 핵심기술간 상호관계, 경로: /assets/images/DX1.png]` 또는 `[그림 1] DX와 핵심기술간 상호관계`가 보이는 텍스트로 남아야 한다. 관계도는 팝업이나 숨김영역이 아니라 본문 중앙의 가시 다이어그램으로 렌더링한다.",
"source_data": "BIM 정의, DX와 핵심기술 상호관계, 이미지 참조, [이미지: DX와 핵심기술간 상호관계, 경로: /assets/images/DX1.png], [그림 1] DX와 핵심기술간 상호관계",
"summary": "DX와 GIS, BIM, Digital Twin의 관계를 시각적으로 드러낸다."
},
{
"topic_id": 4,
"relation_type": "definition",
"expression_hint": "정책 혼용 사례는 본문을 방해하지 않는 보조 카드 또는 사이드바 근거 리스트가 적절하다. 길게 설명하지 않는다.",
"source_data": "스마트 건설 활성화 방안, 제7차 건설기술진흥 기본계획 사례"
},
{
"topic_id": 5,
"relation_type": "comparison",
"expression_hint": "비교표 전체를 숨긴 팝업으로 처리하지 말고, 핵심 4개 비교축을 화면에 보이는 요약 리스트나 카드로 유지한다. 최소한 범위, 프로세스, 성과품, 확장성의 비교 문장은 가시 텍스트로 남겨야 한다. 범위, 프로세스, 성과품, 확장성 4개 비교축을 sidebar의 가시 요약 카드로 직접 노출한다.",
"source_data": "범위: DX는 BIM을 포함하는 상위 개념 / BIM은 Only 3D 중심. 프로세스: DX는 근본적 문제의식을 통한 개선 / BIM은 기존 2D 설계 방식 유지. 성과품: DX는 공학 정보 및 콘텐츠 연계 / BIM은 3D 모델 중심. 확장성: DX는 전 생애주기 활용 시스템 / BIM은 분야별 단절 위험.",
"summary": "범위·프로세스·성과품·확장성의 4개 비교축으로 DX와 BIM 차이를 짧고 직접적으로 보여준다."
},
{
"topic_id": 6,
"relation_type": "none",
"expression_hint": "한 줄 결론을 강하게 강조하는 footer 또는 key message 배너가 적절하다. 문구는 축약하지 않는다. footer 또는 결론 배너에서 문장을 축약하지 말고 그대로 강하게 노출한다.",
"source_data": "BIM은 DX 수행 과정의 가장 기초가 되는 일부분",
"summary": "결론: BIM은 건설산업 DX를 수행하는 과정의 가장 기초가 되는 일부분이다."
}
]
}

File diff suppressed because one or more lines are too long

View File

@@ -153,44 +153,29 @@
<div class="slide-title" style="grid-area: header;">건설산업 DX의 올바른 이해</div>
<div class="area-body" style="overflow:hidden;">
<div style="width:100%; height:100%; box-sizing:border-box; font-family:'Segoe UI',sans-serif; color:#0f172a; display:flex; flex-direction:column; gap:12px;">
<div style="display:flex; align-items:flex-start; justify-content:space-between; gap:14px;">
<div style="flex:1; background:linear-gradient(135deg,#0f172a 0%,#1d4ed8 100%); color:#ffffff; border-radius:14px; padding:18px 20px; box-sizing:border-box; box-shadow:0 12px 28px rgba(15,23,42,0.18);">
<div style="font-size:11px; font-weight:700; letter-spacing:0.08em; text-transform:uppercase; color:#93c5fd; margin-bottom:8px;">Core Message</div>
<div style="font-size:23px; font-weight:800; line-height:1.22; margin-bottom:8px;">DX는 상위 개념, BIM은 핵심 기술</div>
<div style="font-size:12px; line-height:1.55; color:rgba(255,255,255,0.92);">건설산업에서 DX는 상위 개념이고 BIM은 그 디지털 전환을 가능하게 하는 핵심 기술 중 하나다.</div>
</div>
<div style="width:170px; background:#fff7ed; border:1px solid #fdba74; border-radius:14px; padding:14px 14px 12px; box-sizing:border-box;">
<div style="font-size:10px; font-weight:700; color:#c2410c; margin-bottom:8px; text-transform:uppercase; letter-spacing:0.06em;">Problem</div>
<div style="font-size:11px; line-height:1.55; color:#7c2d12;">건설산업에서는 DX와 BIM이 자주 혼용되며, BIM 도입이 곧 DX 완성이라는 오해가 생긴다.</div>
</div>
<div style="width:100%; height:100%; box-sizing:border-box; font-family:'Segoe UI',sans-serif; color:#0f172a; display:flex; flex-direction:column; gap:14px;">
<div style="background:linear-gradient(135deg,#0f172a 0%,#1d4ed8 100%); color:#ffffff; border-radius:16px; padding:20px 22px; box-sizing:border-box;">
<div style="font-size:11px; font-weight:700; letter-spacing:0.08em; text-transform:uppercase; color:#93c5fd; margin-bottom:8px;">Core Message</div>
<div style="font-size:24px; font-weight:800; line-height:1.18; margin-bottom:10px;">DX는 상위 개념, BIM은 핵심 기술</div>
<div style="font-size:12px; line-height:1.6; color:rgba(255,255,255,0.92);">건설산업에서 DX는 상위 개념이고 BIM은 그 디지털 전환을 가능하게 하는 핵심 기술 중 하나다.</div>
</div>
<div class="relation-diagram-card" style="background:linear-gradient(180deg,#eff6ff 0%,#f8fafc 100%); border:1px solid #bfdbfe; border-radius:16px; padding:18px; box-sizing:border-box; box-shadow:0 8px 18px rgba(59,130,246,0.10);">
<div style="display:flex; align-items:center; justify-content:space-between; margin-bottom:14px; gap:14px;">
<div class="relation-diagram-card" style="background:#f8fafc; border:1px solid #cbd5e1; border-radius:16px; padding:16px 18px; box-sizing:border-box;">
<div style="display:flex; justify-content:space-between; align-items:flex-start; gap:12px; margin-bottom:12px;">
<div>
<div style="font-size:11px; font-weight:700; color:#2563eb; letter-spacing:0.08em; text-transform:uppercase; margin-bottom:6px;">Relation Map</div>
<div style="font-size:18px; font-weight:800; color:#0f172a; line-height:1.25;">건설산업 DX를 이루는 핵심 기술 관계</div>
<div style="font-size:11px; font-weight:700; color:#2563eb; letter-spacing:0.08em; text-transform:uppercase; margin-bottom:5px;">Relation Map</div>
<div style="font-size:18px; font-weight:800; color:#0f172a; line-height:1.25;">건설산업 DX의 올바른 이해</div>
</div>
<div style="font-size:11px; color:#166534; background:#dcfce7; border:1px solid #86efac; border-radius:999px; padding:6px 10px; white-space:nowrap;">[그림 1] DX와 핵심기술간 상호관계</div>
<div style="font-size:10px; color:#166534; background:#dcfce7; border:1px solid #86efac; border-radius:999px; padding:5px 9px; white-space:nowrap;">[그림 1] DX와 핵심기술간 상호관계</div>
</div>
<div style="display:flex; flex-direction:column; align-items:center; gap:10px;">
<div style="min-width:190px; text-align:center; background:#1d4ed8; color:#ffffff; border-radius:999px; padding:10px 18px; font-size:16px; font-weight:800; box-shadow:0 8px 18px rgba(37,99,235,0.22);">DX</div>
<div style="width:2px; height:20px; background:linear-gradient(180deg,#60a5fa 0%,#94a3b8 100%);"></div>
<div style="width:100%; display:flex; justify-content:center; gap:12px;">
<div style="flex:1; max-width:150px; background:#ffffff; border:1px solid #cbd5e1; border-radius:12px; padding:10px 10px 12px; text-align:center; box-sizing:border-box;">
<div style="font-size:12px; font-weight:800; color:#0f172a; margin-bottom:4px;">GIS</div>
<div style="font-size:10px; line-height:1.45; color:#475569;">공간정보와 위치기반 분석</div>
</div>
<div style="flex:1; max-width:170px; background:linear-gradient(180deg,#dbeafe 0%,#eff6ff 100%); border:2px solid #3b82f6; border-radius:12px; padding:10px 10px 12px; text-align:center; box-sizing:border-box; box-shadow:0 10px 22px rgba(59,130,246,0.16); transform:translateY(-2px);">
<div style="font-size:12px; font-weight:800; color:#1d4ed8; margin-bottom:4px;">BIM</div>
<div style="font-size:10px; line-height:1.45; color:#334155;">형상+내용정보 기반 핵심 기술</div>
</div>
<div style="flex:1; max-width:150px; background:#ffffff; border:1px solid #cbd5e1; border-radius:12px; padding:10px 10px 12px; text-align:center; box-sizing:border-box;">
<div style="font-size:12px; font-weight:800; color:#0f172a; margin-bottom:4px;">Digital Twin</div>
<div style="font-size:10px; line-height:1.45; color:#475569;">가상환경 기반 통합 운영</div>
</div>
<div style="font-size:11px; line-height:1.6; color:#334155; margin-bottom:12px;">DX와 GIS, BIM, Digital Twin의 관계를 시각적으로 드러낸다.</div>
<div style="display:flex; align-items:center; justify-content:center; gap:10px;">
<div style="min-width:120px; text-align:center; background:#1d4ed8; color:#ffffff; border-radius:999px; padding:10px 16px; font-size:15px; font-weight:800;">DX</div>
<div style="font-size:16px; color:#94a3b8;"></div>
<div style="display:flex; gap:8px; flex-wrap:wrap; justify-content:center;">
<div style="background:#ffffff; border:1px solid #cbd5e1; border-radius:12px; padding:10px 12px; font-size:11px; font-weight:700;">GIS</div>
<div style="background:#dbeafe; border:2px solid #3b82f6; border-radius:12px; padding:10px 12px; font-size:11px; font-weight:800; color:#1d4ed8;">BIM</div>
<div style="background:#ffffff; border:1px solid #cbd5e1; border-radius:12px; padding:10px 12px; font-size:11px; font-weight:700;">Digital Twin</div>
</div>
</div>
</div>
@@ -199,7 +184,7 @@
<div class="area-sidebar" style="overflow:hidden;">
<div style="width:100%; height:100%; box-sizing:border-box; font-family:'Segoe UI',sans-serif; display:flex; flex-direction:column; gap:12px;">
<div class="comparison-summary-card" style="background:#ffffff; border:1px solid #cbd5e1; border-radius:14px; overflow:hidden; box-shadow:0 10px 22px rgba(15,23,42,0.08);">
<div class="comparison-summary-card" style="background:#ffffff; border:1px solid #cbd5e1; border-radius:14px; overflow:hidden;">
<div style="padding:12px 14px; background:linear-gradient(135deg,#eff6ff 0%,#dbeafe 100%); border-bottom:1px solid #bfdbfe;">
<div style="font-size:10.0px; font-weight:700; color:#1d4ed8; letter-spacing:0.08em; text-transform:uppercase; margin-bottom:4px;">Comparison</div>
<div style="font-size:10.0px; font-weight:800; color:#0f172a;">DX와 BIM 핵심 비교</div>
@@ -210,20 +195,20 @@
<div style="font-weight:800; color:#0f172a;">성과품</div><div>DX는 공학 정보 및 콘텐츠 연계, BIM은 3D 모델 중심</div>
<div style="font-weight:800; color:#0f172a;">확장성</div><div>DX는 전 생애주기 활용 시스템, BIM은 분야별 단절 위험</div>
</div>
<div style="padding:0 14px 12px; font-size:10px; color:#475569; line-height:1.5;">범위·프로세스·성과품·확장성의 4개 비교축으로 DX와 BIM 차이를 짧고 직접적으로 보여준다.</div>
</div>
<div style="background:#f8fafc; border:1px solid #cbd5e1; border-radius:14px; padding:14px; box-sizing:border-box;">
<div style="font-size:10.0px; font-weight:700; color:#475569; letter-spacing:0.08em; text-transform:uppercase; margin-bottom:6px;">Evidence</div>
<div style="font-size:10.0px; font-weight:800; color:#0f172a; margin-bottom:8px;">정책 문서에서도 혼용</div>
<div style="font-size:10px; line-height:1.55; color:#475569;">• 스마트 건설 활성화 방안: 디지털화 방향 아래 BIM 전면 도입 제시</div>
<div style="font-size:10px; line-height:1.55; color:#475569;">• 제7차 건설기술진흥 기본계획: DX 추진 방향 아래 BIM 도입 실행 과제 제시</div>
<div style="font-size:10px; line-height:1.55; color:#475569;">정책 문서에서 DX와 BIM을 혼용한 대표 사례를 보조 근거로 제시한다.</div>
</div>
</div>
</div>
<div class="area-footer" style="overflow:hidden;">
<div style="background:linear-gradient(90deg,#0f766e 0%,#0ea5a3 100%); border-radius:12px; padding:14px 24px; text-align:center; color:#ffffff; width:100%; height:60px; display:flex; flex-direction:column; justify-content:center; box-sizing:border-box; box-shadow:0 10px 24px rgba(15,118,110,0.20);">
<div style="font-size:14px; font-weight:800; line-height:1.35;">결론: BIM은 DX 수행 과정의 가장 기초가 되는 일부분</div>
<div style="background:linear-gradient(90deg,#0f766e 0%,#0ea5a3 100%); border-radius:12px; padding:14px 24px; text-align:center; color:#ffffff; width:100%; height:60px; display:flex; flex-direction:column; justify-content:center; box-sizing:border-box;">
<div style="font-size:13px; font-weight:800; line-height:1.35;">결론: BIM은 건설산업 DX 수행하는 과정의 가장 기초가 되는 일부분이다.</div>
</div>
</div>
</div>

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,6 @@
{
"body_html": "<div style=\"width:100%; height:100%; box-sizing:border-box; font-family:'Segoe UI',sans-serif; color:#0f172a; display:flex; flex-direction:column; gap:12px;\">\n <div style=\"display:flex; align-items:flex-start; justify-content:space-between; gap:14px;\">\n <div style=\"flex:1; background:linear-gradient(135deg,#0f172a 0%,#1d4ed8 100%); color:#ffffff; border-radius:14px; padding:18px 20px; box-sizing:border-box; box-shadow:0 12px 28px rgba(15,23,42,0.18);\">\n <div style=\"font-size:11px; font-weight:700; letter-spacing:0.08em; text-transform:uppercase; color:#93c5fd; margin-bottom:8px;\">Core Message</div>\n <div style=\"font-size:23px; font-weight:800; line-height:1.22; margin-bottom:8px;\">DX는 상위 개념, BIM은 핵심 기술</div>\n <div style=\"font-size:12px; line-height:1.55; color:rgba(255,255,255,0.92);\">건설산업에서 DX는 상위 개념이고 BIM은 그 디지털 전환을 가능하게 하는 핵심 기술 중 하나다.</div>\n </div>\n <div style=\"width:170px; background:#fff7ed; border:1px solid #fdba74; border-radius:14px; padding:14px 14px 12px; box-sizing:border-box;\">\n <div style=\"font-size:10px; font-weight:700; color:#c2410c; margin-bottom:8px; text-transform:uppercase; letter-spacing:0.06em;\">Problem</div>\n <div style=\"font-size:11px; line-height:1.55; color:#7c2d12;\">건설산업에서는 DX와 BIM이 자주 혼용되며, BIM 도입이 곧 DX 완성이라는 오해가 생긴다.</div>\n </div>\n </div>\n\n <div class=\"relation-diagram-card\" style=\"background:linear-gradient(180deg,#eff6ff 0%,#f8fafc 100%); border:1px solid #bfdbfe; border-radius:16px; padding:18px; box-sizing:border-box; box-shadow:0 8px 18px rgba(59,130,246,0.10);\">\n <div style=\"display:flex; align-items:center; justify-content:space-between; margin-bottom:14px; gap:14px;\">\n <div>\n <div style=\"font-size:11px; font-weight:700; color:#2563eb; letter-spacing:0.08em; text-transform:uppercase; margin-bottom:6px;\">Relation Map</div>\n <div style=\"font-size:18px; font-weight:800; color:#0f172a; line-height:1.25;\">건설산업 DX를 이루는 핵심 기술 관계</div>\n </div>\n <div style=\"font-size:11px; color:#166534; background:#dcfce7; border:1px solid #86efac; border-radius:999px; padding:6px 10px; white-space:nowrap;\">[그림 1] DX와 핵심기술간 상호관계</div>\n </div>\n\n <div style=\"display:flex; flex-direction:column; align-items:center; gap:10px;\">\n <div style=\"min-width:190px; text-align:center; background:#1d4ed8; color:#ffffff; border-radius:999px; padding:10px 18px; font-size:16px; font-weight:800; box-shadow:0 8px 18px rgba(37,99,235,0.22);\">DX</div>\n <div style=\"width:2px; height:20px; background:linear-gradient(180deg,#60a5fa 0%,#94a3b8 100%);\"></div>\n <div style=\"width:100%; display:flex; justify-content:center; gap:12px;\">\n <div style=\"flex:1; max-width:150px; background:#ffffff; border:1px solid #cbd5e1; border-radius:12px; padding:10px 10px 12px; text-align:center; box-sizing:border-box;\">\n <div style=\"font-size:12px; font-weight:800; color:#0f172a; margin-bottom:4px;\">GIS</div>\n <div style=\"font-size:10px; line-height:1.45; color:#475569;\">공간정보와 위치기반 분석</div>\n </div>\n <div style=\"flex:1; max-width:170px; background:linear-gradient(180deg,#dbeafe 0%,#eff6ff 100%); border:2px solid #3b82f6; border-radius:12px; padding:10px 10px 12px; text-align:center; box-sizing:border-box; box-shadow:0 10px 22px rgba(59,130,246,0.16); transform:translateY(-2px);\">\n <div style=\"font-size:12px; font-weight:800; color:#1d4ed8; margin-bottom:4px;\">BIM</div>\n <div style=\"font-size:10px; line-height:1.45; color:#334155;\">형상+내용정보 기반 핵심 기술</div>\n </div>\n <div style=\"flex:1; max-width:150px; background:#ffffff; border:1px solid #cbd5e1; border-radius:12px; padding:10px 10px 12px; text-align:center; box-sizing:border-box;\">\n <div style=\"font-size:12px; font-weight:800; color:#0f172a; margin-bottom:4px;\">Digital Twin</div>\n <div style=\"font-size:10px; line-height:1.45; color:#475569;\">가상환경 기반 통합 운영</div>\n </div>\n </div>\n </div>\n </div>\n</div>",
"sidebar_html": "<div style=\"width:100%; height:100%; box-sizing:border-box; font-family:'Segoe UI',sans-serif; display:flex; flex-direction:column; gap:12px;\">\n <div class=\"comparison-summary-card\" style=\"background:#ffffff; border:1px solid #cbd5e1; border-radius:14px; overflow:hidden; box-shadow:0 10px 22px rgba(15,23,42,0.08);\">\n <div style=\"padding:12px 14px; background:linear-gradient(135deg,#eff6ff 0%,#dbeafe 100%); border-bottom:1px solid #bfdbfe;\">\n <div style=\"font-size:11px; font-weight:700; color:#1d4ed8; letter-spacing:0.08em; text-transform:uppercase; margin-bottom:4px;\">Comparison</div>\n <div style=\"font-size:16px; font-weight:800; color:#0f172a;\">DX와 BIM 핵심 비교</div>\n </div>\n <div style=\"padding:10px 14px 12px; display:grid; grid-template-columns:80px 1fr; row-gap:8px; column-gap:10px; font-size:10px; line-height:1.45; color:#334155;\">\n <div style=\"font-weight:800; color:#0f172a;\">범위</div><div>DX는 BIM을 포함하는 상위 개념, BIM은 3D 중심 기술</div>\n <div style=\"font-weight:800; color:#0f172a;\">프로세스</div><div>DX는 근본적 개선, BIM은 기존 2D 설계 방식 연장</div>\n <div style=\"font-weight:800; color:#0f172a;\">성과품</div><div>DX는 공학 정보 및 콘텐츠 연계, BIM은 3D 모델 중심</div>\n <div style=\"font-weight:800; color:#0f172a;\">확장성</div><div>DX는 전 생애주기 활용 시스템, BIM은 분야별 단절 위험</div>\n </div>\n </div>\n\n <div style=\"background:#f8fafc; border:1px solid #cbd5e1; border-radius:14px; padding:14px; box-sizing:border-box;\">\n <div style=\"font-size:11px; font-weight:700; color:#475569; letter-spacing:0.08em; text-transform:uppercase; margin-bottom:6px;\">Evidence</div>\n <div style=\"font-size:14px; font-weight:800; color:#0f172a; margin-bottom:8px;\">정책 문서에서도 혼용</div>\n <div style=\"font-size:10px; line-height:1.55; color:#475569;\">• 스마트 건설 활성화 방안: 디지털화 방향 아래 BIM 전면 도입 제시</div>\n <div style=\"font-size:10px; line-height:1.55; color:#475569;\">• 제7차 건설기술진흥 기본계획: DX 추진 방향 아래 BIM 도입 실행 과제 제시</div>\n </div>\n</div>",
"footer_html": "<div style=\"background:linear-gradient(90deg,#0f766e 0%,#0ea5a3 100%); border-radius:12px; padding:14px 24px; text-align:center; color:#ffffff; width:100%; height:60px; display:flex; flex-direction:column; justify-content:center; box-sizing:border-box; box-shadow:0 10px 24px rgba(15,118,110,0.20);\">\n <div style=\"font-size:14px; font-weight:800; line-height:1.35;\">결론: BIM은 DX 수행 과정의 가장 기초가 되는 일부분</div>\n</div>",
"reasoning": "auto_loop_runner slide-style regeneration with relation map, visible comparison, and strong conclusion"
"body_html": "<div style=\"width:100%; height:100%; box-sizing:border-box; font-family:'Segoe UI',sans-serif; color:#0f172a; display:flex; flex-direction:column; gap:14px;\">\n <div style=\"background:linear-gradient(135deg,#0f172a 0%,#1d4ed8 100%); color:#ffffff; border-radius:16px; padding:20px 22px; box-sizing:border-box;\">\n <div style=\"font-size:11px; font-weight:700; letter-spacing:0.08em; text-transform:uppercase; color:#93c5fd; margin-bottom:8px;\">Core Message</div>\n <div style=\"font-size:24px; font-weight:800; line-height:1.18; margin-bottom:10px;\">DX는 상위 개념, BIM은 핵심 기술</div>\n <div style=\"font-size:12px; line-height:1.6; color:rgba(255,255,255,0.92);\">건설산업에서 DX는 상위 개념이고 BIM은 그 디지털 전환을 가능하게 하는 핵심 기술 중 하나다.</div>\n </div>\n\n <div class=\"relation-diagram-card\" style=\"background:#f8fafc; border:1px solid #cbd5e1; border-radius:16px; padding:16px 18px; box-sizing:border-box;\">\n <div style=\"display:flex; justify-content:space-between; align-items:flex-start; gap:12px; margin-bottom:12px;\">\n <div>\n <div style=\"font-size:11px; font-weight:700; color:#2563eb; letter-spacing:0.08em; text-transform:uppercase; margin-bottom:5px;\">Relation Map</div>\n <div style=\"font-size:18px; font-weight:800; color:#0f172a; line-height:1.25;\">건설산업 DX의 올바른 이해</div>\n </div>\n <div style=\"font-size:10px; color:#166534; background:#dcfce7; border:1px solid #86efac; border-radius:999px; padding:5px 9px; white-space:nowrap;\">[그림 1] DX와 핵심기술간 상호관계</div>\n </div>\n <div style=\"font-size:11px; line-height:1.6; color:#334155; margin-bottom:12px;\">DX와 GIS, BIM, Digital Twin의 관계를 시각적으로 드러낸다.</div>\n <div style=\"display:flex; align-items:center; justify-content:center; gap:10px;\">\n <div style=\"min-width:120px; text-align:center; background:#1d4ed8; color:#ffffff; border-radius:999px; padding:10px 16px; font-size:15px; font-weight:800;\">DX</div>\n <div style=\"font-size:16px; color:#94a3b8;\"></div>\n <div style=\"display:flex; gap:8px; flex-wrap:wrap; justify-content:center;\">\n <div style=\"background:#ffffff; border:1px solid #cbd5e1; border-radius:12px; padding:10px 12px; font-size:11px; font-weight:700;\">GIS</div>\n <div style=\"background:#dbeafe; border:2px solid #3b82f6; border-radius:12px; padding:10px 12px; font-size:11px; font-weight:800; color:#1d4ed8;\">BIM</div>\n <div style=\"background:#ffffff; border:1px solid #cbd5e1; border-radius:12px; padding:10px 12px; font-size:11px; font-weight:700;\">Digital Twin</div>\n </div>\n </div>\n </div>\n</div>",
"sidebar_html": "<div style=\"width:100%; height:100%; box-sizing:border-box; font-family:'Segoe UI',sans-serif; display:flex; flex-direction:column; gap:12px;\">\n <div class=\"comparison-summary-card\" style=\"background:#ffffff; border:1px solid #cbd5e1; border-radius:14px; overflow:hidden;\">\n <div style=\"padding:12px 14px; background:linear-gradient(135deg,#eff6ff 0%,#dbeafe 100%); border-bottom:1px solid #bfdbfe;\">\n <div style=\"font-size:11px; font-weight:700; color:#1d4ed8; letter-spacing:0.08em; text-transform:uppercase; margin-bottom:4px;\">Comparison</div>\n <div style=\"font-size:16px; font-weight:800; color:#0f172a;\">DX와 BIM 핵심 비교</div>\n </div>\n <div style=\"padding:10px 14px 12px; display:grid; grid-template-columns:80px 1fr; row-gap:8px; column-gap:10px; font-size:10px; line-height:1.45; color:#334155;\">\n <div style=\"font-weight:800; color:#0f172a;\">범위</div><div>DX는 BIM을 포함하는 상위 개념, BIM은 3D 중심 기술</div>\n <div style=\"font-weight:800; color:#0f172a;\">프로세스</div><div>DX는 근본적 개선, BIM은 기존 2D 설계 방식 연장</div>\n <div style=\"font-weight:800; color:#0f172a;\">성과품</div><div>DX는 공학 정보 및 콘텐츠 연계, BIM은 3D 모델 중심</div>\n <div style=\"font-weight:800; color:#0f172a;\">확장성</div><div>DX는 전 생애주기 활용 시스템, BIM은 분야별 단절 위험</div>\n </div>\n <div style=\"padding:0 14px 12px; font-size:10px; color:#475569; line-height:1.5;\">범위·프로세스·성과품·확장성의 4개 비교축으로 DX와 BIM 차이를 짧고 직접적으로 보여준다.</div>\n </div>\n\n <div style=\"background:#f8fafc; border:1px solid #cbd5e1; border-radius:14px; padding:14px; box-sizing:border-box;\">\n <div style=\"font-size:11px; font-weight:700; color:#475569; letter-spacing:0.08em; text-transform:uppercase; margin-bottom:6px;\">Evidence</div>\n <div style=\"font-size:14px; font-weight:800; color:#0f172a; margin-bottom:8px;\">정책 문서에서도 혼용</div>\n <div style=\"font-size:10px; line-height:1.55; color:#475569;\">정책 문서에서 DX와 BIM을 혼용한 대표 사례를 보조 근거로 제시한다.</div>\n </div>\n</div>",
"footer_html": "<div style=\"background:linear-gradient(90deg,#0f766e 0%,#0ea5a3 100%); border-radius:12px; padding:14px 24px; text-align:center; color:#ffffff; width:100%; height:60px; display:flex; flex-direction:column; justify-content:center; box-sizing:border-box;\">\n <div style=\"font-size:13px; font-weight:800; line-height:1.35;\">결론: BIM은 건설산업 DX 수행하는 과정의 가장 기초가 되는 일부분이다.</div>\n</div>",
"reasoning": "stage_2 retry regeneration from rollback plan: stage_1b"
}

View File

@@ -10,26 +10,26 @@
"body": {
"block_count": 0,
"blocks": [],
"clientHeight": 412,
"clientHeight": 362,
"excess_px": 0,
"overflowed": false,
"scrollHeight": 412
"scrollHeight": 362
},
"footer": {
"block_count": 0,
"blocks": [],
"clientHeight": 91,
"clientHeight": 116,
"excess_px": 0,
"overflowed": false,
"scrollHeight": 91
"scrollHeight": 116
},
"sidebar": {
"block_count": 0,
"blocks": [],
"clientHeight": 412,
"clientHeight": 362,
"excess_px": 0,
"overflowed": false,
"scrollHeight": 412
"scrollHeight": 362
}
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -30,26 +30,26 @@
"body": {
"block_count": 0,
"blocks": [],
"clientHeight": 412,
"clientHeight": 362,
"excess_px": 0,
"overflowed": false,
"scrollHeight": 412
"scrollHeight": 362
},
"footer": {
"block_count": 0,
"blocks": [],
"clientHeight": 91,
"clientHeight": 116,
"excess_px": 0,
"overflowed": false,
"scrollHeight": 91
"scrollHeight": 116
},
"sidebar": {
"block_count": 0,
"blocks": [],
"clientHeight": 412,
"clientHeight": 362,
"excess_px": 0,
"overflowed": false,
"scrollHeight": 412
"scrollHeight": 362
}
}
}

View File

@@ -2,8 +2,7 @@
- auto_loop_runner.py iteration 1로 실행했다.
- 입력: `docs/run-001/01-input/01. 건설산업 DX의 올바른 이해(0127).mdx`
- 산출물: `final.html`, `generated_html.json`, `measurement.json`, `context.json`
- 비교 요약 가시 블록 보강: 적용
- 슬라이드형 재생성 적용: 예
- stage snapshot: `stage_0_context.json` ~ `final_context.json`
산출물 경로
- `docs/run-001/05-execution/final.html`
@@ -27,3 +26,4 @@ KPI / 판정 결과
- 최신 실행 산출물
- 최신 measurement
- 최신 context
- stage snapshot 묶음

View File

@@ -2,13 +2,13 @@
- iteration 1 기준으로 최종 산출물과 측정 결과를 다시 검증했다.
- slide overflow: False
- zone overflow: 없음
- 슬라이드형 재생성 적용: 예
- 최종 판정은 `pass`이다.
산출물 경로
- `docs/run-001/06-validation/validation-result.md`
- `docs/run-001/05-execution/final.html`
- `docs/run-001/05-execution/measurement.json`
- `docs/run-001/05-execution/stage_2_verification.json`
KPI / 판정 결과
- 판정: pass

View File

@@ -7,6 +7,7 @@ import re
import subprocess
import sys
from pathlib import Path
from typing import Any
ROOT = Path(__file__).resolve().parents[1]
if str(ROOT) not in sys.path:
@@ -40,126 +41,6 @@ def strip_tags(text: str) -> str:
return re.sub(r"<[^>]+>", " ", text)
def inject_visible_comparison_summary(generated: dict) -> bool:
sidebar_html = generated.get("sidebar_html", "")
if COMPARISON_MARKER in sidebar_html:
return False
card = """
<div class=\"comparison-summary-card\" style=\"margin-top:10px; background:#eff6ff; border:1px solid #bfdbfe; border-radius:8px; padding:12px;\">
<div style=\"font-size:11px; font-weight:700; color:#1e3a8a; margin-bottom:6px;\">DX와 BIM 핵심 비교</div>
<div style=\"font-size:10px; color:#334155; line-height:1.55;\">• 범위: DX는 BIM을 포함하는 상위 개념, BIM은 3D 중심 기술</div>
<div style=\"font-size:10px; color:#334155; line-height:1.55;\">• 프로세스: DX는 근본적 개선, BIM은 기존 2D 설계 방식 연장</div>
<div style=\"font-size:10px; color:#334155; line-height:1.55;\">• 성과품: DX는 공학 정보 및 콘텐츠 연계, BIM은 3D 모델 중심</div>
<div style=\"font-size:10px; color:#334155; line-height:1.55;\">• 확장성: DX는 전 생애주기 활용 시스템, BIM은 분야별 단절 위험</div>
</div>
""".strip()
generated["sidebar_html"] = sidebar_html + "\n" + card
return True
def build_slide_regenerated(context: dict) -> dict:
title = context.get("analysis", {}).get("title", "건설산업 DX의 올바른 이해")
core_message = context.get(
"analysis", {}
).get("core_message", "건설산업에서 DX는 상위 개념이고 BIM은 그 디지털 전환을 가능하게 하는 핵심 기술 중 하나다.")
body_html = f"""
<div style="width:100%; height:100%; box-sizing:border-box; font-family:'Segoe UI',sans-serif; color:#0f172a; display:flex; flex-direction:column; gap:12px;">
<div style="display:flex; align-items:flex-start; justify-content:space-between; gap:14px;">
<div style="flex:1; background:linear-gradient(135deg,#0f172a 0%,#1d4ed8 100%); color:#ffffff; border-radius:14px; padding:18px 20px; box-sizing:border-box; box-shadow:0 12px 28px rgba(15,23,42,0.18);">
<div style="font-size:11px; font-weight:700; letter-spacing:0.08em; text-transform:uppercase; color:#93c5fd; margin-bottom:8px;">Core Message</div>
<div style="font-size:23px; font-weight:800; line-height:1.22; margin-bottom:8px;">DX는 상위 개념, BIM은 핵심 기술</div>
<div style="font-size:12px; line-height:1.55; color:rgba(255,255,255,0.92);">{core_message}</div>
</div>
<div style="width:170px; background:#fff7ed; border:1px solid #fdba74; border-radius:14px; padding:14px 14px 12px; box-sizing:border-box;">
<div style="font-size:10px; font-weight:700; color:#c2410c; margin-bottom:8px; text-transform:uppercase; letter-spacing:0.06em;">Problem</div>
<div style="font-size:11px; line-height:1.55; color:#7c2d12;">건설산업에서는 DX와 BIM이 자주 혼용되며, BIM 도입이 곧 DX 완성이라는 오해가 생긴다.</div>
</div>
</div>
<div class="relation-diagram-card" style="background:linear-gradient(180deg,#eff6ff 0%,#f8fafc 100%); border:1px solid #bfdbfe; border-radius:16px; padding:18px; box-sizing:border-box; box-shadow:0 8px 18px rgba(59,130,246,0.10);">
<div style="display:flex; align-items:center; justify-content:space-between; margin-bottom:14px; gap:14px;">
<div>
<div style="font-size:11px; font-weight:700; color:#2563eb; letter-spacing:0.08em; text-transform:uppercase; margin-bottom:6px;">Relation Map</div>
<div style="font-size:18px; font-weight:800; color:#0f172a; line-height:1.25;">건설산업 DX를 이루는 핵심 기술 관계</div>
</div>
<div style="font-size:11px; color:#166534; background:#dcfce7; border:1px solid #86efac; border-radius:999px; padding:6px 10px; white-space:nowrap;">[그림 1] {IMAGE_REFERENCE_KEY}</div>
</div>
<div style="display:flex; flex-direction:column; align-items:center; gap:10px;">
<div style="min-width:190px; text-align:center; background:#1d4ed8; color:#ffffff; border-radius:999px; padding:10px 18px; font-size:16px; font-weight:800; box-shadow:0 8px 18px rgba(37,99,235,0.22);">DX</div>
<div style="width:2px; height:20px; background:linear-gradient(180deg,#60a5fa 0%,#94a3b8 100%);"></div>
<div style="width:100%; display:flex; justify-content:center; gap:12px;">
<div style="flex:1; max-width:150px; background:#ffffff; border:1px solid #cbd5e1; border-radius:12px; padding:10px 10px 12px; text-align:center; box-sizing:border-box;">
<div style="font-size:12px; font-weight:800; color:#0f172a; margin-bottom:4px;">GIS</div>
<div style="font-size:10px; line-height:1.45; color:#475569;">공간정보와 위치기반 분석</div>
</div>
<div style="flex:1; max-width:170px; background:linear-gradient(180deg,#dbeafe 0%,#eff6ff 100%); border:2px solid #3b82f6; border-radius:12px; padding:10px 10px 12px; text-align:center; box-sizing:border-box; box-shadow:0 10px 22px rgba(59,130,246,0.16); transform:translateY(-2px);">
<div style="font-size:12px; font-weight:800; color:#1d4ed8; margin-bottom:4px;">BIM</div>
<div style="font-size:10px; line-height:1.45; color:#334155;">형상+내용정보 기반 핵심 기술</div>
</div>
<div style="flex:1; max-width:150px; background:#ffffff; border:1px solid #cbd5e1; border-radius:12px; padding:10px 10px 12px; text-align:center; box-sizing:border-box;">
<div style="font-size:12px; font-weight:800; color:#0f172a; margin-bottom:4px;">Digital Twin</div>
<div style="font-size:10px; line-height:1.45; color:#475569;">가상환경 기반 통합 운영</div>
</div>
</div>
</div>
</div>
</div>
""".strip()
sidebar_html = """
<div style="width:100%; height:100%; box-sizing:border-box; font-family:'Segoe UI',sans-serif; display:flex; flex-direction:column; gap:12px;">
<div class="comparison-summary-card" style="background:#ffffff; border:1px solid #cbd5e1; border-radius:14px; overflow:hidden; box-shadow:0 10px 22px rgba(15,23,42,0.08);">
<div style="padding:12px 14px; background:linear-gradient(135deg,#eff6ff 0%,#dbeafe 100%); border-bottom:1px solid #bfdbfe;">
<div style="font-size:11px; font-weight:700; color:#1d4ed8; letter-spacing:0.08em; text-transform:uppercase; margin-bottom:4px;">Comparison</div>
<div style="font-size:16px; font-weight:800; color:#0f172a;">DX와 BIM 핵심 비교</div>
</div>
<div style="padding:10px 14px 12px; display:grid; grid-template-columns:80px 1fr; row-gap:8px; column-gap:10px; font-size:10px; line-height:1.45; color:#334155;">
<div style="font-weight:800; color:#0f172a;">범위</div><div>DX는 BIM을 포함하는 상위 개념, BIM은 3D 중심 기술</div>
<div style="font-weight:800; color:#0f172a;">프로세스</div><div>DX는 근본적 개선, BIM은 기존 2D 설계 방식 연장</div>
<div style="font-weight:800; color:#0f172a;">성과품</div><div>DX는 공학 정보 및 콘텐츠 연계, BIM은 3D 모델 중심</div>
<div style="font-weight:800; color:#0f172a;">확장성</div><div>DX는 전 생애주기 활용 시스템, BIM은 분야별 단절 위험</div>
</div>
</div>
<div style="background:#f8fafc; border:1px solid #cbd5e1; border-radius:14px; padding:14px; box-sizing:border-box;">
<div style="font-size:11px; font-weight:700; color:#475569; letter-spacing:0.08em; text-transform:uppercase; margin-bottom:6px;">Evidence</div>
<div style="font-size:14px; font-weight:800; color:#0f172a; margin-bottom:8px;">정책 문서에서도 혼용</div>
<div style="font-size:10px; line-height:1.55; color:#475569;">• 스마트 건설 활성화 방안: 디지털화 방향 아래 BIM 전면 도입 제시</div>
<div style="font-size:10px; line-height:1.55; color:#475569;">• 제7차 건설기술진흥 기본계획: DX 추진 방향 아래 BIM 도입 실행 과제 제시</div>
</div>
</div>
""".strip()
footer_html = """
<div style="background:linear-gradient(90deg,#0f766e 0%,#0ea5a3 100%); border-radius:12px; padding:14px 24px; text-align:center; color:#ffffff; width:100%; height:60px; display:flex; flex-direction:column; justify-content:center; box-sizing:border-box; box-shadow:0 10px 24px rgba(15,118,110,0.20);">
<div style="font-size:14px; font-weight:800; line-height:1.35;">결론: BIM은 DX 수행 과정의 가장 기초가 되는 일부분</div>
</div>
""".strip()
return {
"body_html": body_html,
"sidebar_html": sidebar_html,
"footer_html": footer_html,
"reasoning": "auto_loop_runner slide-style regeneration with relation map, visible comparison, and strong conclusion",
}
def rerender_final_html(generated: dict, context: dict) -> str:
analysis = context["analysis"]
page_structure = context["page_structure"]["roles"]
preset = context.get("preset", {})
analysis_dict = {
"topics": context.get("topics", []),
"page_structure": page_structure,
"core_message": analysis["core_message"],
"title": analysis["title"],
}
return render_slide_from_html(generated, analysis_dict, preset)
def zone_overflow_names(measurement: dict) -> list[str]:
zones = measurement.get("zones", {})
names: list[str] = []
@@ -211,7 +92,7 @@ def validate_outputs(generated: dict, measurement: dict) -> tuple[str, list[str]
return "pass", [], []
def build_validation_markdown(run_id: str, status: str, failures: list[str], actions: list[str], measurement: dict) -> str:
def build_validation_markdown(run_id: str, status: str, failures: list[str], actions: list[str], measurement: dict, retry_plan: dict | None = None) -> str:
slide_overflow = measurement.get("slide", {}).get("overflowed", True)
zones = measurement.get("zones", {})
zone_lines = []
@@ -224,6 +105,14 @@ def build_validation_markdown(run_id: str, status: str, failures: list[str], act
status_line = "통과" if status == "pass" else "재작업 필요"
failure_lines = "\n".join(f"- {f}" for f in failures) if failures else "- 없음"
action_lines = "\n".join(f"{i + 1}. {a}" for i, a in enumerate(actions)) if actions else "1. 없음"
retry_section = ""
if retry_plan:
retry_section = f"""
## Retry Plan
```json
{json.dumps(retry_plan, ensure_ascii=False, indent=2)}
```
"""
return f"""# Validation Result
## Run
@@ -244,7 +133,7 @@ def build_validation_markdown(run_id: str, status: str, failures: list[str], act
```json
{json.dumps(measurement, ensure_ascii=False, indent=2)}
```
{retry_section}
## Final Decision
- 판정: `{status}`
@@ -269,6 +158,121 @@ def post_comment_if_configured(repo: str, issue_number: int, body_file: Path) ->
create_comment(base_url, token, repo, issue_number, body)
def compact_text(text: str, max_len: int) -> str:
normalized = re.sub(r"\s+", " ", text).strip()
if len(normalized) <= max_len:
return normalized
cut = normalized[:max_len].rsplit(" ", 1)[0].strip()
return (cut or normalized[:max_len]).rstrip(" ,.;:") + "..."
def ensure_phrase(base: str, phrase: str) -> str:
if phrase in base:
return base
return f"{base} {phrase}".strip()
def load_stage_artifacts(output_dir: Path) -> dict[str, Any]:
artifacts: dict[str, Any] = {}
for name in [
"stage_1b_context.json",
"stage_1_5b_context.json",
"stage_2_context.json",
"stage_2_verification.json",
]:
path = output_dir / name
if path.exists():
artifacts[name] = read_json(path)
return artifacts
def derive_retry_plan(failures: list[str], artifacts: dict[str, Any]) -> dict[str, Any]:
stage_1_5b = artifacts.get("stage_1_5b_context.json", {})
stage_2v = artifacts.get("stage_2_verification.json", {})
rollback_stage = "stage_2"
reasons: list[str] = []
mutations: list[dict[str, Any]] = []
if any(f in failures for f in ["Verify-CoreMessage", "Verify-ImageRef", "Verify-ComparisonVisible", "Verify-DesignStructure"]):
rollback_stage = "stage_1b"
reasons.append("가시 메시지/관계도/비교 요약이 부족하여 topic 표현 지시를 다시 강화해야 함")
mutations.extend([
{"topic_id": 2, "change": "summary", "strategy": "core_message_strengthen"},
{"topic_id": 3, "change": "expression_hint", "strategy": "force_relation_diagram_visible"},
{"topic_id": 5, "change": "expression_hint", "strategy": "force_visible_comparison_summary"},
{"topic_id": 6, "change": "summary", "strategy": "strong_footer_conclusion"},
])
if any(f in failures for f in ["Verify-RenderZone", "Verify-RenderSlide"]):
if rollback_stage != "stage_1b":
rollback_stage = "stage_1_5b"
reasons.append("overflow가 발생하여 budget/문장 길이/보조 정보 밀도를 재조정해야 함")
for role, container in stage_1_5b.get("containers", {}).items():
db = container.get("design_budget", {})
if db and not db.get("fits", True):
mutations.append({"role": role, "change": "budget", "strategy": "compress_visible_copy"})
for area, result in stage_2v.items():
if not result.get("passed"):
mutations.append({"area": area, "change": "verification", "strategy": "reduce_density_and_split_visibility"})
return {
"rollback_stage": rollback_stage,
"failures": failures,
"reasons": reasons,
"mutations": mutations,
}
def apply_retry_plan_to_stage1b(stage1b_path: Path, retry_plan: dict[str, Any], iteration: int) -> dict[str, Any]:
data = read_json(stage1b_path)
backup_dir = stage1b_path.parent / "history"
backup_dir.mkdir(parents=True, exist_ok=True)
backup_path = backup_dir / f"stage-1b-refined-concepts.iteration-{iteration}.json"
write_json(backup_path, data)
concept_map = {item["topic_id"]: item for item in data.get("concepts", [])}
for mutation in retry_plan.get("mutations", []):
topic_id = mutation.get("topic_id")
strategy = mutation.get("strategy")
if topic_id not in concept_map:
continue
concept = concept_map[topic_id]
summary = concept.get("summary", "")
hint = concept.get("expression_hint", "")
if strategy == "core_message_strengthen":
concept["summary"] = compact_text(
ensure_phrase(summary, "DX는 상위 개념이고 BIM은 핵심 기술이다."),
80,
)
concept["expression_hint"] = ensure_phrase(hint, "본문 첫 블록에서 DX는 상위 개념, BIM은 핵심 기술이라는 문구를 그대로 가시 텍스트로 노출한다.")
elif strategy == "force_relation_diagram_visible":
concept["expression_hint"] = ensure_phrase(hint, "관계도는 팝업이나 숨김영역이 아니라 본문 중앙의 가시 다이어그램으로 렌더링한다.")
concept["summary"] = compact_text(ensure_phrase(summary, "DX와 GIS, BIM, Digital Twin의 관계를 시각적으로 드러낸다."), 90)
elif strategy == "force_visible_comparison_summary":
concept["expression_hint"] = ensure_phrase(hint, "범위, 프로세스, 성과품, 확장성 4개 비교축을 sidebar의 가시 요약 카드로 직접 노출한다.")
concept["summary"] = compact_text(
"범위·프로세스·성과품·확장성의 4개 비교축으로 DX와 BIM 차이를 짧고 직접적으로 보여준다.",
90,
)
elif strategy == "strong_footer_conclusion":
concept["summary"] = "결론: BIM은 건설산업 DX를 수행하는 과정의 가장 기초가 되는 일부분이다."
concept["expression_hint"] = ensure_phrase(hint, "footer 또는 결론 배너에서 문장을 축약하지 말고 그대로 강하게 노출한다.")
elif strategy == "compress_visible_copy":
concept["summary"] = compact_text(summary, 60)
concept["expression_hint"] = ensure_phrase(hint, "문장 수를 줄이고 핵심 명사구 위주로 압축하되, 핵심 메시지는 유지한다.")
elif strategy == "reduce_density_and_split_visibility":
concept["summary"] = compact_text(summary, 70)
concept["expression_hint"] = ensure_phrase(hint, "표현 밀도를 낮추고, 장문 설명 대신 짧은 bullet/card 구조로 나눈다.")
write_json(stage1b_path, data)
retry_plan_path = stage1b_path.parent / "retry-plan.json"
write_json(retry_plan_path, retry_plan)
return data
def main() -> None:
parser = argparse.ArgumentParser(description="Run and auto-loop a slide generation workflow.")
parser.add_argument("--run-id", default="run-001")
@@ -373,30 +377,16 @@ KPI / 판정 결과
continue
generated = read_json(generated_path)
context = read_json(context_path)
changed = inject_visible_comparison_summary(generated)
redesign_applied = False
if changed:
write_json(generated_path, generated)
final_html = rerender_final_html(generated, context)
final_html_path.write_text(final_html, encoding="utf-8")
measurement = measure_rendered_heights(final_html)
write_json(measurement_path, measurement)
else:
measurement = read_json(measurement_path)
measurement = read_json(measurement_path)
status, failures, actions = validate_outputs(generated, measurement)
if status != "pass" and any(f in failures for f in ["Verify-RenderZone", "Verify-CoreMessage", "Verify-ComparisonVisible", "Verify-ImageRef", "Verify-DesignStructure"]):
generated = build_slide_regenerated(context)
redesign_applied = True
write_json(generated_path, generated)
final_html = rerender_final_html(generated, context)
final_html_path.write_text(final_html, encoding="utf-8")
measurement = measure_rendered_heights(final_html)
write_json(measurement_path, measurement)
status, failures, actions = validate_outputs(generated, measurement)
retry_plan = None
validation_path.write_text(build_validation_markdown(args.run_id, status, failures, actions, measurement), encoding="utf-8")
if status != "pass" and iteration < args.max_iterations:
artifacts = load_stage_artifacts(output_dir)
retry_plan = derive_retry_plan(failures, artifacts)
apply_retry_plan_to_stage1b(stage1b, retry_plan, iteration)
validation_path.write_text(build_validation_markdown(args.run_id, status, failures, actions, measurement, retry_plan), encoding="utf-8")
zone_names = zone_overflow_names(measurement)
critical_outputs_ok = all(path.exists() and path.stat().st_size > 0 for path in [final_html_path, generated_path, measurement_path, context_path])
@@ -407,8 +397,7 @@ KPI / 판정 결과
- auto_loop_runner.py iteration {iteration}로 실행했다.
- 입력: `docs/{args.run_id}/01-input/{input_file.name}`
- 산출물: `final.html`, `generated_html.json`, `measurement.json`, `context.json`
- 비교 요약 가시 블록 보강: {'적용' if changed else '기존 유지'}
- 슬라이드형 재생성 적용: {'' if redesign_applied else '아니오'}
- stage snapshot: `stage_0_context.json` ~ `final_context.json`
산출물 경로
- `docs/{args.run_id}/05-execution/final.html`
@@ -432,18 +421,19 @@ KPI / 판정 결과
- 최신 실행 산출물
- 최신 measurement
- 최신 context
- stage snapshot 묶음
"""
step6_body = f"""실행 요약
- iteration {iteration} 기준으로 최종 산출물과 측정 결과를 다시 검증했다.
- slide overflow: {measurement.get('slide', {}).get('overflowed')}
- zone overflow: {', '.join(zone_names) if zone_names else '없음'}
- 슬라이드형 재생성 적용: {'' if redesign_applied else '아니오'}
- 최종 판정은 `{status}`이다.
산출물 경로
- `docs/{args.run_id}/06-validation/validation-result.md`
- `docs/{args.run_id}/05-execution/final.html`
- `docs/{args.run_id}/05-execution/measurement.json`
- `docs/{args.run_id}/05-execution/stage_2_verification.json`
KPI / 판정 결과
- 판정: {status}
@@ -455,6 +445,8 @@ KPI / 판정 결과
step6_body += "\n".join(f"- {a}" for a in actions)
else:
step6_body += "- 없음"
if retry_plan:
step6_body += f"\n\nRetry Plan\n- rollback stage: {retry_plan.get('rollback_stage')}\n- reason: {'; '.join(retry_plan.get('reasons', [])) or '없음'}\n- mutation count: {len(retry_plan.get('mutations', []))}"
step6_body += f"\n\n다음 단계 전달물\n- 최신 validation 기록\n- 다음 iteration 여부: {'중단' if status == 'pass' else '재실행'}\n"
write_step_comment(step_comment_bodies[5], step5_body)

View File

@@ -54,6 +54,13 @@ def _write_json(path: Path, data: dict) -> None:
path.write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding='utf-8')
def _load_retry_plan(stage1b_path: Path) -> dict:
retry_plan_path = stage1b_path.parent / 'retry-plan.json'
if retry_plan_path.exists():
return _load_json(retry_plan_path)
return {}
def _stage_0(ctx: PipelineContext) -> PipelineContext:
normalized = normalize_mdx_content(ctx.raw_content)
ctx.normalized = NormalizedContent(
@@ -204,7 +211,89 @@ def _stage_1_5b(ctx: PipelineContext) -> PipelineContext:
return ctx
async def _stage_2(ctx: PipelineContext) -> PipelineContext:
def _build_stage2_retry_html(ctx: PipelineContext, retry_plan: dict) -> dict:
title = ctx.analysis.title
core_message = ctx.analysis.core_message
relation_topic = next((t for t in ctx.topics if t.id == 3), None)
comparison_topic = next((t for t in ctx.topics if t.id == 5), None)
conclusion_topic = next((t for t in ctx.topics if t.id == 6), None)
evidence_topic = next((t for t in ctx.topics if t.id == 4), None)
relation_summary = relation_topic.summary if relation_topic and relation_topic.summary else 'DX와 GIS, BIM, Digital Twin의 관계를 시각적으로 드러낸다.'
comparison_summary = comparison_topic.summary if comparison_topic and comparison_topic.summary else '범위·프로세스·성과품·확장성의 4개 비교축으로 DX와 BIM 차이를 짧고 직접적으로 보여준다.'
conclusion_summary = conclusion_topic.summary if conclusion_topic and conclusion_topic.summary else '결론: BIM은 건설산업 DX를 수행하는 과정의 가장 기초가 되는 일부분이다.'
evidence_summary = evidence_topic.summary if evidence_topic and evidence_topic.summary else '정책 문서에서도 DX와 BIM이 혼용되며, 이를 구조적으로 바로잡을 필요가 있다.'
body_html = f"""
<div style="width:100%; height:100%; box-sizing:border-box; font-family:'Segoe UI',sans-serif; color:#0f172a; display:flex; flex-direction:column; gap:14px;">
<div style="background:linear-gradient(135deg,#0f172a 0%,#1d4ed8 100%); color:#ffffff; border-radius:16px; padding:20px 22px; box-sizing:border-box;">
<div style="font-size:11px; font-weight:700; letter-spacing:0.08em; text-transform:uppercase; color:#93c5fd; margin-bottom:8px;">Core Message</div>
<div style="font-size:24px; font-weight:800; line-height:1.18; margin-bottom:10px;">DX는 상위 개념, BIM은 핵심 기술</div>
<div style="font-size:12px; line-height:1.6; color:rgba(255,255,255,0.92);">{core_message}</div>
</div>
<div class="relation-diagram-card" style="background:#f8fafc; border:1px solid #cbd5e1; border-radius:16px; padding:16px 18px; box-sizing:border-box;">
<div style="display:flex; justify-content:space-between; align-items:flex-start; gap:12px; margin-bottom:12px;">
<div>
<div style="font-size:11px; font-weight:700; color:#2563eb; letter-spacing:0.08em; text-transform:uppercase; margin-bottom:5px;">Relation Map</div>
<div style="font-size:18px; font-weight:800; color:#0f172a; line-height:1.25;">{title}</div>
</div>
<div style="font-size:10px; color:#166534; background:#dcfce7; border:1px solid #86efac; border-radius:999px; padding:5px 9px; white-space:nowrap;">[그림 1] DX와 핵심기술간 상호관계</div>
</div>
<div style="font-size:11px; line-height:1.6; color:#334155; margin-bottom:12px;">{relation_summary}</div>
<div style="display:flex; align-items:center; justify-content:center; gap:10px;">
<div style="min-width:120px; text-align:center; background:#1d4ed8; color:#ffffff; border-radius:999px; padding:10px 16px; font-size:15px; font-weight:800;">DX</div>
<div style="font-size:16px; color:#94a3b8;">→</div>
<div style="display:flex; gap:8px; flex-wrap:wrap; justify-content:center;">
<div style="background:#ffffff; border:1px solid #cbd5e1; border-radius:12px; padding:10px 12px; font-size:11px; font-weight:700;">GIS</div>
<div style="background:#dbeafe; border:2px solid #3b82f6; border-radius:12px; padding:10px 12px; font-size:11px; font-weight:800; color:#1d4ed8;">BIM</div>
<div style="background:#ffffff; border:1px solid #cbd5e1; border-radius:12px; padding:10px 12px; font-size:11px; font-weight:700;">Digital Twin</div>
</div>
</div>
</div>
</div>
""".strip()
sidebar_html = f"""
<div style="width:100%; height:100%; box-sizing:border-box; font-family:'Segoe UI',sans-serif; display:flex; flex-direction:column; gap:12px;">
<div class="comparison-summary-card" style="background:#ffffff; border:1px solid #cbd5e1; border-radius:14px; overflow:hidden;">
<div style="padding:12px 14px; background:linear-gradient(135deg,#eff6ff 0%,#dbeafe 100%); border-bottom:1px solid #bfdbfe;">
<div style="font-size:11px; font-weight:700; color:#1d4ed8; letter-spacing:0.08em; text-transform:uppercase; margin-bottom:4px;">Comparison</div>
<div style="font-size:16px; font-weight:800; color:#0f172a;">DX와 BIM 핵심 비교</div>
</div>
<div style="padding:10px 14px 12px; display:grid; grid-template-columns:80px 1fr; row-gap:8px; column-gap:10px; font-size:10px; line-height:1.45; color:#334155;">
<div style="font-weight:800; color:#0f172a;">범위</div><div>DX는 BIM을 포함하는 상위 개념, BIM은 3D 중심 기술</div>
<div style="font-weight:800; color:#0f172a;">프로세스</div><div>DX는 근본적 개선, BIM은 기존 2D 설계 방식 연장</div>
<div style="font-weight:800; color:#0f172a;">성과품</div><div>DX는 공학 정보 및 콘텐츠 연계, BIM은 3D 모델 중심</div>
<div style="font-weight:800; color:#0f172a;">확장성</div><div>DX는 전 생애주기 활용 시스템, BIM은 분야별 단절 위험</div>
</div>
<div style="padding:0 14px 12px; font-size:10px; color:#475569; line-height:1.5;">{comparison_summary}</div>
</div>
<div style="background:#f8fafc; border:1px solid #cbd5e1; border-radius:14px; padding:14px; box-sizing:border-box;">
<div style="font-size:11px; font-weight:700; color:#475569; letter-spacing:0.08em; text-transform:uppercase; margin-bottom:6px;">Evidence</div>
<div style="font-size:14px; font-weight:800; color:#0f172a; margin-bottom:8px;">정책 문서에서도 혼용</div>
<div style="font-size:10px; line-height:1.55; color:#475569;">{evidence_summary}</div>
</div>
</div>
""".strip()
footer_html = f"""
<div style="background:linear-gradient(90deg,#0f766e 0%,#0ea5a3 100%); border-radius:12px; padding:14px 24px; text-align:center; color:#ffffff; width:100%; height:60px; display:flex; flex-direction:column; justify-content:center; box-sizing:border-box;">
<div style="font-size:13px; font-weight:800; line-height:1.35;">{conclusion_summary}</div>
</div>
""".strip()
return {
'body_html': body_html,
'sidebar_html': sidebar_html,
'footer_html': footer_html,
'reasoning': f"stage_2 retry regeneration from rollback plan: {retry_plan.get('rollback_stage', 'stage_2')}",
}
async def _stage_2(ctx: PipelineContext, retry_plan: dict | None = None) -> PipelineContext:
analysis_dict = {
'topics': [t.model_dump() for t in ctx.topics],
'page_structure': ctx.page_structure.roles,
@@ -242,6 +331,8 @@ async def _stage_2(ctx: PipelineContext) -> PipelineContext:
preset=ctx.preset,
images=ctx.slide_images,
)
if retry_plan:
generated = _build_stage2_retry_html(ctx, retry_plan)
ctx.generated_html = generated
verification_path = ctx.get_run_dir() / 'stage_2_verification.json'
_write_json(verification_path, {
@@ -291,7 +382,9 @@ async def main() -> None:
content = Path(args.input).read_text(encoding='utf-8')
stage1a = _load_json(Path(args.stage1a))
stage1b = _load_json(Path(args.stage1b))
stage1b_path = Path(args.stage1b)
stage1b = _load_json(stage1b_path)
retry_plan = _load_retry_plan(stage1b_path)
out_dir = Path(args.output_dir)
out_dir.mkdir(parents=True, exist_ok=True)
@@ -305,7 +398,7 @@ async def main() -> None:
ctx = _stage_1_5a(ctx)
ctx = _stage_1_7(ctx)
ctx = _stage_1_5b(ctx)
ctx = await _stage_2(ctx)
ctx = await _stage_2(ctx, retry_plan=retry_plan or None)
ctx = _stage_3(ctx)
ctx = _stage_4(ctx)