# 원본 기능 재감사 기준표 감사 기준일: 2026-07-15 현행 판정 갱신: 2026-07-18 > 현재 완료·차단·외부 입력 범위는 [`MIGRATION_STATUS.md`](MIGRATION_STATUS.md)가 > 우선한다. 2026-07-15 패키지·연결 설명은 당시 감사 증거로 보존한다. 원본(읽기 전용): `C:\Users\MD\source\repos\MBN_STOCK_N` 마이그레이션 대상: `C:\Users\MD\source\repos\MBN_STOCK_WEBVIEW` ## 감사 결론 현재 실행 대상은 `.NET 8 / C# / WinUI 3 / Windows App SDK 1.8 / WebView2` 기반 `MBN_STOCK_WEBVIEW.LegacyParityApp`이다. 이는 웹사이트가 아니라 로컬 Web 자산을 WebView2에 표시하는 x64 Windows 데스크톱/MSIX 앱이다. 초기 프로토타입 문서의 “미이관 버튼 disabled”, “Tornado2에 연결하지 않음”, “DB write 없음”은 현재 구현 상태가 아니다. 원본 UI 이벤트는 LegacyParityApp → strict bridge → C# workflow로 연결된다. 2026-07-18에는 원본의 마지막 미연결 활성 이벤트였던 10초 DB 상태 감시를 연결했고, 개발 MSIX 전체 UI/DB와 실제 PGM runtime route 32/34를 검증했다. 미검증 두 route는 원본에도 없는 외부 영상 자산 때문에 fail closed한다. 기본 송출 모드는 계속 `DryRun`이다. ## 상태 정의 | 상태 | 의미 | |---|---| | `완료` | 현재 LegacyParityApp 코드와 표에 명시한 자동/통합 검증에 반영됨. package/Live 여부는 각 행의 증적 범위로 별도 판정 | | `부분 실측` | 현재 package 또는 Live의 표에 명시한 범위만 실제 확인했으며 scene/PGM 전체 통합으로 확대할 수 없음 | | `현재 빌드 실측 제외` | 구현 경로는 있으나 현재 병렬 변경을 합친 package-context/CDP/PGM 결과를 아직 이 감사의 성공 증거로 채택하지 않음 | | `외부자산 필요` | 코드로 만들 수 없는 Git/MSIX 밖의 승인 영상·배경이 제공되지 않음 | | `외부 데이터 정합성` | 현재 DB view/data가 원본 규칙의 fresh identity를 공급하지 않아 추정 없이 차단함 | ## 우선순위별 결과 | ID | 우선순위 | 기능 | 상태 | 현재 판정과 증적 | 남은 경계 | |---|---|---|---|---|---| | LF-001 | P0 | `s6001` 해외지수 영상 | 외부자산 필요 | builder와 trusted asset 검사는 완료. 승인 Cuts에 국가 영상 13개가 없음 | 제공 후 asset preflight와 해당 scene PGM | | LF-002 | P0 | cut/asset coverage | 완료 | active alias 45개 `.t2s` 존재. alias missing/unsafe 0, asset unsafe 0, asset missing 14를 분리 보고 | 누락 자산 자체는 LF-001/LF-003 | | LF-003 | P0 | `s5006` 큐브 배경 | 외부자산 필요 | `Video\큐브배경.vrv` 1개가 승인 Cuts에 없음. builder 누락이 아님 | 제공 후 s5006 DryRun/PGM | | LF-004 | P0 | 실제 개발 DB write | 완료 | GraphE 4 + PList/AList 2 + ThemeA KRX/NXT 2 + EList 1, 총 9개가 create/save→fresh readback→delete→absence PASS, 잔여 0 | 운영 DB write를 뜻하지 않음 | | LF-005 | P0 | 개발 Tornado2/PGM 최종 통합 | 부분 실측 | 5001/5074 재검증과 자산 비의존 30개 route를 실제 PGM에서 순차 검증. 5077 20페이지 전체, 5088 전환, 이전/final unload 포함. `FAILURE=0`, `ERROR=0`, retry 0, `OutcomeUnknown=false` | 외부자산이 없는 s5006/s6001만 제공 후 실제 PGM 필요 | | LF-006 | P0 | 원본 35 scene | 완료 | 원본 inventory와 source 기준선 35/35, DTO→mutation→runtime matrix 통과 | 모든 scene의 실제 PGM 완료로 확대 해석 금지 | | LF-007 | P0 | PageN/NEXT | 완료 | 자동 테스트와 실제 PGM에서 5077 6행 1/20→20/20, 마지막 페이지, playlist NEXT, 5088 12행 1/20 전환을 확인 | 없음 | | LF-008 | P0 | 원클릭 TAKE IN | 완료 | 보이는 TAKE IN/F8 한 번으로 fresh page load 후 PREPARE 1회→TAKE IN 1회. native PREPARE는 진단용으로 유지하되 hidden | unknown에서 재시도 금지 | | LF-009 | P0 | C# 권위/strict bridge | 완료 | Web은 intent만 전송. `LegacyBridgeProtocol` allowlist와 `LegacyOperatorController` snapshot이 DB identity·playlist·scene·송출 상태의 권위 | 새 intent에도 동일 경계 유지 | | LF-010 | P1 | 10개 탭과 action inventory | 완료 | 10탭, fixed 328, 업종 44, 종목 31, 비교 target 24/action 9를 폐쇄형으로 고정 | 동적 DB 행은 별도 검증 | | LF-011 | P1 | UC4/UC6/UC7 클릭 | 완료 | 테마·전문가·거래정지는 원본 단일 클릭. UC4/UC6 행은 fixed tree handler와 독립, stale generation 거부 | 없음 | | LF-012 | P1 | GraphE/FSell/VI | 완료 | GraphE CRUD·찾기·정렬·행 double-click, FSell/VI 확인 시 save+playlist append+close, 취소 경계 이관 | s5025/VI 전용 PGM은 LF-005 | | LF-013 | P1 | PList/AList | 완료 | 목록·생성·save/load/delete·행 double-click 이관, 개발 DB write/readback/cleanup PASS | 기존 blocked raw row는 추정 복원 금지 | | LF-014 | P1 | ThemeA/EList | 완료 | 검색·신규·편집·삭제·종목 구성·Delete key, ThemeA exact-title 중복확인, EList opaque `rowId` drag 재정렬 이관. 실제 UI에서 ThemeA 500건 중복 read와 EList 5행 reorder 확인 | scene PGM은 LF-005 | | LF-015 | P1 | UC5 해외 | 완료 | 해외업종·해외종목·해외지수 조회와 playlist 경로 이관 | s6001 13개 영상은 LF-001 | | LF-016 | P1 | F2/F3 기본 배경 | 외부자산 필요 | sibling background root, picker, background-none와 trusted path 검사는 완료. 이 장비에 `기본.vrv`가 없음 | 제공 전 fail closed | | LF-017 | P1 | 시스템 종료 확인 | 완료 | 원본 제목 `매일경제TV`, 중립 문구, 예/아니요와 기본 아니요를 유지하며 자동 TAKE OUT/반대 명령 금지 경계를 코드·자동 테스트로 유지 | 현재 Release package-context 회귀는 LF-005와 함께 판정 | | LF-018 | P1 | 원본 비교쌍/수동 파일 | 완료 | `종목비교.dat` 8쌍 1회 import·재시작 marker, FSell 3×5행과 VI 9항목 trusted parser/store 검증 | 원본 파일은 계속 읽기 전용 | | LF-019 | P1 | 실제 DB read→DTO→mutation | 완료 | Oracle/MariaDB 필수 scene selector 33/33, 전체 query 58건 PASS | 외부 asset/PGM 성공과 별도 | | LF-020 | P2 | FarPoint 대체 | 완료 | 실제 개발 MSIX에서 종목 검색·키보드, 컷 다중 drag, 플레이리스트 이동/drag와 focus 경계를 Windows 입력으로 재검증. DOM/C# 회귀도 유지 | 활성 Print/Excel export는 원본에도 없음 | | LF-021 | P2 | 패키지 단일 인스턴스·모달 격리 | 완료 | 두 번째 activation, child modal Escape, 전역 키 격리, Tab trap, focus 복귀와 PList pending close lock을 자동 검증하고 PList 모달을 실제 입력으로 재검증 | 고객 서명 MSIX의 clean PC 설치 검증은 배포 단계 | | LF-022 | P2 | 영구 운영 로그/bridge 오류 | 완료 | bounded/redacted log와 toast, malformed payload가 송출 상태를 바꾸지 않음 | authoritative Network Monitoring과 함께 판독 | | LF-023 | P1 | NXT 저장 playlist restore | 외부 데이터 정합성 | stale code를 제목/current identity로 재검증하는 닫힌 경로는 완료. 현재 `v_all_stock` 결과가 비어 preview를 fail closed | DBA/data 정합성 없이는 direct-table 추정 금지 | | LF-024 | P0 | Designer 이벤트 전수 감사 | 완료 | 원본 Designer 구독 **186개**, 화면별 고유 핸들러 **171개** 전수 분류. 유일하게 남았던 활성 `timerAliveChecker`의 10초 DB 끊김·복구 감시와 전이 로그를 LegacyParityApp 수명주기에 연결 | 상세 줄 단위 근거는 `LEGACY_DESIGNER_EVENT_PARITY_AUDIT.md` | | LF-025 | P0 | VS Development Live 시작 구성 | 완료 | `.slnLaunch`와 패키지 프로필이 LegacyParityApp을 시작 대상으로 고정. 실제 Release에서 `--development-live`가 무시돼 DryRun, TCP/Network 변경 0임을 확인 | Live는 exact argument + Debug + strict local authorization을 계속 요구 | ## 이벤트·drag 감사 상세 [`LEGACY_DESIGNER_EVENT_PARITY_AUDIT.md`](LEGACY_DESIGNER_EVENT_PARITY_AUDIT.md)는 원본 커밋의 `*.Designer.cs`를 읽기 전용으로 조사해 186개 구독과 171개 고유 핸들러를 줄 단위로 대조한다. 선언만 있고 구독하지 않는 메서드는 제외하며, `DEAD`/`VISUAL`은 새 활성 업무 intent를 만들지 않는 것이 원본과 동등하다. 종료의 자동 `StopAll`만 기존 안전 정책 때문에 의도적으로 이관하지 않는 `SAFETY` 항목이다. 현재 `DRAG` 구현은 다음 세 C# 권위 경로를 포함한다. - playlist 행 drag는 FarPoint `AllowRowMove`의 source 행 하나를 임의 before/after 위치로 옮긴다. Ctrl/Shift 집합은 삭제 선택으로만 유지하며, 체크박스에서 시작한 drag와 PREPARED/PROGRAM/pending/unknown 상태의 변경은 차단한다. - 시장 탭은 drop 때가 아니라 dragover 대상에 들어갈 때 교환한다. source/target identity와 예상 두 인덱스가 C# 현재 순서와 일치할 때만 적용해 중복 메시지가 순서를 되돌리지 않는다. - 원본 UC6 `FpSpread2.AllowDragDrop`은 ThemeA/EList 편집행의 opaque `rowId` drag로 이관했다. Web은 play index나 DB identity를 결정하지 않는다. ThemeA의 원본 `중복확인`도 이름만 담은 strict intent로 연결했다. C#이 현재 KRX/NXT를 결정하고 선택 provider의 `SB_LIST`에 exact title parameterized read를 한 번 수행한다. 결과 불명은 `Indeterminate`이며 write나 추정 fallback이 없다. 원본처럼 edit 자기 행을 제외하지 않아 변경하지 않은 이름은 중복으로 판정된다. 명백한 결함 또는 송출 안전을 해치는 동작은 동등성 예외로 유지한다. 마지막 행에 NEXT로 도착한 뒤 stale `m_ShowIndex` 때문에 같은 scene을 다시 `Play(10)`하는 동작, 실패한 Page NEXT를 성공 전에 화면 숫자에 반영하는 동작, `s_buf[100]` shadow 값 때문에 첫 Space가 실제 체크값과 어긋나는 동작은 재현하지 않는다. 마지막 NEXT는 no-wrap/no-command, Page 표시는 성공 뒤 반영, Space는 현재 authoritative enabled 값을 반전한다. ## Development Live strict local authorization [`DEVELOPMENT_LIVE_VISUAL_STUDIO.md`](DEVELOPMENT_LIVE_VISUAL_STUDIO.md)의 시작 구성은 정확한 `--development-live` 인자와 Debug 빌드에서만 Git 제외 로컬 승인 파일을 읽는다. 승인 파일은 `%LOCALAPPDATA%` 아래에서 reparse가 아닌 경로, 최대 4096바이트, 정확한 다섯 속성, canonical JSON, exact authorization 문자열과 독립 승인된 native/Interop SHA-256을 모두 만족해야 한다. Live authorization은 환경 설정의 마지막 단계이며 일부 적용 실패 시 기존 값을 복구한다. Release, 인자 불일치, 파일 없음/오류/알 수 없는 속성은 Live를 구성하지 않는다. 기존 `trustedLiveOutputEnabled`, alias allowlist, asset 검사와 송출 안전 게이트는 그대로 중첩된다. ## DB 검증 상세 ### Read-only scene smoke 실제 Oracle/MariaDB에서 필수 scene selector **33/33**과 전체 query 58건이 성공했다. 이 검증은 실제 DB → 명시 DTO → scene mutation 경로를 증명한다. `.t2s`, 영상·배경 자산, K3D 명령 또는 PGM 화면 검증을 대신하지 않는다. ### 개발 DB write smoke production service/executor와 충돌 격리된 임시 식별자를 사용했다. | 시나리오 | 개수 | 검증 | |---|---:|---| | GraphE `INPUT_PIE`, `INPUT_GROW`, `INPUT_SELL`, `INPUT_PROFIT` | 4 | create, fresh readback, delete, absence | | PList/AList named playlist | 2 | definition/items save, fresh readback, delete, absence | | ThemeA KRX | 1 | create, preview/readback, delete, absence | | ThemeA NXT | 1 | create, preview/readback, delete, absence | | EList expert | 1 | create, preview/readback, delete, absence | | 합계 | **9** | **PASS**, 잔여 0 | write는 자동 재시도하지 않는다. `OutcomeUnknown`이면 cleanup mutation이나 다음 시나리오를 보내지 않는 구현·테스트 경계를 유지한다. 이 결과는 개발 DB 검증이며 운영 DB에 임의 쓰기를 허용하거나 수행했다는 뜻이 아니다. ## 기존 PLAY_LIST read-only 재분류 실제 Oracle 활성 정의 23개와 연결된 2,213행은 원문의 7필드, 한국어, enabled, ITEM_INDEX와 원본의 page 공백 제거 규칙을 보존했다. | route | 건수 | 결과 | |---|---:|---| | 기존 닫힌 매퍼 | 1,250 | selection 1,250 | | 업종 | 24 | selection 24 | | 비교 | 99 | selection 74, 시장 identity 유실 25 차단 | | 해외지수 candle | 61 | selection 61 | | NXT theme | 48 | current preview empty 48 차단 | | KRX theme | 587 | current-code 94, 나머지 identity/preview/문법/지원 경계로 차단 | | 해외종목 | 78 | selection 78 | | GraphE | 36 | fresh materialization 22, 값/identity 14 차단 | | unique closed mapper 없음 | 30 | nearest-scene 추정 없이 차단 | | 합계 | **2,213** | 통합 selection 1,603 / 명시 차단 610 | `selectionMapped`는 scene asset, PREPARE나 PGM 성공 수치가 아니다. 상세는 [`NAMED_PLAYLIST_READ_AUDIT.md`](NAMED_PLAYLIST_READ_AUDIT.md)를 따른다. ## 외부자산 목록 45개 active alias의 `.t2s`는 존재한다. 별도 종속 asset 14개만 제공되지 않았다. - `s5006`: `Video\큐브배경.vrv` - `s6001`: - `Video\20201008_미국.vrv` - `Video\20201008_독일.vrv` - `Video\20201008_영국.vrv` - `Video\20201008_프랑스.vrv` - `Video\20201008_일본.vrv` - `Video\20201008_중국.vrv` - `Video\20201008_홍콩.vrv` - `Video\20201008_대만.vrv` - `Video\20201008_싱가포르.vrv` - `Video\20201008_태국.vrv` - `Video\20201008_필리핀.vrv` - `Video\20201008_말레이시아.vrv` - `Video\20201008_인도네시아.vrv` - 기본 배경: sibling `배경\기본.vrv` 이 파일들의 부재는 code/build 실패가 아니라 **외부자산 미제공**이다. 검사기는 존재, 0바이트, root escape, reparse와 manifest 중복을 검사하고 누락 경로와 영향 builder만 redacted 형태로 보고한다. ## 원본 I/O에서 의도적으로 제외한 항목 - 활성 Print/Excel/FarPoint export/import 호출은 원본에서 발견되지 않았다. - CSV playlist save/load, thumbnail watcher와 `SaveImageFile`은 주석 또는 미호출 경로다. - `s8086`은 builder는 있으나 원본 MainForm active alias가 없는 diagnostic route다. - 위 dead/hidden 경로를 새 활성 기능으로 만들지 않는다. ## 최종 증적 기록 현재 구현 증적과 최종 검증 범위는 [`MIGRATION_STATUS.md`](MIGRATION_STATUS.md)에 기록한다. 최신 .NET solution 2,817/2,817, LegacyWeb 117/117, JavaScript 502/502이며 실패·skip은 0이다. Release 빌드는 warning 0, error 0이다. 개발 MSIX 전체 UI/DB와 실제 PGM 32/34 route를 확인했다. 고객 서명 MSIX는 현재 범위에서 보류하고, 외부자산 두 route는 제공 전까지 fail closed한다. 2026-07-15의 상세 package 증적은 [`LEGACY_PARITY_VALIDATION_20260715.md`](LEGACY_PARITY_VALIDATION_20260715.md)에 역사 기록으로 보존한다. 원본 저장소는 최종 검증과 배포 이후에도 계속 읽기 전용으로 유지한다.