# 교각 모델링 앱 개선 기획서 — 「2. 입력 묶음 확인·확정」 개편 | 버전 | 수정일 | 수정자 | 주요 변경 내용 | 비고 | | :--- | :--- | :--- | :--- | :--- | | v0.1.00 | 2026-10-14 | 심영표 | 신규 작성 | 초안 `[미확정]` — D1~D6 결정 반영(7.2절) | | v0.1.01 | 2026-10-15 | 심영표 | 7.2절 D3~D6을 권고안대로 결정 반영 | 사용자 지시 "권고안대로" | | v0.1.02 | 2026-10-15 | 심영표 | 4.4절 템플릿 구분 기준 재정의(각도=값, 기초=말뚝 유무, 도면 먼저 추천) | 사용자 결정 3건(OPEN #30 ①②④) | | v0.1.03 | 2026-10-16 | 심영표 | A단계(분류·표시) 구현 결과 6.1절 추가 | 사용자 "개편 구현 진행" 지시; B단계는 사용자 승인 후 | | v0.1.04 | 2026-10-16 | 심영표 | B단계(앱 확인 엔진·근거표·일치 묶음 일괄 확정) 구현 결과 6.2절 추가, Prism 적용 시점 결정 반영 | 사용자 "B단계 착수" + "Prism은 B단계 새 화면부터, 기존 화면 교체는 D단계" | | v0.1.05 | 2026-10-19 | 심영표 | 이전 방식 일괄 확정 제거 반영, C단계 1차(앵커 학습·따라가기, R1·R2·R5) 구현 결과 6.3절 추가 | 사용자 "이전방식 일괄 확정은 지금 제거하고, C단계 착수" | | v0.1.06 | 2026-10-19 | 심영표 | C단계 2차 결과 6.4절 추가(표 값 교차 확인, 운곡교 P3·P4 실사용 확인, R3·R4 기하 앵커 시험 결과 = 미채택) | 사용자 "C단계 2차 착수, 운곡교 P3·P4에 앵커를 불러와 실제 후보 확인" | | v0.1.07 | 2026-10-19 | 심영표 | D단계(전 화면 Prism 교체, 사용설명서 v0.2.12, 전체 회귀, 운곡교 P3·P4 A등급 반영) 결과 6.5절 추가 | 사용자 "D단계 착수, 운곡교 P3·P4 후보 반영" | | v0.1.08 | 2026-10-20 | 심영표 | 운곡교 P3·P4 실사용 결과와 앱 개선점 6.6절 추가(OPEN #34·#35) | 사용자 "앱의 개선점을 알려줘" → "진행해줘" | | v0.1.09 | 2026-10-20 | 심영표 | 개선 ②③④⑥ 구현 결과 6.7절 추가 | 사용자 "#34의 2·3·4·6번 순으로 진행" | | v0.1.10 | 2026-10-20 | 심영표 | 개선 ①⑤ 구현 결과 6.8절 추가 | 사용자 "①(읽기 도구 통합), ⑤(일괄 실행 중단 표시)를 진행해줘" | | v0.1.11 | 2026-10-20 | 심영표 | 검토 요약 확정(한 화면 검토 + 한 번 확정) 6.9절 추가 | 사용자 "확정 판정이 오래 걸리고 확인하기 어렵다 → 앱이 일괄 처리, 사용자는 일괄 검토" 제안 → 권고안 진행 | | v0.1.12 | 2026-10-20 | 심영표 | 6.9절에 후속 변경 추가(도면에서 읽기에 표 값 통합, 검토 요약 모두 체크·주의 표시) | 사용자 "템플릿 원본 그대로도 모두 도면에서 읽기로 바꾸고, 미확정도 일괄 확정" | | v0.1.13 | 2026-10-20 | 심영표 | 운곡교 P4 복구 결과와 앱 수정 계획 6.10절 추가 | 사용자 "앱을 수정계획을 정리해줘" (P4 결정 소실 사고 기반) | | v0.1.14 | 2026-10-20 | 심영표 | W4(원본 잔존 검사 확대) 상세 계획 6.11절 추가, 실측 근거 스크립트 보관 | 사용자 "「원본 잔존 검사 확대」에 대한 계획을 세워줘" | > 상태: **초안 `[미확정]`**. 코드는 고치지 않았고, 이 문서는 계획만 담습니다. 수치는 2026-10-14 현재 앱(`Code/교각모델링앱/`)과 보호 템플릿 4종을 직접 센 값입니다. `[추론]`은 확인이 필요한 판단입니다. --- ## 1. 개요 ### 1.1 목적 앱 교각 화면의 「2. 입력 묶음 확인·확정」을 다음 네 가지가 되도록 고칩니다. 1. 도면 **표 밖 치수**(표 3종에 없는 치수·EL·위치)를 앱이 찾아 후보로 제시합니다. 2. 묶음별 **확인**(도면 대조)을 앱이 수행하고 근거를 보여 줍니다. **확정**은 사람이 합니다(결정 D1). 3. 같은 템플릿 안에서 **바꿔도 되는 값과 바꾸면 안 되는 값**을 구분해 화면에 표시합니다. 4. 지금의 문제점과 해결방법을 정리해 개발 순서를 정합니다. ### 1.2 범위 | 포함 | 제외 | | :--- | :--- | | 교각 화면 2절(묶음 표·일괄 확정)과 [표 후보값]·[도면 문자 검색] 화면 | 3절 게이트 실행·승인 흐름(그대로) | | 값 확인 엔진(`engine/`)에 검사·탐색 추가, 확정 기록(`confirm.json`) 확장 | 새 교각 형식의 생성기·검사기(형식이 다르면 별도 Task) | | 보호 템플릿의 묶음 분류 메타 | 구조계산·간섭 검사·측량좌표(기존 한계 그대로) | ### 1.3 용어 | 용어 | 뜻 | | :--- | :--- | | 묶음 | `params.json`·`expected.json`의 최상위 항목 하나(예: `footing`, `G4`) | | 확인 | 묶음 값을 도면 원자료와 대조하는 일. 이 기획에서는 **앱이 수행** | | 확정 | "내가 이 값을 도면과 대조했다"는 **사람의 검토 기록**(해시로 값 변경 시 자동 무효) | | 표 밖 치수 | 받침 ELEVATION TABLE·솔플레이트 TABLE·철근재료표 3종에 없는 값. 정면·측면·평면·단면의 치수 문자와 작도선·철근 점에서 읽음 | | 앵커 | 원본 교각 판독에서 "이 값을 도면의 어디서(뷰·레이어·객체·상대 위치·문자 패턴) 읽었는가"를 적은 기록 | --- ## 2. 현황 ### 2.1 현재 화면과 동작 - 화면: 교각 화면 **「2. 입력 묶음 확인·확정」** = 묶음 표(파일·묶음·상태·확정자·확정 시각) + **[필요한 묶음 일괄 확정]** 버튼 (`web/templates/pier.html` 18~35행). - 동작: 사용자가 묶음을 열어 값을 도면과 **눈으로** 대조·수정하고 확정합니다. 일괄 확정은 미확정 필수 묶음에 확정자 이름·시각·해시를 **그대로 찍습니다**(`web/app.py` `confirm_all`: 값 검사 없음). - 값을 고치면 해시가 달라져 '변경됨 · 재확정 필요'가 되고 승인된 게이트도 '재실행 필요'가 됩니다(이 부분은 잘 동작). - 표 밖 치수: [도면 문자 검색](글자·정규식)과 [핸들 조회](객체 핸들의 좌표·길이·반지름)로 사람이 찾습니다. EL 문자는 목록만 보여 줍니다(`reader.el_list`). 값 자동 반영은 없습니다. - 표 3종은 자동 인식해 [표 후보값]에서 현재 값과 비교합니다(`reader.proposals`). ### 2.2 규모 (보호 템플릿 4종, 직접 집계) | 템플릿 | 전체 묶음 | 참고(확정 불필요) | **확정 필요** | 확정 필요 묶음 합계 용량 | 철근 중심선 목록(손으로 못 고침)의 비중 | | :--- | --: | --: | --: | --: | --: | | 운곡교P1형 | 30 | 7 | 23 | 32 KB | 0 % (철근이 params 규칙 값) | | 산외교울산P1형 | 31 | 5 | 26 | 117 KB | 84 % (`coping_rebar` 98 KB) | | Ramp-A교P1형 | 30 | 5 | 25 | 135 KB | 89 % (`coping_rebar` 121 KB) | | 옥성교P1형 | 32 | 5 | 27 | 463 KB | 95 % (`coping_rebar` 301 KB + `footing_rebar` 142 KB) | --- ## 3. 문제점 | # | 문제 | 근거 | 영향 | | :-- | :--- | :--- | :--- | | P1 | **일괄 확정이 값을 검사하지 않음.** 확정 = 도장 | `confirm_all`은 `p.confirm()`만 호출. 화면 문구는 "값을 도면·판독서와 대조하셨습니까?" 한 줄 | 확정 기록의 신뢰가 사람의 성실에만 의존. 일괄 버튼이 쉬워 검토가 생략되기 쉬움 | | P2 | **템플릿 원본 값이 그대로 확정될 수 있음.** 복사 직후 값은 원본 교각의 값 | 사용설명서 5.1 주의문. 묶음 표에 '원본 값 그대로'라는 표시 없음 | 새 도면 대조 없이 확정·승인하면 **원본 교각 모델이 PASS**로 나옴(가장 위험한 실수) | | P3 | **근거가 안 보임.** 묶음마다 "이 값이 도면 어디서 왔는지"가 없음 | 묶음 표에 출처 열 없음. `_src` 메모는 '확정 불필요(참고)'로 숨음 | 사람이 매번 판독서·도면을 따로 열어 대조 | | P4 | **표 밖 치수는 전부 수작업.** 판독 스크립트를 교각마다 새로 씀 | 새 형식 1개당 판독·등록 스크립트 약 10개(`Code/옥성P1판독/` 등). 앱은 문자 검색·핸들 조회까지 | 확인 단계 병목. 오타·누락·잘못된 뷰 기준 위험 | | P5 | **손으로 대조할 수 없는 묶음.** 철근 중심선 목록이 용량의 84~95 % | 2.2절 | 사람이 '열어서 눈으로 확인'할 수 없으므로 확정이 형식적 | | P6 | **같은 템플릿에서 바꿔도 되는 값과 안 되는 값이 구분되지 않음.** 모두 같은 JSON 편집 화면 | 묶음 편집은 '형식(객체·목록·숫자) 유지'만 강제(`set_section`) | 형식을 정의하는 값(`form`, `builders`, 마크 구성)을 실수로 고쳐 생성기가 깨지거나, 값이 아닌 형식이 달라진 도면을 같은 템플릿으로 밀어 넣음 | | P7 | **params와 expected가 같은 후보에서 함께 채워짐.** | 사용설명서 5.3 주의문(두 줄 함께 반영 시 검사 무의미) | 검사의 독립성(독립 기대값 원칙)이 사용 습관에 의존 | | P8 | **확인 상태의 층이 하나.** '미확정 / 확정 / 변경됨' 3값뿐 | `store.section_state` | "앱이 확인했다", "도면에 근거 없음", "불일치 의심"을 표현할 방법이 없음 | --- ## 4. 해결 방향 ### 4.1 화면 개편 — 「2. 입력 묶음 확인·확정」 **원칙**: 앱이 확인하고 근거를 보이며, 사람은 근거를 보고 확정합니다(결정 D1). 앱은 **확정하지 않습니다**. 현행 표(파일·묶음·상태·확정자·확정 시각)를 아래 열로 바꿉니다. | 열 | 내용 | | :--- | :--- | | 묶음 | 파일·이름. 클릭하면 편집 화면 | | 변수 등급 | V1 / V2 / V3 / F (4.4절). 색과 글자 병기 | | 값 출처 | 표 / 표 밖 치수(도면 위치) / 판독 스크립트 / **템플릿 원본 그대로** / 사람 입력 | | **앱 확인** | 일치 / 주의 / 불일치 / 근거 없음 / 해당 없음(참고) + 근거 보기 | | 사람 확정 | 확정·미확정·변경됨, 확정자·시각 | - 표 위에 한 줄 요약: "필요 27개 중 앱 확인 일치 19 · 주의 4 · 불일치 1 · 근거 없음 3 · 사람 확정 0". - **[일치 묶음 일괄 확정]**: 앱 확인이 '일치'인 묶음만 대상. 누르기 전 근거표를 한 번 열어야 활성화(D4 결정 대기). '주의·불일치·근거 없음'은 묶음마다 사유를 적어 개별 확정합니다. - '템플릿 원본 그대로'인 묶음(P2)은 앱 확인이 **'근거 없음(원본값)'**이며 일괄 확정에서 제외됩니다. 새 도면과 대조(표 후보값 반영·표 밖 치수 반영·사람 입력)해 값이 바뀌거나 근거가 붙어야 풀립니다. 새 도면 값이 우연히 원본과 같은 묶음은 '일치(원본과 동일, 근거 있음)'로 구분합니다. ### 4.2 도면 표 밖 치수 찾기 (결정 D2: 규칙 + 템플릿 앵커) **탐색 규칙 6종** (4개 교각 도면에서 판독 스크립트가 쓴 방법을 앱 규칙으로 일반화합니다) | 규칙 | 찾는 것 | 방법 | 이미 있는 것 | | :--- | :--- | :--- | :--- | | R1 레벨 | 기초·기둥·코핑 EL | `EL.` 문자 + 인접 레벨선·치수선 연결 | `reader.el_list`(목록만) | | R2 치수 사슬 | `22@120=2.640`, `100 \| 2@100 \| 72@125=9.000` | 문자 패턴 → 치수 사슬로 파싱, 합계가 전체 치수와 맞는지 검산 | `store.chain`(입력용 파서만) | | R3 철근 점·선 | 철근 위치 목록 | 철근 레이어의 점 심볼·선의 좌표(뷰 기준) → 위치 목록, R2와 대조 | 없음(스크립트) | | R4 콘크리트 외곽 | 코핑 정면 외곽 점 목록 | 콘크리트 레이어 선 → 중심선(y = 0) 단면 점열 | 없음(스크립트) | | R5 뷰 기준 | 정면·측면·평면 각각의 기준점·좌표 변환(예: z = 도면 y − 309,179.8) | 뷰 제목 문자('정면도' 등)·축척·EL 문자로 기준 후보 | 없음(스크립트에 상수) | | R6 표 수량 대조 | 재료표 N과 작도 점·선 개수 | R3 결과 개수 = 재료표 수량이면 근거 강화(옥성교: 스터럽 106 = 39 + 27 + 40) | `reader.proposals` 일부 | **앵커(템플릿 원본의 판독 위치 기억)** - 앵커 한 줄 = `{값 경로, 뷰, 도면 레이어, 객체 종류, 기준 대비 상대 위치 또는 문자 패턴, 변환 규칙}`. 원본 교각의 판독 스크립트가 값을 읽을 때 같이 남기는 형식으로 정합니다(소급 추출 범위는 D6). - 새 도면에서 같은 레이어·뷰·상대 위치·문자 패턴을 따라가 **후보**를 만들고, 규칙 R1~R6의 검산 결과로 **신뢰 등급**을 붙입니다. | 신뢰 등급 | 조건 | 화면 | | :--- | :--- | :--- | | A | 앵커 일치 + 검산(사슬 합계·재료표 수량) 일치 | 후보 + 근거, 반영 가능 | | B | 앵커 일치, 검산 없음 또는 일부 불일치 | 후보 + 주의 | | C | 규칙만 일치, 앵커 없음(형식이 다른 도면 등) | 후보 목록만, 반영 시 사유 필요 | | 없음 | 어떤 규칙도 일치하지 않음 | **'근거 없음'으로 표시, 억지 후보를 만들지 않음** | - 출력 = [표 후보값]과 같은 비교 표에 '표 밖 치수' 구역을 추가: 현재 값 / 후보 / 도면 위치(D1·좌표·핸들) / 신뢰 등급 / [도면 보기](`dxftools.render`와 같은 확대 이미지). 선택해 반영하는 것은 사람입니다(자동 반영 없음). - **한계**: 규칙과 앵커는 4개 교각의 도면 틀(운곡교 P1·P2, 산외교 울산 P1, Ramp-A교 P1, 옥성교 P1)에서만 검증됩니다. 틀이 다르면 등급 C 또는 '없음'이 나오는 것이 **정상 동작**입니다. ### 4.3 입력 묶음 확인·확정을 앱이 수행하기 (결정 D1: 앱 확인 + 사람 확정) **앱 확인 8종** (묶음마다 해당하는 것만 수행, 결과는 일치·주의·불일치·근거 없음·해당 없음) | # | 확인 | 방법 | 막는 문제 | | :-- | :--- | :--- | :--- | | C1 | 출처 있음 | 값마다 표·표 밖 치수·스크립트·사람 입력 중 어디서 왔는지 기록 여부 | P3 | | C2 | 도면 재대조 | 표 후보값·표 밖 치수 후보와 현재 값 비교 | P4 | | C3 | 템플릿 원본 잔존 | 현재 값이 템플릿 원본과 같은데 새 도면 근거가 없는 항목 수 | **P2** | | C4 | 내부 정합 | 치수 사슬 합 = 전체 치수, 본수 = 재료표 N, 직경 = 재료표, 위치 목록 길이 = 사슬 개수 | P5 | | C5 | params ↔ expected 독립 | expected 값이 params에서 복사됐는지(두 값이 같고 근거도 같은 한 후보) | **P7** | | C6 | 범위·단위 | EL(m×1000)·mm 단위 상식 범위, 음수·0·순서 역전 | 오타 | | C7 | 변수 등급 위반 | F(고정) 항목이 템플릿 원본과 달라졌는지, V3(생성 변수)가 생성 스크립트 없이 손으로 고쳐졌는지 | **P6** | | C8 | 재생성 일치(V3) | 판독 스크립트로 재생성한 목록의 해시와 현재 해시 | P5 | **상태와 기록 (기존 `confirm.json` 호환)** ``` 미확인 → 앱 확인(일치|주의|불일치|근거 없음) → 사람 확정(확정자·시각·근거 해시) ↑ 값이 바뀌면 둘 다 자동 무효(기존 해시 방식 유지) ``` - `confirm.json`의 확정 기록은 그대로 두고, 앱 확인은 `autocheck.json`(묶음 해시·결과·근거 목록·검사 버전·시각)에 별도로 둡니다. **앱 확인은 확정 기록을 만들지 않습니다.** - 게이트 실행 조건은 지금처럼 '필요 묶음이 사람 확정됨'입니다(변경 없음). 앱 확인은 조건이 아니라 **판단 자료**입니다. - 보고서 초안 8장(검증 방법)에 "앱 확인 결과 요약"을 추가해 사람 확정 근거가 남게 합니다. **앱이 스스로 확정하지 않는 이유 (결정 D1 근거)** 1. 이 앱의 검증 구조는 **생성과 검사의 독립**에 기대고 있습니다. 앱이 값을 만들고(후보 반영) 같은 앱이 확정하면 검토자가 없어집니다. 2. 앱 확인 '일치'는 "후보를 만든 규칙과 값이 같다"이지 "도면이 맞다"가 아닙니다(규칙이 틀린 도면에서 거짓 일치 가능). 3. 확정은 책임 기록입니다. 앱이 근거를 모아 주면 사람의 확정이 **빨라지되 의미는 유지**됩니다. ### 4.4 같은 템플릿에서 변수 가능과 불가능 구분 **4단계 분류** (묶음마다, 필요하면 필드마다 표시) | 등급 | 뜻 | 예 | 앱에서의 처리 | | :--- | :--- | :--- | :--- | | **V1 값 변수** | 같은 형식에서 도면마다 달라지는 숫자·문자 값 | 기초·버림 크기, 기둥 지름·높이, 코핑 치수·EL, 말뚝 개수·간격·길이, 받침 표 값, 직경, fck | 화면 편집 가능, 앱 확인 대상 | | **V2 목록 변수** | 같은 형식에서 도면마다 달라지는 위치·점 목록 | 철근 위치 목록, 치수 사슬, 코핑 정면 외곽 점 | 치수 사슬 입력 가능, 앱 확인 대상(C4) | | **V3 생성 변수** | 값이 도면마다 다르지만 **판독 스크립트가 만든** 큰 목록 | `coping_rebar.bars`(98~301 KB), `footing_rebar.bars`(옥성) | 화면 직접 편집 **차단**, 판독 스크립트 재실행 안내, 재생성 일치(C8) | | **F 고정** | 형식을 정의하는 값. 바꾸면 같은 템플릿이 아님 | `scope`, `builders`, `checkers`, 각 묶음의 `form`·`shape`·`kind`, 철근 마크 체계, 게이트 검사기 이름 | 편집 시 **경고(D3: 차단 또는 경고)**, 바꾸면 '형식 변경 — 새 템플릿 필요' 표시 | **같은 템플릿에서 바꿔도 되는가** (예시, `[추론]` 항목은 시험 후 확정) | 변경 | 판정 | 이유 | | :--- | :--- | :--- | | 기초 크기·두께, 기둥 지름·높이, 말뚝 개수·간격·길이 | 가능(V1) | 생성기가 값으로 받음 | | 받침 표 값(EL.'X', h1~h3, A·B, S, L·T) | 가능(V1) | 표 후보값으로 이미 지원 | | 철근 간격·개수·직경(재료표) | 가능(V1·V2) | 치수 사슬 입력 | | 코핑 상면 단 수·받침 개수 변경 | 조건부 `[추론]` | 검사기 기대값·음성 시험 대상이 개수에 묶여 있음(OPEN #19 A7: 받침 10개 전제) | | 코핑 철근 중심선 목록 | 스크립트 필요(V3) | 사람이 좌표 수만 개를 고칠 수 없음 | | 평면 skew(사각)·받침 회전·기초 회전 등 **각도** | 가능(V1) `[2026-10-15 결정]` | 각도는 템플릿이 아닌 값. 옥성교(skew 18°)·새재1교(0°) 검사기는 하나로 통합(선행: 두 교각 시험 재실행) | | 말뚝 개수·간격·배치 | 가능(V1·V2) | 말뚝 **유무**만 형식 | | 하면 곡선 ↔ 직선 경사, 기초의 말뚝 유무, 기둥 단면 형식, 대좌 공유 여부 | **불가(F)** | 생성기·검사기가 다름 → 다른 템플릿 | | 철근 형상 종류(U형 → 폐합 등), 마크 체계 | **불가(F)** | 생성기·expected 스키마가 정함 | | 게이트 범위(`scope`)·생성기·검사기 이름 | **불가(F)** | 형식 정의 | **새 도면이 이 템플릿으로 가능한지 판별하는 체크리스트** (교각 만들기 화면에 질문으로 제공, 예/아니오) 1. 기초 형식(말뚝 유무: 기초판+말뚝 / 기초판만 / 기초판 없는 단일 말뚝)이 같은가 2. 기둥 단면 형식(원형 / 기타)이 같은가 3. 코핑 하면 형상(곡선 / 직선 경사 / 나팔형)이 같은가. 평면의 사각·직각과 각도는 **문항이 아니라 값 확인**(skew·회전 각도 입력)으로 옮긴다 `[2026-10-15 결정]` 4. 받침 배치 구조(받침마다 대좌 / 앞뒤 공유 대좌)가 같은가 5. 철근 형상 종류가 재료표 형식 열과 같은가 6. 철근 생성 방식(규칙 값 / 철근별 중심선)이 같은가 하나라도 '아니오'면 "같은 템플릿으로 만들 수 없음 — 가장 가까운 템플릿 + 생성기·검사기 추가 필요"로 안내하고, 억지로 진행하면 묶음 표에 '형식 불일치 경고'를 상시 표시합니다. **도면 먼저 추천 (2026-10-15 결정)**: 교각 만들기 화면의 순서를 "도면 올리기 → 추천 순위(근거) → 템플릿 선택 → 6문항 확인"으로 바꾼다. 도면의 단서(말뚝·PILE 문자, Ø, 재료표 형식 열, 받침 표 행 수, 정면도 R 문자)로 문항 값을 추정해 미리 채우고 템플릿을 일치 문항 수로 순위 매긴다. 사람이 바꿀 수 있고, 맞는 템플릿이 없으면 "판단 불가"로 표시한다. R·각도 문자는 정면도·평면도 영역으로 한정해 철근 굽힘 반경 r 등과 구분한다. 논의 근거: `context-migration/템플릿구분기준과도면기반추천_논의.md`. **구현**: 보호 템플릿에 `variability.json`(묶음·필드 경로 → 등급)을 추가합니다. 편집 화면과 앱 확인 C7이 이 파일을 읽습니다. 4개 템플릿 분류는 부록 A. --- ## 5. 문제점과 해결방법 | 문제 | 해결방법 | 기대 효과 | 난이도 | 우선순위 | | :--- | :--- | :--- | :--: | :--: | | P1 일괄 확정이 검사 안 함 | 앱 확인(C1~C8) + '일치 묶음만 일괄 확정' + 근거표 열람 조건(D4) | 일괄 확정이 도장이 아닌 근거 기반 확정이 됨 | 중 | 1 | | P2 템플릿 원본값 확정 위험 | C3 '템플릿 원본 잔존' + 일괄 확정 제외 + 묶음 표에 '원본값' 표시 | 원본 모델이 PASS로 나오는 사고 방지 | **하** | **1** | | P3 근거가 안 보임 | 값 출처 열 + 근거 보기(도면 위치·표 행·스크립트·사슬 검산) | 판독서를 따로 열 필요 감소 | 중 | 2 | | P4 표 밖 치수 수작업 | 규칙 R1~R6 + 앵커 + 신뢰 등급 후보 표(결정 D2) | 새 도면 확인 시간 단축, 오타·누락 감소 | **상** | 3 | | P5 손으로 대조 불가 | V3 분류 + C4·C8(내부 정합·재생성 일치) + 편집 차단 | 확정이 '요약된 검산 결과'에 근거 | 중 | 2 | | P6 변수·고정 미구분 | 4단계 분류 + `variability.json` + 판별 체크리스트 + 형식 불일치 경고 | 형식이 다른 도면을 같은 템플릿에 밀어 넣는 실수 방지 | 중 | 2 | | P7 params·expected 동시 채움 | C5(독립성) + 후보 반영 화면에서 params 줄 별도 선택 안내 강화 | 검사 독립성 유지 | 하 | 2 | | P8 확인 상태 1층 | `autocheck.json` 별도 층(앱 확인), 확정 기록은 불변 | "앱이 확인", "근거 없음", "불일치 의심" 표현 가능 | 하 | 1 | --- ## 6. 구현 계획 | 단계 | 내용 | 주요 변경 | 시험·판정 | | :--- | :--- | :--- | :--- | | **A 분류·표시** | `variability.json` 작성(4템플릿), 묶음 표에 변수 등급·값 출처 열, '템플릿 원본 그대로' 표시(C3) | `web/templates/pier.html`, `web/store.py`, `data/_템플릿/*/variability.json` | 4템플릿에서 분류 100 %, 새 교각(템플릿 복사 직후) 전 묶음이 '원본값' 표시 | | **B 앱 확인 엔진** | C1~C8 구현, `autocheck.json`, 근거표 화면, '일치 묶음 일괄 확정'(D4), 보고서 8장 요약 | `engine/verify.py`(신설), `web/app.py`, 템플릿, `engine/report.py` | 5개 교각 자기 데이터 전 묶음 '일치'(거짓 불일치 0), 값을 일부러 바꾸면 '불일치'(거짓 일치 0, 음성 시험), 기존 회귀 9종 FAIL 0 | | **C 표 밖 치수 탐색** | 규칙 R1~R6, 앵커 형식·추출 도구, 후보 표 구역, 도면 보기 | `engine/reader.py`, `engine/anchors.py`(신설), 판독 스크립트 앵커 기록 | 4개 도면에서 원본 params 값 재현율(등급 A·B 비율)·거짓 후보 0건 집계, 틀이 다른 도면에서 '없음' 정상 표시 | | **D 통합·문서** | 일괄 확정 문구·흐름, 사용설명서 개정(5.3·5.4·9장), 회귀 전체 | 사용설명서 v0.2.08, 시험 `tools/test_confirm_check.py` | 웹 E2E 포함 전체 회귀 PASS | - 각 단계는 **정지·승인**(사용자) 후 진행합니다(HITL). ### 6.1 구현 현황 (2026-10-16) **A단계 분류·표시 — 구현 완료, 사용자 승인 대기** | 항목 | 구현 | | :--- | :--- | | 변수 등급 분류 | `engine/variability.py`(규칙 표 + 묶음 내용으로 V3 판정: 철근 `bars` 목록 100개 이상), 보호 템플릿 6종에 `variability.json`(초안) 작성 — `tools/make_variability.py`. 템플릿 저장·교각 생성 때 자동 작성·복사 | | 묶음 표 | 「변수 등급」「값 출처」 열 추가. 값 출처는 등급 파일의 일반 출처(표 / 표 밖 치수 / 판독 스크립트 / 사람 입력 / 템플릿 고정) | | 템플릿 원본 그대로(C3) | 교각 생성 시 묶음별 해시를 `pier.json`의 `origin`에 기록 → 값이 그대로면 표에 '▲ 템플릿 원본 그대로'. 필수 묶음 중 원본인 것은 표 위에 목록 경고 | | F 항목 편집(D3) | F 묶음 또는 묶음 안의 고정 필드(`column.shape`, `coping.form` 등)를 바꾸면 **사유 입력 필수**, `edit_log.json`에 기록. 차단하지 않음 | | V3 편집 | 화면에서 저장 거부, 판독 스크립트 재실행 안내 | | 시험 | `tools/test_variability.py` 전부 PASS(분류 100 %, 부록 A 일치, 신규 교각 26/26 원본 표시·수정 시 해제, F 사유·V3 차단, 기록 없는 기존 교각은 주장하지 않음) | **기획과 다르게 한 점·한계** 1. 「값 출처」는 **일반 출처**입니다. 묶음 값이 실제로 도면의 어디서 왔는지(C1·C2 근거)는 B·C단계 몫입니다. 2. **기존 교각**(2026-10-16 이전 생성)은 템플릿 복사 기록이 없어 '원본 그대로' 여부를 판단하지 않습니다(표시도 안 함). 새로 만드는 교각부터 적용됩니다. 3. `variability.json`은 묶음 수준 초안입니다. 필드 수준 분류와 담당자 확정(R6)은 남아 있습니다. 4. 시안의 Prism 시각 디자인(UX1~UX3)은 아직 앱에 적용하지 않았습니다(기존 화면 스타일 유지). 적용 시점은 사용자 결정 대기. 5. 「앱 확인」 열·요약 띠·일괄 확정 근거표는 B단계입니다. ### 6.2 B단계 구현 현황 (2026-10-16) **앱 확인 엔진 `engine/verify.py` — 구현 완료, 사용자 승인 대기** | 항목 | 구현 | | :--- | :--- | | 앱 확인 C1~C8 | C1 출처 기록, C2 도면 재대조(ELEVATION·솔플레이트·재료표 후보 vs 현재 값), C3 템플릿 원본 잔존, C4 내부 정합(철근 수량 vs 재료표 수량; 계획 FAIL은 '주의'), C5 params/expected 독립, C6 범위·단위, C7 변수 등급 위반(F 항목), C8 재생성(연결된 스크립트 없음 → 해당 없음) | | 상태 판정 | 불일치(검사 하나라도 실패) > 근거 없음(템플릿 원본 그대로, 독립 근거 없음) > 일치(표 대조 일치) / 주의(수량만 확인, 계획된 예외 등) / 해당 없음(참고·사람 결정 기록). F 묶음은 템플릿 원본(기록 없는 기존 교각은 보호 템플릿들)과 같으면 일치 | | 저장 | `autocheck.json`(묶음 해시·결과·근거 목록·검사 버전) — `confirm.json`과 별도, **앱은 확정 기록을 만들지 않음**. 값·도면·검사 버전이 바뀌면 자동 재실행(약 1초) | | 화면(Prism) | 묶음 표 위 **요약 띠**(필요 N개 중 일치·주의·불일치·근거 없음·해당 없음·사람 확정), 「앱 확인」 열 + 근거 한 줄, **근거 보기**(8종 검사별 결과·비교 내용·도면 위치), **일치 묶음 일괄 확정**(근거표를 끝까지 내려야 활성, 대상 목록 해시 표식, 이름 필수), 앱 확인이 일치가 아닌 묶음은 개별 확정 시 **사유 필수**(확정 기록에 사유·당시 앱 확인 상태 저장) | | 보고서 | 8장에 「8.1 입력 묶음 앱 확인 결과 요약」(묶음별 앱 확인·근거·사람 확정·사유) | | Prism | `web/static/prism.css`(시안 pier.css에서 `.prism` 범위로 생성, `tools/make_prism_css.py`)를 새 화면(요약 띠·표·근거 보기·일괄 확정)에만 적용. 기존 화면 교체는 D단계 | **실제 교각 6종 결과** (`tools/report_autocheck.py`, 필요 묶음 기준) | 교각 | 일치 | 주의 | 불일치 | 근거 없음 | 해당 없음 | | :--- | --: | --: | --: | --: | --: | | Ramp-A교P1 | 11 | 2 | 0 | 9 | 3 | | 산외교울산P1 | 12 | 4 | 0 | 7 | 3 | | 산외교울산P2 | 12 | 4 | 0 | 8 | 3 | | 새재1교P1 | 9 | 4 | 0 | 10 | 3 | | 옥성교P1 | 9 | 4 | 0 | 11 | 3 | | 운곡교P1 | 9 | 0 | 0 | 11 | 3 | | (참고) 운곡교P3·P4 | 0~1 | 0~1 | **8** | 11 | 3 | - **거짓 불일치 0**: 모델링된 교각의 자기 데이터에서 불일치 0건. 운곡교 P3·P4(P1 값을 복사만 한 교각)는 표 대조에서 **불일치 8건**으로 정확히 잡힙니다. - **거짓 일치 0**(시험): 받침 h1 +5 → 불일치, expected 값 +1 → 불일치, 코핑 철근 1본 삭제 → 불일치, 두께 −5 → 불일치. 수량만 확인한 철근 목록은 '일치'가 아니라 '주의'. - 근거 없음이 많은 이유: 기초·기둥·코핑 치수, 철근 위치·좌표, EL은 **표 밖 치수**라 앱이 아직 대조하지 못합니다(C단계). 숨기지 않고 '근거 없음'으로 표시합니다. **기획과 다르게 한 점·한계 (B단계)** 1. 기획의 수용 기준 "5개 교각 자기 데이터 전 묶음 '일치'"는 **달성하지 못함** — 표 밖 치수 묶음은 C단계 전에는 일치가 될 수 없고 '근거 없음'입니다(거짓 일치를 만들지 않기 위해). 거짓 불일치 0·거짓 일치 0은 달성. 2. C8(재생성 일치)은 앱에 생성 스크립트가 연결되어 있지 않아 '해당 없음'입니다. 3. ~~이전 방식 일괄 확정은 접힌 항목으로 유지~~ → **2026-10-19 제거**(사용자 결정). `confirm_all` 경로와 화면 항목을 없앴고, 묶음은 [일치 묶음 일괄 확정] 또는 근거 보기에서 하나씩(일치가 아니면 사유 필수) 확정합니다. 이 경로를 쓰던 시험 9종은 `tools/testlib.confirm_required`(묶음마다 사유를 붙여 개별 확정)로 바꿨습니다. P1 '확정 = 도장' 문제 해소. 4. 개별 확정(`section/.../confirm`)은 앱 확인이 일치가 아니면 사유가 서버에서 강제됩니다. 이에 맞춰 시험 4곳이 사유를 넣도록 바뀌었습니다. 5. 기존 교각의 C3(템플릿 원본)은 판단하지 않고, F 묶음만 보호 템플릿과 비교합니다. 6. 육안 확인: 임시 서버+헤드리스 Edge로 요약 띠·표·근거 보기·일괄 확정 화면을 캡처해 확인했습니다(`검증/ui_check_shots/`). ### 6.3 C단계 1차 구현 현황 (2026-10-19) **표 밖 치수 탐색: 앵커 학습·따라가기 — 구현 완료, 사용자 승인 대기** (R1 레벨·R2 치수 사슬·R5 뷰 기준 구현, R3·R4 미구현) | 항목 | 구현 | | :--- | :--- | | 앵커 학습 `engine/anchors.py` | 모델링된 교각의 숫자 필드(V1·V2 묶음, 1 m 이상)마다, 값과 같은 도면 치수·EL 문자(레이어·도면·좌표)를 기록. 같은 값이 1~6곳에서 나올 때만 앵커. 같은 파일 안에서 다른 종류 필드가 같은 값을 가지면(예: 두께와 지름 2500) '공유'로 표시해 A등급에서 뺌 | | 따라가기(R5) | 새 도면과 앵커 도면에 공통인 문자(제목·라벨)로 뷰별 이동량을 구하고(가까운 5개 중앙값), 예측 위치 반경 1,200 mm 안에서 같은 레이어·같은 종류의 문자를 후보로 취함. **도면 틀 일치율**(공통 문자 비율)이 70 % 미만이면 모든 후보를 C로 낮춤 | | 신뢰 등급 | A = 2곳 이상 따라가 모두 같고 이동 편차 작음 / B = 2곳 이상 일치 또는 1곳 / C = 서로 다름·틀이 다른 도면. 후보가 없으면 '없음'(억지 후보를 만들지 않음) | | R1 레벨 | 'EL. 38.916' 형식 문자를 앵커 종류 EL로 처리(z 계열 필드) | | R2 치수 사슬 | `n@간격=합계` 문자를 파싱해 개수 × 간격 = 합계 검산. 맞지 않으면 묶음 표 위 경고와 후보 화면 목록(도면 보기 링크) | | 저장 | 보호 템플릿 6종에 `anchors.json`(`tools/make_anchors.py`, 앵커 도면은 각 템플릿의 원본 교각). 교각 생성 시 복사, 앵커 없는 교각은 후보 화면에서 템플릿을 골라 불러옴. 앵커가 자기 도면에서 나왔으면(`sources` 해시 일치) 근거로 쓰지 않음 | | 화면(Prism) | [표 후보값]에 「표 밖 치수 후보」 구역: 요약 띠(후보·다름·A·B·C 수, 틀 일치율), 표(반영·대상·현재·후보·등급·근거 n곳 중 m곳·도면 위치·**도면 보기**), 반영 사유(C 필수). 도면 보기 = 해당 위치 확대 PNG(`engine/render.py`) | | 반영 규칙 | 같은 도면 문자에서 나온 후보를 params와 expected에 함께(한 번에 또는 따로) 반영 불가(P7), C등급은 사유 필수, 이미 같은 값은 반영 안 함, 반영·이전 값·등급·위치를 `anchor_log.json`에 기록, 바뀐 묶음은 재확정. 앱이 스스로 반영하지 않음 | | 앱 확인 연동 | 새 검사 **C2b 표 밖 치수 재대조**: A 후보가 현재 값과 다르면 불일치, B가 다르면 주의, A가 같고 앵커 필드의 60 % 이상 대조되면 일치(강한 근거), 일부만이면 주의. 자기 도면 앵커는 제외 | **검증 결과** (`tools/test_anchors.py`, 실제 교각 9종 도면) | 항목 | 결과 | | :--- | :--- | | 같은 도면 틀(울산 P1↔P2, 운곡교 P1↔P2) A등급 | **45건 중 틀린 후보 0건**, 값이 바뀐 필드를 A로 정확히 복원한 것 13건 | | 같은 도면 틀 B등급 | 451건 중 388건 일치(86 %), 틀린 후보 약 14 % — 경고로 표시 | | 같은 도면 틀 C등급 | 48건 중 12건 일치 — 목록만, 반영 시 사유 필요 | | 다른 도면 틀(36쌍) | **A·B 후보 0건**(틀 일치율 < 70 % → 전부 C) | | R2 사슬 검산 | 9개 도면 중 **운곡교 P4 도면의 사슬 2건이 불일치**(`62@125=7.250`은 계산 7,750, `29@250=7.750`은 계산 7,250 — 합계가 서로 바뀐 것으로 보임). 나머지 8개 도면은 0건 | | 새 교각 시험 | 템플릿 운곡교P1형 + 운곡교 P2 도면: 후보 146건, A 11건(다른 값 7건 — 모두 운곡교 P2 모델링 값과 일치), 후보가 다른 묶음 6개가 앱 확인에서 불일치 | | 시험 중 사고 | 처음 시험이 `store`를 환경변수 설정 전에 불러와 실제 `data/`에 시험 교각 2개를 만들었음 → 즉시 삭제, 시험은 `PIERAPP_DATA` 설정 뒤에 불러오도록 수정하고 `data/`를 건드리지 않는지 단언 추가 | **기획과 다르게 한 점·한계 (C단계 1차)** 1. **R3(철근 점·선)·R4(콘크리트 외곽 점열)는 미구현.** 철근 위치 목록·코핑 외곽 점열은 앵커로 읽을 수 없어 여전히 '근거 없음'입니다. 스칼라 치수·EL 문자로 읽히는 필드만 후보가 됩니다. 2. 수용 기준 "거짓 후보 0건"은 **A등급에서만 달성**(같은 틀 45건 중 0건). B등급은 약 14 %가 틀립니다(단, B는 경고 표시이고 앱 확인에서도 주의까지만 반영). 3. 앵커는 단일 숫자 문자와 값이 같은 필드만 학습합니다. 계산해서 얻는 값(예: 사슬 합, EL 차)은 앵커가 없습니다. 1 m 미만 값은 대상이 아닙니다. 4. D6(소급 추출: 옥성교·Ramp-A교부터)에 따라 만들었으나, 학습이 자동이라 **보호 템플릿 6종 모두**에 앵커를 만들었습니다. 5. 같은 도면 틀이어야 작동합니다. 틀이 다른 도면(다른 설계 회사 도면 등)은 후보가 C등급 이하로 떨어지는 것이 정상 동작입니다. 6. 기존 교각 9종은 앵커가 없어 후보 화면에서 템플릿을 골라 불러와야 합니다(자동 선택 안 함). 7. 육안 확인: 임시 서버+헤드리스 Edge로 후보 화면을 캡처해 확인(`검증/ui_check_shots/candidates.png`). ### 6.4 C단계 2차 결과 (2026-10-19) **① 운곡교 P3·P4에 운곡교P1형 앵커를 불러와 실제 후보 확인** (`tools/report_anchor_pier.py`, 실제 `data/운곡교P3·P4`에 `anchors.json` 복사 — 값은 하나도 반영하지 않음) - 두 교각의 현재 값은 `운곡교p2`를 복사한 것이고(`pier.json`의 template 항목), 도면은 P3·P4 자신의 것입니다. 도면 틀 일치율 0.77(≥ 0.70, 같은 틀로 인정). - 후보 146건 중 현재 값과 다른 것 91건(P3) · 102건(P4). | 단계 | P3 | P4 | | :--- | :--- | :--- | | 표 교차 확인 전 | A 11 · B 116 · C 19 | A 9 · B 118 · C 19 | | **표 교차 확인 후** | **A 56**(표 값과도 일치 47) · B 65 · C 25(표 값과 달라 낮춘 것 18) | A 54(47) · B 67 · C 25(18) | - 표 값이 있는 필드만 비교하면 B등급은 34건 중 23건(68 %)만 맞았습니다. 틀린 것은 대부분 **같은 값을 공유하는 마크의 재료표 길이**(P3·P4·P5의 L이 서로 같아 후보가 서로 바뀜)였고, 표 교차 확인으로 모두 C로 내려갑니다. - 화면 확인: 후보 구역 최상단에 표 값과도 일치하는 A등급이 나열되고(받침 EL, 철근 길이·수량, 기초 EL, 기둥 높이), 앱 확인에서 불일치가 P3 10개·P4 11개로 표시됩니다(표 후보 8개 묶음 + 앵커 A 후보 묶음)(`검증/ui_check_shots/candidates_P3.png`, `pier_P3.png`). - 이 후보는 **아직 반영하지 않았습니다.** 반영 여부는 사용자가 [표 후보값] 화면에서 결정합니다(P3·P4는 모델링 전이고, 반영 후에도 앵커가 못 읽는 철근 위치 목록·코핑 외곽 등은 직접 판독해야 합니다). **② 표 값 교차 확인 구현** (`engine/anchors.cross_check`, 화면에 "표 값과도 일치" / "표 값 X와 다름 — 표를 따르세요") - 표(ELEVATION·솔플레이트·재료표) 값이 있는 필드: 앵커 후보가 표와 같으면 **A**, 다르면 표 값을 병기하고 **C**. 표 값이 없는 필드는 그대로. - 같은 도면 틀 4쌍 시험: A등급 45건 → **165건, 전부 맞음**(128건이 표로 확인, 47건은 표와 달라 C로 하향). **③ R3·R4(기하 앵커) 시험 결과 — 채택하지 않음** - 시도: 앵커가 없는 숫자 필드(≥ 1 m)에 대해 콘크리트·철근·중심선 레이어의 선분 길이가 같은 값인지 찾아, 새 도면에서 같은 위치·방향의 선분 길이를 후보로 삼음(울산 P1↔P2, 운곡교 P1↔P2). - 결과: A등급 15~18건/쌍이 **값이 바뀐 필드를 하나도 복원하지 못했고**(바뀐 값 복원 0건), 같은 값이 우연히 맞은 것과 철근 위치 목록(좌표인데 길이로 잘못 대응)의 오답 A가 2~7건 섞임. 위치 목록·외곽 점열은 길이가 아니라 **뷰 기준점 대비 좌표**이므로 뷰 기준점(R5)을 도면 틀마다 확정해야 하는데, 이는 현재 구조(문자 기반 이동량)로는 신뢰할 수 있게 구할 수 없었습니다. - 결론: 철근 점·선(R3)과 콘크리트 외곽 점열(R4)은 **여전히 '근거 없음'**으로 두고 판독 스크립트(사람)로 읽습니다. 억지 후보를 만들지 않는 방침 유지. 시도 코드는 보관하지 않고 결과만 기록(프로토타입 삭제). **④ 화면 편의**: A등급 중 현재 값과 다른 후보를 expected만 / params만 한 번에 선택(두 파일 동시 선택은 P7 때문에 제공하지 않음). **한계 (C단계 2차)** 1. 표 교차 확인은 표가 있는 필드만 개선합니다. 표 밖 필드의 B등급 정확도(약 86 %)는 그대로입니다. 2. R3·R4 미구현 상태 유지 — 철근 위치·코핑 외곽 묶음은 앱 확인에서 계속 '근거 없음'이 됩니다. 3. P3·P4의 후보를 반영하지 않은 상태라 두 교각의 앱 확인은 불일치 10~11개 그대로입니다(반영 후 다시 확인). - 확정·게이트 승인은 어느 단계에서도 앱이 대신하지 않습니다. 시험은 별도 시험 폴더에서만 확정 흐름을 실행합니다(실제 교각 데이터 보호: 웹 일괄 실행이 Ramp-A·울산·옥성 게이트 보고서를 '재로드 안 함' 상태로 덮어쓴 일이 있음, 원인(시험 또는 앱 사용) 미확인, OPEN #25). - 수용 기준(착수 전 확정): ① 모든 필수 묶음에 앱 확인 상태가 있다 ② '근거 없음'을 숨기지 않는다 ③ 거짓 일치 0·거짓 불일치 0(4개 도면 기준) ④ 앱이 확정 기록을 만들지 않는다 ⑤ 기존 시험 FAIL 0. --- ### 6.5 D단계 결과 (2026-10-19) **① 전 화면 Prism 교체**: `web/templates/base.html`을 Prism 틀(위쪽 띠·본문)로 바꾸고 `web/static/prism-app.css`를 추가해, 옛 화면의 표·버튼·입력칸·안내 문구가 Prism 토큰(색·간격·Pretendard)을 따르게 했습니다(템플릿별 개별 수정 없이 공통 틀로 교체). 상태 표시는 색과 함께 글자·기호를 씁니다. 형식 불일치 경고는 계속 닫을 수 없습니다. 어두운 테마는 시험하지 않았습니다. **② 사용설명서 v0.2.12**: 앱 확인·근거 보기·일치 묶음 일괄 확정·변수 등급·표 밖 치수 후보·도면 먼저 추천·6번째 템플릿을 반영하고, 이전 방식 일괄 확정 설명을 삭제했습니다. **③ 운곡교 P3·P4 후보 반영(A등급, 파일 하나씩)**: `tools/apply_anchor_a.py`로 앱의 후보 반영 경로를 거쳐 expected 쪽 A등급 후보를 반영했습니다(P3 29필드, P4 34필드, 반영 전 params·expected·confirm.json은 `backup/before_anchor_A_*`에 보관, 기록은 `anchor_log.json`). params 쪽 A등급 후보는 같은 도면 문자를 expected에 이미 썼기 때문에 P7 규칙으로 막혀 반영하지 못했습니다. 그 결과 묶음 단위 앱 확인 불일치는 P3 10·P4 11로 그대로이고, 필드 단위 expected 차이 줄은 69→52(P3), 75→63(P4)로 줄었습니다. 남은 불일치는 A등급 후보가 아닌 값(표 후보·params 독립 판독이 필요한 값)입니다. **④ 회귀**: fast 15/15 PASS, Rhino 그룹 결과는 OPEN #26에 기록합니다. **남은 결정**: 표 후보(expected 쪽) 검토 후 반영 여부, params 독립 판독, 운곡교 P4 도면 판(OPEN #33). --- ### 6.6 운곡교 P3·P4 실사용 결과와 앱 개선점 (2026-10-20) **결과 요약** | 교각 | 입력 | 게이트 결과 | 검사 | 계획된 FAIL | 계획 외 FAIL | | :--- | :--- | :--- | :--- | :--- | :--- | | 운곡교 P3 | 도면에서 읽은 값으로 params·expected 갱신(77곳 + 표 후보 105건 + 2차 48곳) | G1~G5 모두 PASS·승인 | 578/585 | 7 (B12, C9~C13 원래 길이 5건, C13 규칙) | 0 | | 운곡교 P4 | `apply_pier_read.py` 로 144곳 + 표 후보 118건 | G1~G5 모두 PASS·승인 | 577/585 | 8 (B11, B12, C9~C13 원래 길이 5건, C13 규칙) | 0 | - 첫 실행 → 최종 실행의 계획 외 FAIL: P3 G1 34·G2 7·G3 5·G4 28 → 0, P4 G1 18·G2 10·G3 22·G5 10(허위 G4 PASS) → 0. - 새 도구: `tools/verify_pier_geometry.py`(도면 값 55항목을 params 와 비교; P1·P3 55/55 로 재현 확인), `tools/apply_pier_read.py`(읽은 값을 params·expected 에 반영; P1·P3 `--dry` 로 재현 확인), `tools/infer_footing_rebar.py`(기초 철근 층 규칙; P1 재현), `tools/extract_coping_outline.py`. - 읽을 수 있는 값: 표 3종(받침·솔플레이트·재료표), 치수 글자, 코핑 외곽·철근 단·C15·C16, 받침 위치·회전, 기초·말뚝·기둥, 기초 철근 층(규칙 + 재료표 개수 일치), 기둥 철근(후프·결속). 읽을 수 없거나 가정: 스터럽 좌측 윗면, c14 좌측 규칙, 결속철근 끝 높이, 설계 의도. **앱 개선점 (OPEN #34, 효과 큰 순)** | # | 개선 | 근거(실제 사례) | | :--- | :--- | :--- | | 1 | 도면 읽기 도구를 후보 화면에 통합, 템플릿 재현 검증 포함 | P3 수작업 77곳, P4 144곳 | | 2 | params↔expected 일관성 검사(Rhino 실행 전) | 게이트 1회 약 150초, P3 실패의 대부분이 옛 값 혼재 | | 3 | 필드 단위 '템플릿 원본 그대로 남음' 검사 | P3: 앱 확인 불일치 0인데 게이트 40여 건 실패 | | 4 | 표 칸에서 학습한 앵커의 거짓 후보 제거 | P3·P4: 재료표 S1 길이 칸 '3.800' 을 G3 사슬 끝으로 오인 | | 5 | 일괄 실행 중단 시 중간 결과·이전 승인 요약 구분 표시 | P4: `display.py` 오류 후 승인 요약이 이전 실행 것으로 남음 | | 6 | 점 좌표를 키로 쓰는 목록 정합 검사 | P3: `hooks_up` 옛 좌표로 G4 코핑 밖 점 56개 | | 7 | 확정 사유 최소 품질 | 사유 'asf', 'afs', '12' | | 8 | 임시 등록 '설계자 확인 대기' 상태 관리, 해당 없음 항목 자동 탐지 | P2 의 G3 B9 551/493 항목이 P3·P4 에 남음 | | 9 | 보고서에 독립 근거 구분 표시 | PASS = 내부 일관성(params·expected 가 같은 읽기에서 나온 값 다수) | | 10 | P1 규칙 가정 단계(스터럽 좌측 윗면, c14 좌측 규칙)의 도면 읽기 | P4: 규칙이 틀려 재료표 역산값으로 교체 | | 11 | 도면 파일 해시·개정 번호 기록·비교 | P4 D2 사슬 오류: 사용자 CAD 판과 올린 파일 불일치 의심 | | 12 | 다른 도면 틀·형식(울산·새재1교)에서의 일반성 확인 | 교각 2개·템플릿 1개로만 확인 | **설계자 확인 대상**(OPEN #35): P3 C13, P4 B11·B12·C9·C13, D2 사슬(#33). 모두 임시 등록이며 보고서에 '설계자 확인 전'으로 표시해야 한다. **이번 작업에서 생긴 오류(재발 방지)**: `apply_pier_read.py` 가 pier_id 를 바꾸면서 `display.hidden_ids` 를 바꾸지 않아 P4 일괄 실행이 마지막 단계에서 중단됨 → 스크립트 수정(개선 3·6 과 같은 종류: 파생 값의 동시 갱신 누락). --- ### 6.7 개선 ②③④⑥ 구현 결과 (2026-10-20) | 개선 | 구현 | 시험 결과 | | :--- | :--- | :--- | | ② params↔expected 일관성(C9) | `engine/consistency.py`: 같은 양을 나타내는 두 파일 값의 규칙 103~106건(기초·말뚝·기둥, 코핑 윗면 단·하면, 받침 피치·열 위치, 코핑 철근 단·C15·C16·루프·스터럽 하단, 후프·결속 사슬, 기초 철근 층·B9·B10, 재료표 사본). 다르면 해당 묶음이 불일치(b). 규칙의 경로가 없는 교각(새재1교 등)은 건너뜀 | 완성된 P1·P3·P4: 불일치 0. P3 최초 백업 상태(`before_stage2`): 54건 모두 검출, expected G1~G4 전부 불일치. P4 `before_table_apply`: 16건 검출. 다른 형식 4종: 거짓 불일치 0 | | ③ 필드 단위 원본 잔존(C3b) | 교각 생성 시 `origin_values.json` 기록(이전 교각은 `tools/make_origin_values.py`로 초기 백업에서 재구성). 바뀐 묶음 안에서 높이로 보이는 값(10~60 m, z·단 높이·점 좌표의 z)이 기록값 그대로이면 주의(w) | P3 `before_hooks_up` 상태에서 `hooks_up` 좌표 4개를 정확히 지목. 완성된 상태: 경고 0(처음에는 길이 12400·12000 등을 높이로 오인해 경고가 많았으나 높이 키로 제한) | | ④ 거짓 앵커 | `engine/anchors.py` `TABLE_RULE="single"`: 후보를 따라간 근거가 재료표 칸 **하나**뿐이면 C등급(`table_only`). 두 방식(`none`: 표 칸을 아예 제외)과 비교 | P3·P4 확인값 기준 B등급 오답: 끔 10/65 · single 2/39 · none 3/29. A등급 오답 0 유지. 부작용: P3에서 expected:G2(일치→주의)·params:column_rebar(일치→근거 없음) 2개 묶음의 근거가 줄어듦(표 칸 하나로 맞던 B등급 후보) | | ⑥ 점 좌표 목록 | C9 규칙: `c14.hooks_up`의 각 점이 `c14.points`에 있어야 함 | 최초 오류(P3 `before_hooks_up`)의 4점 모두 검출, 점 하나를 옮기면 해당 항목만 깨짐 | **검사 환경 정리**: 실제 사용 중 `운곡교p2`(휴지통으로 이동)에 의존하던 시험 5종(`test_open19`·`test_rampa`·`test_saejae`·`test_okseong`·`test_ulsan_p2`)과 `test_anchors`를 `tools/testlib.pier_dir`(휴지통 최신 복사본, 대소문자 구분)로 바꿈. `test_autocheck`는 P3가 완성 값을 갖게 되어 최초 백업(다른 교각 값) 상태로 시험하도록 바꿈. 회귀 fast 16/16 PASS(`test_consistency` 추가). **남은 개선**: ① 읽기 도구 통합, ⑤ 일괄 실행 중단 표시, ⑦ 확정 사유 품질, ⑧ 임시 등록 관리, ⑨ 독립 근거 구분 표시, ⑩~⑫. --- ### 6.8 개선 ①⑤ 구현 결과 (2026-10-20) | 개선 | 구현 | 시험 결과 | | :--- | :--- | :--- | | ① 읽기 도구 통합 | `engine/geomread.py`: P3·P4 모델링 때 따로 만든 읽기 도구(코핑 외곽·철근 선·원, 기초·말뚝·기둥 글자, 받침 폴리라인, 재료표, 기초 철근 규칙)를 하나로 합친 순수 함수 `read()`(부작용 없음, 사본과 변경 목록 반환)와 `apply_selected()`. `engine/footing_rule.py`(기초 철근 규칙). 화면 「도면에서 읽기」(`/pier/<이름>/geomread`): 묶음별 현재/읽은 값/근거 표, 체크한 줄만 반영, 반영 전 `backup/before_geomread_*`, `read_log.json`, 추론 줄 기본 미선택, 도면 틀 일치율 70 % 미만 또는 필요한 선·글자가 없으면 이유를 알리고 읽지 않음. `tools/apply_pier_read.py` 는 같은 읽기의 명령줄 판 | `tools/test_geomread.py` PASS: 운곡교 P1·P3 에서 읽은 값 = 현재 값(변경 0), P4 는 추론 줄 1건만, 초기 P4 백업(P1 복사)에서 144건 제안이 검증된 P4 값과 모두 같음(표시 선택 `hidden_ids` 제외), 다른 도면 틀 2종 거절, 화면에서 고른 줄만 기록·백업·로그·확정 무효화 | | ⑤ 일괄 실행 중단 표시 | `batch.json` 에 `started`·`reason`(error/fail/blocked, 서버 중단은 killed)·`error`·`gate`, 게이트 결과에 `at`. 게이트 화면: 중단 이유 안내, 결과 시각과 '이전 실행 결과' 표시, 중단되기 전에 계산된 검사기 원본(`<게이트>.json` 이 기록(`_gate.json`)보다 새로울 때)을 '중단된 실행의 임시 결과'로 표시(승인·보고서에 쓰이지 않음), 입력이 바뀐 뒤의 승인은 '승인 기록은 이전 입력 것(무효)' | `tools/test_batch_notice.py` PASS: 오류·FAIL·조건 미충족·서버 중단 안내, 이전 실행 결과 표시, 임시 결과, 무효 승인 표시, 완료된 실행에는 안내 없음, 실제 작업자(`_batch`)에 가짜 Rhino 를 연결해 세 중단 경로의 기록 확인 | **선택과 한계** - 읽기 결과를 params 와 expected 에 함께 채우는 것은 두 파일의 독립성을 떨어뜨림 → 화면 문구와 앱 확인 C9 설명으로 알림, 표(재료표) 값은 표 후보값 화면에서 따로 대조. - 표시 선택 `display.hidden_ids` 는 교각 이름이 바뀌면 템플릿의 숨김을 새 이름으로 옮겨 제안(P4 는 사용자가 비움으로 정함). - 읽기 규칙의 범위: 운곡교 도면 틀 1종, 교각 4개. 좌측 스터럽 윗면(추론)·c14 좌측 규칙·결속철근 끝 높이는 P1 규칙 가정. - 환경: 일괄 실행 오류 시 중간 결과가 `<게이트>.json` 으로 남는 것을 이용(별도 저장 없음). **남은 개선**: ⑦ 확정 사유 품질, ⑧ 임시 등록 관리, ⑨ 독립 근거 구분 표시, ⑩ P1 규칙 가정 단계 읽기, ⑪ 도면 해시·개정 번호, ⑫ 다른 도면 틀 일반성. --- ### 6.9 검토 요약 확정 (2026-10-20) **문제**: 묶음 20~23개를 하나씩 확정하는 데 시간이 오래 걸리고, 사유가 비거나('12', 'asf') 무엇이 바뀌었는지 보기 어려웠다. 사용자 제안: 앱이 일괄 확정하고 사용자는 일괄 검토만 한다. **결정(권고안)**: "앱이 확정"은 확정의 의미(사람이 도면과 대조했다는 기록)를 없애므로 채택하지 않고, **앱이 검토를 준비하고 사람이 한 화면에서 검토·체크해 한 번에 확정**한다(D1 유지). 근거 없음 묶음은 **항목별 체크**(a)를 요구, 기존 개별 확정 화면은 예외 처리용으로 유지. | 요소 | 구현 | | :--- | :--- | | 화면 | `/pier/<이름>/review` (교각 화면 [검토 요약으로 확정]). 확정이 필요한 묶음을 네 구역으로: 불일치(확정 불가), 주의·근거 없음(항목별 체크), 사람 결정 기록(체크), 일치(근거 훑어보기 + 구역 체크 1회) | | 앱이 준비하는 것 | `engine/review.py`: 바뀐 것(교각 생성 시점 값 기록 `origin_values.json` 대비 변경 값 수와 예), 앱이 확인하지 못한 것(근거 없음·주의 검사 항목), 값의 출처(`read_log.json`·`anchor_log.json` 이력), 사유 자동 작성(`auto_reason`) | | 사람이 하는 것 | 도면과 대조한 묶음에 체크, 목록 끝까지 읽기(표식 `review_view.json` = 그때 목록의 해시), 확정자 이름, 공통 의견(선택) | | 기록 | 묶음별 확정 기록에 사유(앱 확인·변경·출처·의견 포함), 확정 당시 앱 확인 상태, 이름. 앱은 체크가 없으면 아무것도 확정하지 않음 | | 안전장치 | 이름·끝까지 읽기·체크 없으면 거절, 값이 바뀌면 표식 무효, 불일치는 요청에 id 가 들어와도 확정하지 않음 | **시험** `tools/test_review.py`(PASS): 화면 조회만으로는 확정 0, 표식·이름 없으면 거절, 체크 없으면 0, 일치 구역은 구역 체크로만, B·D 는 체크한 것만, 불일치는 거절, 기록에 사유·앱 확인 상태·이름, 값이 바뀌면 표식 무효, 불일치를 고치면 모든 필수 묶음이 이 화면으로 확정되어 게이트가 열림. 회귀 fast 19/19. **후속 변경 (같은 날)**: ① 「도면에서 읽기」가 표 값(받침·솔플레이트·재료표 후보)을 같은 화면에 "표 값" 구역으로 포함(`geomread.table_changes`), 반영은 `reader.apply_proposals` 와 같은 규칙, 받침마다 다른 솔플레이트 길이는 `{번호: 값}` 으로 정규화 — 새 교각에서 템플릿 원본 값이 한 화면으로 모두 도면 값이 됨(시험: 초기 P4 백업 + 읽기 + 표 행 = 검증된 P4 의 표 관련 필드, 알려진 예외는 앵커 값·`tie_offset` 상수·낡은 직경 기록). ② 「검토 요약 확정」에 [모두 체크]·[모두 해제] 버튼, 주의 표시(템플릿 원본 그대로·설계자 확인 전 임시 등록 포함)를 칩과 확정 사유에 기록, 주의 표시가 있으면 모두 체크 시 확인창. 불일치 묶음은 여전히 확정 불가, 이름·끝까지 읽기·체크 없이는 확정되지 않음. 앞서 제안한 '낮은 위험/높은 위험 두 단계' 대신 사용자 요청에 따라 일괄 체크 + 주의 표시로 구현(위험도별 분류는 미구현). **한계**: 체크는 사용자의 선언이라 실제 대조 여부는 앱이 확인할 수 없다. 사유의 "무엇을 어떻게 대조했는지"는 공통 의견에 적어야 남는다. 앞으로 앱 확인 'C10 도구 읽기 이력'을 근거(출처, 독립 검증 아님)로 연결하면 근거 없음 항목이 줄 수 있다(미구현). ### 6.10 운곡교 P4 복구 결과와 앱 수정 계획 (2026-10-20) > 상태: **계획 `[미확정]`** — 코드는 고치지 않았다. 아래 W1~W8은 사용자 승인 후 PDCA 순서로 구현한다. #### 6.10.1 사고 경위와 복구 | 시각 | 사실 | | :--- | :--- | | 09:08 | 첫 P4 G1~G5 통과·승인 → 11:20 사용자가 삭제(휴지통 `운곡교P4_20261020_112015`) | | 11:22~12:01 | 템플릿에서 다시 만든 판에 읽기·결정 반영 → 12:01 삭제(휴지통 `운곡교P4_20261020_121116`) | | 12:11 | 템플릿(운곡교P1형)에서 또 새로 만들고 읽기 279건 반영 → 12:12 검토 요약으로 5개 게이트 묶음 일괄 확정 | | 12:15 | 일괄 실행: G5만 통과, G1~G4 **계획 외 FAIL 11건**으로 G1에서 중단 | | 복구 | 휴지통 판의 `expected.json`·`params.json` 복원(현재 판 백업 `data/운곡교P4/backup/before_restore_decisions_20261020/`). 임시 폴더 시험: G1 171/171·G2 42/42·G3 71/73(계획 2)·G4 110/116(계획 6)·G5 183/183, 계획 외 0 | 12:11 판에서 템플릿 값으로 되돌아가 있던 곳(결정 소실 6곳): ① 앵커 `rear_first_from_tip` 1198 → 1232 ② `tie_offset` 22.5 → 17.5 ③ 좌측 스터럽 윗면 40447([추론]) ④ 코핑 상단 `a` 11856/11881/11905 → 11855/11880/11904 ⑤ c14 높이 .5 → .1 ⑥ 계획된 FAIL B11·C13 누락, B12 사유가 P1 값(28/34)으로 복귀. 1232는 기준 템플릿 운곡교P1형의 값이며 교각마다 다르다(P1 1232·P2 1223·P3 1212·P4 1198). #### 6.10.2 원인 (반복될 수 있는 실패) | # | 원인 | 근거 | | :-- | :--- | :--- | | C1 | 사람의 결정(앵커 채택, 계획된 FAIL, 역산값)이 교각 데이터 안에만 있어 교각을 지우면 같이 사라지고, 새 교각에 다시 적용할 수단이 없다 | 6곳 소실 | | C2 | 앱이 알고 있는 후보(B등급 1198)가 읽기에 자동 반영되지 않고, 경고만 남은 채 확정됨 | G1 확정 사유 `현재 1232 ≠ 도면 1198` | | C3 | 원본 잔존 검사(C3b)가 높이로 보이는 값만 비교해 `tie_offset`·`a` 등을 놓침 | 12:15 FAIL | | C4 | params와 expected가 서로 다른 값을 가리켜도 실행 전에 막지 못함(모델은 1198, 기준값은 1232) | G1 후열 패드 중심 X 5건 | | C5 | 계획된 FAIL이 템플릿(P1) 승인 상태로 상속되고, 새 교각에 필요한 항목은 사람이 추가해야 함 | B11·C13 누락 | | C6 | 게이트 실패가 어느 입력 필드 때문인지 앱이 알려 주지 않아 휴지통 판과 수동 비교가 필요했음 | 이번 복구 | #### 6.10.3 가능과 불가능의 경계 | 값의 종류 | 앱이 채울 수 있나 | 방식 | | :--- | :--- | :--- | | 표·글자·치수(재료표, ELEVATION TABLE, 사슬) | 가능 | 도면에서 읽기(같은 틀 A등급 165건 전부 정답) | | 식이 정해진 계산값 | 가능(식 확인 후) | 규칙으로 다시 계산, 출처 「계산」 표시 | | 도면에 없는 역산·추론값 | 제안만 가능 | 사람이 채택, 결정 기록에 남겨 재적용 | | 선·점으로 그린 기하(R3·R4) | 불가능 | 시험에서 미채택(오답 A 2~7건/쌍) | | 도면끼리 충돌하는 값 | 불가능 | 사람이 선택, 계획된 FAIL·설계자 확인 대기 | | 다른 도면 틀 | 불가능 | 앵커 새로 학습 | 모든 묶음이 읽기로 채워지지는 않는다(P4: `tol_mm`·`rebar_palette`·`planned_fail`·`materials`는 읽기 0건). 게이트 시작에는 자기 묶음 확정과 이전 게이트 승인이 필요하나, 확정은 사람의 선언일 뿐 값의 정확성을 보장하지 않는다(P4 12:15). #### 6.10.4 수정 항목 설계 원칙: 앱이 준비하고 사람이 한 화면에서 체크해 한 번에 확정한다는 기존 결정(D1, 6.9절)을 유지한다. 확정 부담을 늘리지 않고, **앱이 더 많이 채우고 사실로 확인되는 모순만 차단**한다. | # | 수정 | 해결하는 원인 | 내용 | | :-- | :--- | :--- | :--- | | W1 | 실행 전 관문 | C4·C2 | 일괄 실행 전에 params↔expected 불일치(사실)와 후보≠현재 값을 모아 보여 주고, 불일치는 실행을 막고 후보 차이는 확인을 받는다. 기존 C9(`engine/consistency.py`)에 앵커 대상 필드를 추가하고 검사 항목 → 깨질 게이트 항목을 예측한다 | | W2 | 읽기에 후보 빠짐없이 | C2 | 앱이 아는 B등급 이상 후보 중 현재 값과 다른 것을 「도면에서 읽기」 화면에 기본 선택으로 올린다(추론 줄은 지금처럼 기본 미선택) | | W3 | 결정 기록 분리 | C1·C5 | `decisions.json`에 사람 결정(앵커 채택, 계획된 FAIL, 역산·추론값과 사유)을 읽기 이력과 따로 보관, 교각 삭제 시 휴지통에 함께 이동. 「이전 결정 다시 적용」 화면에서 같은 도면 틀일 때만 기본 선택, 고른 것만 반영 | | W4 | 원본 잔존 검사 확대 | C3 | C3b를 변수 등급 V1·V2 숫자 필드 전체로 넓혀 템플릿 값 그대로인 필드를 「확인 필요」로 모은다. 파생값(`a`, c14 높이)이 어떤 입력에서 나오는지 식을 먼저 조사 | | W5 | 실패 → 입력 필드 연결 | C6 | 계획 외 FAIL마다 원인 후보 필드를 표시(예: `rear pad centre X` → `G1.seats.rear_first_from_tip`), 「계획된 FAIL로 등록」 버튼(사유 필수) | | W6 | 계획된 FAIL 상속 상태 | C5 | 템플릿에서 상속된 항목은 「미승인(상속)」으로 표시하고 게이트 결과로 해당 여부를 대조 (OPEN #34 ⑧과 통합) | | W7 | 재현 시험 | 전체 | 검증된 첫 P4를 정답으로 「템플릿 + 읽기 + 재적용한 결정」 결과가 같은지 비교하는 `tools/test_pier_rebuild.py`. 이번 6곳 소실을 잡아야 통과 | | W8 | 템플릿 승격 | C1 | 같은 도면 틀에서 결정이 반복되면(C13 L 28.966, B12 32/38) 「운곡교P3·P4형」 템플릿 후보로 올린다. 사용자 승인 필수, 설계자 확인 대기 항목은 상속 상태 유지 | 시험 방식: 각 항목마다 P4 12:11 판(결정 소실 상태)을 입력으로 쓰는 음성 시험과, 완성된 P1·P3·P4에서 거짓 차단 0건을 확인하는 양성 시험을 둔다. #### 6.10.5 순서와 결정 필요 사항 | 단계 | 항목 | 이유 | | :--- | :--- | :--- | | 1 | W1·W2 | 변경이 작고 이번 사고의 직접 원인을 막는다(같은 화면) | | 2 | W3·W7 | 근본 대책과 그 검증 | | 3 | W5·W6 | 실패 해석과 계획된 FAIL 정리 | | 4 | W4·W8 | 파생식 조사·템플릿 승인이 필요해 뒤로 미룸 | | # | 결정 필요 | 권고 | | :-- | :--- | :--- | | D7 | 이전 결정의 자동 재적용 범위 | 같은 도면 틀일 때만 기본 선택, 나머지는 목록에서 고름 | | D8 | 기존 교각에 결정 기록을 소급할지 | 새 교각부터만 적용 | | D9 | 미확정 상태의 시험 실행(승인 없이 임시 폴더에만 결과)을 앱에 둘지 | 둔다. 승인 기록은 남기지 않음 | | D10 | W4의 파생식 조사를 1~3단계 뒤로 미룰지 | 미룬다 | **미해소(P4 승인)**: 복구한 값은 아직 확정되지 않았다. 미확정 5개 묶음(`expected:planned_fail`·G1·G2·G4, `params:coping_rebar`)을 검토 요약에서 재확정하고, 일괄 실행·G4·G5 승인 후 보고서 초안을 쓴다(OPEN #37). ### 6.11 W4 원본 잔존 검사 확대 계획 (2026-10-20) > 상태: **계획 `[미확정]`** — 코드는 고치지 않았다. 실측 스크립트: `Code/교각모델링앱/tools/analysis_w4_residual_sizing.py`. #### 6.11.1 목적 새 교각을 템플릿에서 만든 뒤 **도면 값으로 바뀌어야 하는데 템플릿 값 그대로 남은 필드**를 150초짜리 게이트 실행 전에 찾아 사람에게 보여 준다. #### 6.11.2 현행 C3b와 한계 `engine/verify.py` `stale_fields_check`: ① 키 이름이 높이처럼 생긴 필드(`height_like`)만 ② 값이 10~60 m ③ 같은 묶음에서 그런 값이 3개 이상 바뀐 경우에만 ④ 생성 시점 값(`origin_values.json`)과 같으면 경고(w, 실패 아님). 그래서 높이가 아닌 값(`tie_offset`, 앵커 `rear_first_from_tip`, 코핑 상단 `a`)은 비교 대상이 아니다. #### 6.11.3 실측 (P4 12:11 판 = 결정 소실 상태, 정답 = 복원한 P4) | 항목 | 값 | | :--- | :--- | | 템플릿 숫자 필드 / P1~P3에서 교각마다 달라진 필드 | 1,676 / 958 | | 12:11 판에서 템플릿 값 그대로인 숫자 필드 | 767 | | 현행 C3b가 잡은 후보 | **0건** | | 「템플릿 값 그대로 + 교각마다 달라지는 필드」(단순 확대) | 88건 중 실제 틀림 5건 → **정밀도 6 %** (거짓 경보 83건) | | 위 기준 + 3교각 모두 서로 다른 값 | 2건 중 1건(`rear_first_from_tip`) → 정밀도 50 %, 놓침 많음 | 해석: **통계만으로 확대하면 경보가 94 % 거짓이라 쓸 수 없다.** 거짓 경보 대부분은 P4가 P1과 같은 구조라 맞게 같은 값인 필드(받침 이동 검사, 기초 철근 층, 솔플레이트 표 등)다. 실제로 게이트를 깬 필드는 소수(`rear_first_from_tip`, `tie_offset`, 코핑 상단 `a` 3개)다. 한편 c14 높이(.1 대 .5)와 계획된 FAIL 차이는 템플릿 잔존이 아니다(c14는 0.4 mm 차이로 게이트는 통과, 계획된 FAIL은 목록 항목 누락) → W3·W5·W6 몫이다. 필드별 이력(검증된 교각): `tie_offset` P1·템플릿 17.5, P2·P3·P4 22.5 / `a` P1·P2 11855·11880·11904, P3 11856·11880·11905, P4 11856·11881·11905 / `rear_first_from_tip` 1232·1223·1212·1198(전부 다름). 즉 교각마다 달라지는 폭이 작은(1~5 mm) 값은 사람이 눈으로 놓치기 쉽다. #### 6.11.4 설계 — 통계 경보 대신 단계별 확인 | # | 내용 | 효과·비고 | | :-- | :--- | :--- | | W4a | **교각별 확인 목록(watch-list)**: `variability.json`에 필드 단위로 「교각마다 달라지며 템플릿 값이면 확인 필요」를 지정. 초기 목록은 이력으로 실증된 필드(위 3개와 `G2.schedule_L` 등)로 시작. 템플릿 값 그대로면 앱 확인 「주의」(C3b 확장), W1 실행 전 관문에 연결 | 정밀도가 높은 소수 목록. 새 교각이 검증될 때 도구가 후보 추가를 제안하고 담당자가 승인 | | W4b | **통계 후보는 경보가 아니라 묶음 요약**: 「교각마다 달라지는 필드 N개가 템플릿 값 그대로」를 묶음 단위로 접어 보여 주고 필드 목록은 펼쳐 볼 때만 표시 | 거짓 94 %를 경보로 쓰지 않으면서 훑어볼 수 있게 함 | | W4c | **읽기 후보 연동**(W2): 목록·통계 후보 중 도면에서 후보(앵커·표)가 있는 필드는 「도면에서 읽기」 화면에 기본 선택으로 올림 | `rear_first_from_tip`은 B등급 후보가 있었다 | | W4d | **파생값 조사**: `a`, `tie_offset` 등이 어떤 입력·도면 글자에서 나오는지 P1~P4 값과 도면 문자로 조사. 식이 확인되면 계산값으로 제안(출처 「계산」), 못 찾으면 W4a 목록에 남김 | 현재 식을 모름. 조사 결과에 따라 W4a 목록이 줄어듦 | | W4e | **교각 그룹별 기본값 승격**(W8 연계): `tie_offset` 22.5처럼 P2 이후 전부 같은 값은 템플릿 P1 값(17.5)이 오히려 예외이므로, 같은 도면 틀 그룹 템플릿에서 기본값을 바꾸는 후보로 제안 | 승인 필수 | #### 6.11.5 판정 규칙 (C3b 확장안) | 조건 | 판정 | | :--- | :--- | | W4a 목록 필드가 생성 시점 값 그대로 | **주의(w)**, 검토 요약의 해당 묶음에 필드명·템플릿 값·교각별 이력 표시 | | 위 값이 읽기 후보(A·B등급)와 다름 | 주의 + 읽기 후보로 제시 | | 통계 후보(W4b) | 정보(건수만), 판정에 영향 없음 | | 묶음 전체가 그대로 | 기존 C3 | 실패(불일치)로 판정하지 않는다: 같은 값이 맞을 수도 있고(P2~P4 `a` 11880 등), 근거 없이 막으면 6.9절의 일괄 검토 흐름을 해치기 때문이다. 막는 것은 W1(params↔expected 사실 불일치)이 맡는다. #### 6.11.6 시험 | 시험 | 기준 | | :--- | :--- | | 음성(잡아야 함) | P4 12:11 판에서 `rear_first_from_tip`·`tie_offset`·`a` 3개 모두 주의로 표시 | | 양성(거짓 경보 억제) | 완성된 P1·P2·P3·P4에서 W4a 목록 경보 0건 (값이 도면 값이면) | | 통계 후보 | 12:11 판 기준 건수만 표시, 판정 불변 | | 회귀 | `tools/test_autocheck.py`·`test_consistency.py`·`test_review.py` 통과, 기존 C3b 동작 유지 | | 신규 | `tools/test_stale_watchlist.py` | #### 6.11.7 순서와 결정 필요 1. W4d 파생값 조사(코드 변경 없음, 결과를 보고) → 2. W4a·W4b 구현 → 3. W4c(W2 구현 시 함께) → 4. W4e(W8 승인 시). | # | 결정 필요 | 권고 | | :-- | :--- | :--- | | D11 | 초기 watch-list 필드 범위 | 게이트를 실제로 깬 3개 + `G2.schedule_L`로 시작해 사고 때마다 추가 | | D12 | 통계 후보(W4b)를 화면에 둘지 | 묶음 요약만 두고 경보 아님 | | D13 | 템플릿 값 그대로를 실패가 아닌 주의로 둘지 | 주의 유지(차단은 W1 사실 불일치만) | --- ## 7. 리스크·결정 사항 ### 7.1 리스크 | # | 리스크 | 대응 | | :-- | :--- | :--- | | R1 | 앱 확인 '일치'를 "도면이 맞다"로 오해 | 근거 보기에서 '무엇과 무엇이 같은가'를 문장으로 표시, 신뢰 등급 병기 | | R2 | 규칙·앵커가 4개 도면에 과적합 | 등급 C·'없음'을 정상으로 표시, 새 형식 도면마다 앵커 추가 | | R3 | 앵커 소급 추출 비용(원본 4교각) | D6 결정(신규부터 vs 소급) | | R4 | 앱 확인 규칙이 생성 스크립트와 같은 논리여서 순환 | 도면 원자료(DXF·문자 색인)를 직접 읽는 경로만 사용, 스크립트 재생성 일치(C8)는 '독립성 낮음'으로 표시 | | R5 | 일괄 확정이 다시 도장화 | 일치만 대상, 근거표 열람 조건, 주의·불일치는 사유 필수 | | R6 | 변수 등급 오분류 | `variability.json`은 템플릿 원본 교각 담당자가 확정, 분류 변경은 별도 Task | ### 7.2 결정 사항 | # | 내용 | 상태 | 권고 | | :-- | :--- | :--- | :--- | | D1 | 확정 주체 | **결정 2026-10-14 / 심영표: 앱 확인 + 사람 확정** | — | | D2 | 표 밖 치수 탐색 방식 | **결정 2026-10-14 / 심영표: 규칙 + 템플릿 앵커** | — | | D3 | F(고정) 항목 편집 시 처리 | **결정 2026-10-15 / 심영표: 권고안** | 경고 + 사유 입력(차단은 생성기 개발자 모드에서만) | | D4 | 일괄 확정 조건 | **결정 2026-10-15 / 심영표: 권고안** | '일치' 묶음만, 근거표를 한 번 열어야 활성화 | | D5 | 착수 범위·순서 | **결정 2026-10-15 / 심영표: 권고안** | A → B 먼저(위험 큰 P1·P2 해소), C는 B 검증 뒤 | | D6 | 앵커 소급 추출 | **결정 2026-10-15 / 심영표: 권고안** | 옥성교·Ramp-A(최근, 판독 스크립트 최신)부터, 나머지는 필요 시 | --- ## 부록 A. 보호 템플릿 묶음 분류 (등급 초안, 담당자 확정 전) | 묶음 | 운곡교P1형 | 울산형 | Ramp-A형 | 옥성교형 | | :--- | :-: | :-: | :-: | :-: | | `pier_id` | F | F | F | F | | `scope`·`builders`·`checkers`·`negative` (실행 설정) | F (없음=기본) | F | F | F | | `lean_concrete`·`footing`·`column`·`materials` | V1 | V1 | V1(기초 없음) | V1 | | `piles` / `pile` | V1 | — | V1(`pile` 구간) | V1 | | `coping` | V1 + 점 목록 V2 (`form` F) | V1 + V2 (`form` F) | V1 + V2 (`form` F) | V1 + V2 (`form`·`skew_deg` 구조는 F) | | `bearing_seats`·`sole_plates` | V1 + 위치 V2 (대좌 구조 F) | V1 + V2 | V1 + V2 | V1 + V2 (대좌 공유 구조 F) | | `rebar_marks` | 직경 V1, 마크 체계 F | 동일 | 동일 | 동일 | | `column_rebar` | V1·V2 (`form` F) | V1·V2 | V1·V2 | V1·V2 | | `footing_rebar` | V1·V2 | V1·V2 | — (`shaft_rebar` V1·V2) | **V3** (중심선 목록) | | `coping_rebar` | V1·V2 (규칙 값) | **V3** | **V3** | **V3** | | `expected.G1~G5` | V1·V2 (**params와 독립 입력**) | 동일 | 동일 | 동일 | | `expected.planned_fail`·`rebar_palette` | 사람 결정 기록(교각별) | 동일 | 동일 | 동일 | | `display`·`_schema`·`_meta`·`*_src`·`hitl_decisions*` | F / 참고 | 동일 | 동일 | 동일 | > 이 표는 묶음 수준의 초안입니다. 필드 수준 분류(`variability.json`)는 A단계에서 템플릿마다 작성하고 담당자가 확정합니다. ## 부록 B. 근거 파일 | 구분 | 경로 | | :--- | :--- | | 화면·동작 | `Code/교각모델링앱/web/templates/pier.html`, `web/app.py`(`confirm_all`, `unconfirmed`), `web/store.py`(`GATE_SECTIONS`, `section_state`, `confirm`, `set_section`) | | 표 판독·후보 | `engine/reader.py`(`table_candidates`, `field_candidates`, `proposals`, `el_list`, `entity_info`) | | 사용 방법 | `DOC/04_실행/실행_T형교각모델링앱사용설명서_2026-10-14_v0.2.07.md` §4~5, §9 | | 일반화 이력 | `context-migration/OPEN_미해결목록.md` #19·#23·#24·#25, `DOC/02_분석/분석_운곡교P2교각도면판독_2026-10-12_v0.1.00.md` §7 | | 표 밖 치수 판독 사례 | `Code/옥성P1판독/extract_g*.py`, `DOC/02_분석/분석_옥성교P1교각도면판독_2026-10-14_v0.1.07.md` |