Files
MBN_STOCK_WEBVIEW/docs/LEGACY_FEATURE_AUDIT.md

29 KiB
Raw Blame History

원본 기능 재감사 기준표

감사 기준일: 2026-07-12 원본(읽기 전용): C:\Users\MD\source\repos\MBN_STOCK_N 마이그레이션 대상: C:\Users\MD\source\repos\MBN_STOCK_WEBVIEW

이 문서는 원본 WinForms/FarPoint 프로그램과 현재 WinUI 3/WebView2 프로그램을 다시 대조한 결과다. 원본 저장소와 실제 Cuts는 읽기 전용으로 조사했다. 자동 테스트나 UI 코드가 존재한다는 사실과 실제 운영 환경에서 동등성이 확인됐다는 사실을 구분한다.

상태 정의

상태 의미
미적용 원본 동작의 대응 구현 또는 필수 검증 경로가 아직 없다.
적용 중 현재 작업 트리에 구현 또는 검사 보강이 있으나 최종 패키지·실환경 검증까지 끝나지 않았다.
완료 현재 코드와 해당 자동 검증에 반영됐고 이번 재감사에서 완료로 판정했다.
외부자산 필요 코드만으로 완료할 수 없으며 Git/MSIX 밖의 승인된 자산이나 운영 환경이 필요하다.

완료 수는 증분 포팅과 최종 회귀 결과에 따라 바뀌므로 아래 표를 단일 기준으로 사용한다. 기존 문서에서 사용하는 완료, 통합 완료, 전체 통과 표현도 아래 상태와 검증 범위로 다시 해석해야 한다.

우선순위별 결과

ID 우선순위 기능·누락 후보 상태 근거 파일·메서드 현재 판정 검증 방법
LF-001 P0 s6001 해외지수 영상 자산 외부자산 필요 현재 src/MBN_STOCK_WEBVIEW.Core/Playout/Scenes/ReadOnlyPanelSceneBuilders.cs:491-513, S6001SceneMutationBuilder.Metadata/Index; 검증기 src/MBN_STOCK_WEBVIEW.Playout/Configuration/ValidatedPlayoutOptions.cs:375-406, ResolveAssetPath 해외지수 15개 target이 13개 Video\20201008_<국가>.vrv에 의존한다. 감사 시 승인 Cuts의 Video 폴더는 비어 있어 이 target들은 DryRun PREPARE에서도 COM 호출 전에 차단된다. 유가·금의 PNG/JPG는 존재한다. 승인된 파일을 Cuts root 아래에 제공한 뒤 강화된 cut/asset 검사와 s6001 각 target DryRun PREPARE를 실행한다. 실제 PGM은 별도 승인 회차에서만 확인한다.
LF-002 P0 cut coverage의 장면 종속 asset 검사 완료 scripts/LegacyCutRequirements.json, LegacyCutCoverage.psm1, Test-LegacyCutCoverage.ps1; 테스트 tests/Scripts/Test-LegacyCutCoverage.Tests.ps1, LegacyCutRequirementManifestTests.cs 45개 active alias와 23개 장면 종속 asset을 분리해 존재·0바이트·root escape·reparse·manifest 중복을 검사한다. 완전/누락/0바이트/reparse/escape fixture가 자동 테스트에 연결됐다. 실제 승인 Cuts read-only 실행은 alias missing/unsafe 0, asset unsafe 0, asset missing 14로 정확히 실패했다: s5006 1개와 s6001 13개 영상이다. 실제 누락 14개가 승인 Cuts에 제공되면 같은 명령을 다시 실행해 Status=Passed를 확인한다. 검사기 완료와 외부 자산 준비 완료는 LF-001/LF-003에서 분리한다.
LF-003 P0 s5006 큐브 배경 영상 외부자산 필요 원본 MBN_STOCK_N/Scene/s5006.cs:30-31; 현재 src/MBN_STOCK_WEBVIEW.Core/Playout/Scenes/ReadOnlyPanelSceneBuilders.cs:31-48; docs/PLAYOUT_OPERATIONS.md:81-85 Video\큐브배경.vrv가 승인 Cuts에 없다. 기존 운영 문서에는 누락이 기록돼 있으나 파일 제공 전에는 s5006 PREPARE가 완료된 것이 아니다. asset 검사 통과 후 s5006 DryRun PREPARE, 승인된 Test/PGM 회차 순으로 검증한다.
LF-004 P0 실제 운영 DB write 미적용 docs/OPERATOR_UI_PARITY.md:48-62,167-170,214-218,229-246,278; GraphE MainWindow.ManualFinancial.cs; PList MainWindow.NamedPlaylists.cs; ThemeA/EList MainWindow.OperatorCatalogs.cs mutation 계약, fake executor, rollback·OutcomeUnknown 테스트는 존재하지만 GraphE, PList/AList, ThemeA, EList의 운영 Oracle write는 실행하지 않았다. FSell/VI도 격리 저장소 write만 검증했다. 따라서 운영 데이터 쓰기 동등성은 미검증이다. 승인된 테스트용 식별자와 사전 snapshot을 정하고 create/update/delete를 각 1회 실행한다. 매 단계 후 별도 read-only 조회로 결과를 대조하고, timeout·OutcomeUnknown이면 반복하지 않는다. 운영 데이터에는 임의로 실행하지 않는다.
LF-005 P0 전체 장면·운영 UI의 실제 Tornado2/PGM 검증 미적용 docs/MIGRATION.md:69-74; docs/OPERATOR_UI_PARITY.md:48-62; docs/PLAYOUT.md:348-366 승인된 실제 회차의 범위는 5001/5074와 그 Page/playlist NEXT, refresh, TAKE OUT이다. 자동 builder/DB smoke 결과를 나머지 장면의 PGM 동등성으로 확대할 수 없다. 장면별 허용 자산과 DB 전제조건을 먼저 통과시킨다. 이후 회차별 계획 SHA-256과 명시적 승인을 받아 Network Monitoring 명령, callback, PGM 화면을 함께 기록한다.
LF-006 P1 시스템 종료 확인 완료 MainWindow.CloseConfirmation.cs, EnsureCloseConfirmationAttached, OnAppWindowClosing, BuildCloseConfirmationMessage, DetachCloseConfirmation; 연결부 MainWindow.xaml.cs:54-63,101-112,OnClosed; 테스트 tests/Web/operator-ui-app-integration.test.cjs:384-408 모든 시스템 close를 먼저 취소하고 기본 버튼이 취소인 확인창을 연다. PREPARED/PROGRAM, command pending, OutcomeUnknown에 맞는 경고를 표시하며 종료 과정에서 TAKE OUT이나 반대 명령을 자동 실행하지 않는다. Web 통합 테스트를 실행하고 패키지 앱에서 idle, prepared/on-air 경고, 취소, 명시적 종료를 수동 확인한다.
LF-007 P1 패키지 앱 단일 인스턴스 완료 App.xaml.cs:9-57, OnLaunched, OnMainInstanceActivated; 테스트 tests/Web/operator-ui-app-integration.test.cjs:72-88 AppInstance.FindOrRegisterForKey가 MainWindow와 DB/WebView/playout runtime 생성 전에 실행된다. 두 번째 인스턴스는 activation을 primary로 전달한 뒤 종료하며 기존 프로세스를 이름으로 찾아 강제 종료하지 않는다. 통합 테스트 후 설치된 MSIX를 두 번 실행해 프로세스 하나, 창 하나, 기존 창 활성화를 확인한다.
LF-008 P1 운영자 모달의 전역 단축키 격리 완료 Web/app.js:6808-6845, hasOpenOperatorModal, isolateOperatorModalShortcut; 테스트 tests/Web/operator-ui-app-integration.test.cjs:410-429 GraphE, FSell/VI, ThemeA/EList 등 modal이 열려 있으면 F2/F3/F8/Escape, Home/End/Delete/Space, Ctrl+K가 workspace 송출·playlist handler로 전달되지 않는다. F8/Escape에는 modal을 먼저 닫으라는 안내를 표시한다. Web 통합 테스트 후 각 modal 입력 필드에서 해당 키를 눌러 playout command와 playlist mutation이 발생하지 않는지 확인한다.
LF-009 P1 PList의 기존 한국어 DC_TITLE/LIST_TEXT 복원 적용 중 원본 MBN_STOCK_N/Form/PList.cs:81-124, data_load; 현재 src/MBN_STOCK_WEBVIEW.Core/Data/NamedPlaylistPersistence.cs:442-540,742-787, LoadAsync/ParseItem; Web/named-playlist-workflow.js:334-412, restoreRawRows; Web/app.js:4317-4619,5017-5052 운영 Oracle read-only 집계에서 활성 정의 23개와 연결된 2,213행은 모두 정확히 7필드였고 canonical ASCII group은 0행, malformed/null은 0행이었다. 즉 전 행이 기존 한국어 형식이므로 legacy→canonical 복원이 필수다. 삭제된 정의에 연결된 orphan 88개 프로그램/9,369행은 현재 UI load 대상이 아니다. 닫힌 매퍼와 fresh identity 재검증을 보강 중이며 전체 2,213행의 unique/blocked 판정이 끝나기 전에는 완료로 보지 않는다. 실제 read-only PList 행을 원본과 새 앱에서 같은 프로그램 코드로 읽어 DC_TITLE과 caret 7개 필드를 글자 단위로 비교한다. <EFBFBD> 또는 mojibake가 없어야 하며 trusted restore와 fresh page plan 전에는 PREPARE가 계속 차단돼야 한다. raw 값은 로그·문서에 출력하지 않고 분류 건수만 기록한다.
LF-010 P1 원본 F2/F3 배경 디렉터리 동등성 코드 적용 / 외부자산·패키지 검증 대기 원본 MBN_STOCK_N/MainForm.cs:4008-4054, btnback_Click, ckback_CheckedChanged; 현재 MainWindow.Background.cs, PlayoutSceneCompositionFactory, TrustedPlayoutAssetPath, ValidatedPlayoutOptions; 문서 docs/TRUSTED_BACKGROUND_ROOT.md Cuts gate를 유지한 채 별도 LegacyBackgroundDirectory를 추가했고, 생략 시 원본처럼 SceneDirectory\..\배경을 계산한다. F2는 유효할 때만 picker 전 기본.vrv를 복원하고 F3-on은 항상 기본 파일을 다시 검증한다. root escape·조상/파일 reparse·hardlink·누락·opened-handle final path를 fail closed로 검사하며 Cuts fallback은 없다. 이 장비의 원본 bin\Debug\배경기본.vrv는 실제로 없어 현재 기본 배경은 잠긴다. Core Debug/Release 1,259/1,259, Playout Debug/Release 387/387과 앱 Debug/Release x64 build를 통과했다. signed 패키지에서 별도 root 상태 메시지와 F2/F3를 확인하고, 자산 제공 뒤 다음 PREPARE mutation/PGM은 승인 회차에서 검증한다.
LF-011 P1 종목비교.dat 기존 저장쌍 이전 적용 중 원본 MBN_STOCK_N/Control/UC3.cs:34-55,181-185, UC3_Load, Data_Load, File_Save; 현재 src/MBN_STOCK_WEBVIEW.Core/Data/LegacyComparisonPairImport.cs, MainWindow.LegacyComparisonImport.cs, Web/comparison-import-workflow.js, Web/app.js; 테스트 LegacyComparisonPairImportServiceTests.cs, comparison-import-workflow.test.cjs, comparison-import-app-integration.test.cjs 원본 파일은 CP949 358바이트, 비어 있지 않은 8행, 각 행 정확히 9필드이며 0~3열만 값이 있다는 감사 fixture를 SHA-256 1EE76BC4…BFC0D2F2로 고정했다. Web이 경로를 전달하지 않는 고정 read-only source, reparse/크기/2회 quiescent snapshot 검사, strict CP949/9필드 parser, 현재 Oracle/MariaDB 종목·해외 identity exact read, 고정 시장명과 해외 동명이름 충돌 차단, 전체 중복·500쌍 경계, 명시적 버튼과 one-time marker/rollback을 구현했다. 원본은 수정하지 않고 성공 뒤 WebView private localStorage schema만 사용한다. 이 장비의 실제 설정으로 동일 서비스 read-only smoke를 실행해 8행 전부와 SHA-256이 일치하고 모든 identity가 해소됨을 확인했다. 다만 패키지 UI 버튼→localStorage→재시작 marker까지의 1회 실행은 아직 하지 않았으므로 완료로 올리지 않는다. 실제 패키지에서 명시적 버튼 1회로 8행을 모두 fresh DB 재검증하고 local schema/hash/순서를 확인한다. 같은 profile의 두 번째 실행은 marker로 차단되고, 원본 변경·손상·동명이름·기존쌍 중복은 부분 저장 없이 전체 fail closed여야 한다.
LF-012 P1 FSell/VI 원본 Data의 안전한 이전과 설정 문서 적용 중 원본 MBN_STOCK_N/MainForm.cs:338-339, FSell.cs:31-88, VIList.cs:31-34,137-139; 현재 src/MBN_STOCK_WEBVIEW.Core/Data/LegacyManualOperatorDataImport.cs, src/MBN_STOCK_WEBVIEW.Infrastructure/Playout/LegacyManualOperatorDataImporter.cs, MainWindow.ManualLists.cs, Web/manual-lists-workflow.js, Web/manual-lists-ui.js UserProfile 아래 고정 원본 경로만 read-only로 두 번 읽고 strict CP949, FSell 파일별 5행+종료 레코드, VI 9열·최대 100건·4,000바이트를 검사한다. 명시적 확인 뒤 private store가 완전히 비어 있을 때만 4개 staged 파일을 no-overwrite로 옮기고 production parser readback 후 v1 marker를 마지막에 기록한다. rollback을 확정하지 못하면 OutcomeUnknown quarantine이며 자동 재시도하지 않는다. 실제 source smoke는 FSell 15행·VI 9건·aggregate SHA-256 fd39a363…a2114였고, 이 장비의 private 4개 파일은 이미 원본과 각각 byte-identical이어서 DestinationNotEmpty로 source read 전 중단했으며 전후 SHA가 같았다. 새 빈 package profile fixture에서 버튼→4파일→marker→재시작 차단을 확인한다. 현재 운영 profile에서는 기존 동일 파일을 덮어쓰거나 marker를 임의 생성하지 않는다.
LF-013 P1 generic native bridge-error 표시 적용 중 producer MainWindow.xaml.cs:431-437, MainWindow.Playout.cs:121-126,370-375; 현재 consumer Web/app.js:6446-6454, handleBridgeError, handleNativeMessage; 테스트 tests/Web/operator-ui-app-integration.test.cjs:431-435 재감사 당시 소비자가 없던 오류 표시가 현재 작업 트리에 반영됐다. bounded 메시지와 운영 로그 표시는 확인되지만 최종 회귀·패키지 반영 전이라 완료로 올리지 않는다. malformed status/quarantine payload fixture로 bridge-error 1회, bounded toast/log, playout state 불변을 확인하고 전체 Web 테스트와 패키지 UI를 다시 검증한다.
LF-014 P2 영구 운영 로그 적용 중 원본 MBN_STOCK_N/MainForm.cs:84-128,132-180,542-543,675,776, initAliveChecker, LogWrite, timerAliveChecker_Tick; 현재 src/MBN_STOCK_WEBVIEW.Infrastructure/Diagnostics/NativeOperatorLogWriter.cs, NativeOperatorLogTransitions.cs, MainWindow.NativeOperatorLog.cs %LOCALAPPDATA%\MBN_STOCK_WEBVIEW\Logs\Log_MMdd.log에 Startup/Shutdown, Oracle/MariaDB·Tornado 전이, 실행 gate를 통과한 PREPARE/TAKE IN/NEXT/TAKE OUT의 요청과 terminal 결과만 기록한다. 4MiB/31일, provider별 중복 억제, single-command terminal, reparse/handle 검증을 적용했다. TimedOut과 불명확 결과는 OutcomeUnknown 한 번으로 끝내며 late result를 기록하지 않는다. 공개 record는 폐쇄 enum만 받아 requestId, 장면, 경로, SQL, DB message와 예외 문자열을 구조적으로 받을 수 없다. Debug/Release 자동 검증 후 package context에서 시작→DB/DryRun 상태→종료를 실행하고 파일 재시작 잔존, 중복 억제, 금지 문자열 부재를 확인한다.
LF-015 P2 호출자가 없는 native bridge handler 완료 MainWindow.xaml.cs, OnWebMessageReceived; 테스트 tests/Web/operator-ui-app-integration.test.cjs Web 호출자가 없던 open-externalreload message case를 native allowlist에서 제거했다. 외부 navigation/new-window 처리와 WebView process failure의 내부 reload 복구 메서드는 별도 native event 경로로 유지한다. 정적 계약 테스트에서 두 message case와 Web 발신 literal이 모두 없음을 확인했다.
LF-016 P2 실제 preview 이미지·영상 외부자산 필요 docs/MIGRATION.md:73-74; 원본 MBN_STOCK_N/MainForm.cs:1448-1462,1894-1911,2919-2921 현재 preview는 안전한 DTO/mutation 텍스트 중심이다. 실제 이미지·영상 연결은 후속 자산이다. 다만 원본 thumbnail 호출과 watcher는 주석 또는 미호출이므로 활성 원본 동등성의 P0/P1 blocker로 보지 않는다. 승인된 preview 자산이 생기면 asset root와 노출 정보 검사를 거쳐 패키지 화면에서 확인한다.
LF-017 P1 모든 업무 탭에서 계속 보이는 종목 검색·31컷 적용 중 원본 MBN_STOCK_N/MainForm.Designer.cs:2022-2036,2454-2462; 현재 Web/index.html의 독립 stock-panel, Web/app.jsrenderStockWorkflow; 테스트 operator-ui-app-integration.test.cjs 종목 검색·31컷을 catalog panel 밖의 독립 열로 옮기고 모든 업무 메뉴에서 항상 표시한다. 1920 브라우저에서 11개 메뉴를 이동해 검색어, 표시, 31개 행이 유지되고 문서 가로 overflow가 없음을 확인했다. signed MSIX에서 실제 DB 검색 결과·선택 종목이 모든 탭 전환 뒤 유지되고 컷 추가가 같은 identity를 쓰는지 확인한 뒤 완료로 올린다.
LF-018 P2 원본 트리·컷 목록 일괄 추가 제스처 적용 중 원본 부모 double-click MBN_STOCK_N/Control/UC1.cs:141-180; 소스 컷 Ctrl/Shift 선택 MBN_STOCK_N/MainForm.cs:3427-3525,3534-3549,3635-3643; 현재 Web/legacy-batch-selection-workflow.js, Web/app.js; 테스트 legacy-batch-selection-*.test.cjs 종목 31컷의 plain/Ctrl/Shift/Ctrl+Shift 선택, 단일 double-click, 선택 컷 추가를 포팅했다. 해외·환율·지수 fixed source의 섹션 전체 추가는 모든 자식을 먼저 materialize한 뒤 원본 순서로 한 번에 commit하며, 수동/지원불가가 한 건이라도 있으면 부분 추가 없이 전체 차단한다. 실제 브라우저에서 5개 선택, 해외 43개 순서 추가, 수동 혼합 섹션 0건 추가를 확인했다. signed MSIX 확인 뒤 업종·비교·테마 등 전용 source group의 부모 전체 추가가 원본에서 실제로 필요한 범위를 계속 분리 포팅한다. source drag/drop 자체는 오조작 검증 뒤 결정한다.
LF-019 P1 저장 PList의 테마_NXT stale code 복원 적용 중 원본 Control/UC4.cs, Scene/s5074.cs, s5077.cs, s5088.cs; 현재 LegacyNamedNxtThemeRestoreService, MainWindow.NamedNxtThemeRestore.cs, Web/named-nxt-theme-restore-workflow.js; 상세 docs/NAMED_NXT_THEME_RESTORE.md 원본처럼 제목 exact lookup으로 현재 Maria code를 찾고 현재가 전용 5/6/12행, 정렬 fallback, 0012 PRE/1323 AFTER, fresh PageN을 닫힌 batch로 복원한다. 실제 활성 48행/24제목은 모두 current identity가 유일하고 저장 code 48개가 전부 stale였지만 현재 preview가 전부 비어 있어 48행 모두 PreviewEmpty로 정상 차단됐다. KRX 테마는 후보가 아니다. Maria SB_ITEM/v_all_stock live 연계가 복구된 뒤 같은 read-only audit에서 한 행 이상 live item을 확인하고, fresh page preflight와 Debug/Release/MSIX UI를 검증한다. 실제 PGM은 별도 승인 회차가 필요하다.
LF-020 P2 원본 초기 업무 화면 해외 적용 중 원본 MainForm.Designer.cs, 첫 TabPage 해외; 현재 Web/index.html, Web/app.js 초기 activeMarket 원본은 첫 업무 탭인 해외로 시작하지만 재감사 당시 새 앱은 dashboard로 시작했다. dashboard는 새 진단 화면으로 유지하면서 초기 active identity, 제목과 최초 조회를 해외로 맞추는 중이다. Web 초기화 테스트와 signed MSIX 첫 실행에서 해외만 active이고 최초 DB 요청이 중복되지 않는지 확인한다.
LF-021 P2 업무 탭 드래그 순서 변경 코드 적용 / 패키지 검증 대기 원본 MainForm.Designer.cs:1063-1066 TabControl drag events, MainForm.cs:3183-3312 tab_MouseDown/tab_MouseMove/tab_DragOver/swapTabPages; 현재 Web/market-nav-reorder.js, Web/app.jsmarketNavReorder controller; 테스트 market-nav-reorder*.test.cjs 새 dashboard는 첫 위치에 고정하고 원본 10개 업무 button만 data-market identity로 교환한다. active DOM node와 view/DB/playlist state는 건드리지 않으며 local/session storage에 저장하지 않는다. drag token은 닫힌 형식으로 검증하고, Alt+위/아래는 인접 교환과 첫·마지막 경계를 제공한다. 입력, modal, PREPARE 이후 잠금에서는 실행하지 않는다. 전용 10/10과 전체 Web 353/353, cut fixture, Debug/Release x64 build가 통과했다. signed MSIX에서 pointer drag, 키보드 포커스, active click 유지와 재시작 시 기본 순서 복원을 확인한다.
LF-022 P2 GraphE 검색 Enter 다음 찾기 적용 중 원본 GraphE.Designer.cs:229, GraphE.cs:605, downSearch_Click; 현재 Web/manual-financial-ui.js; 테스트 manual-financial-ui.test.cjs 목록 수락 전 Enter는 기존 DB 조회를 유지하고, 이후 Enter는 현재 선택 다음 행부터 대소문자 무시 Contains로 한 건을 찾아 load한다. 원본처럼 마지막에서 처음으로 순환하지 않으며 pending·잠금·숨김 modal은 무동작이다. 네 GraphE 모드 관련 테스트 39/39 후 signed MSIX에서 한 건·마지막·검색어 변경을 확인한다.
LF-023 P2 전문가 추천 편집기의 Delete 키 적용 중 원본 UC6.Designer.cs:571, UC6.cs:230; 현재 Web/operator-catalog-ui.js; 테스트 operator-catalog-ui.test.cjs expert draft의 포커스/선택 행에서만 Delete를 기존 removeDraftItem으로 처리한다. ThemeA, modal 밖, input/textarea/contenteditable에는 영향이 없고 잠금·DB write 중에는 삭제하지 않고 event만 dialog 내부에서 격리한다. Web 전체 회귀와 signed MSIX EList/전문가 편집 modal에서 확인한다.

활성 PLAY_LIST 2,213행 재분류

운영 Oracle의 활성 프로그램 정의 23개와 연결된 2,213행을 원문을 출력하지 않는 read-only 집계로 다시 분류했다. 삭제된 정의에 매달린 orphan 데이터 88개 프로그램/9,369행은 현재 PList의 정상 load 대상이 아니므로 아래 수치에 포함하지 않았다.

복원 분류 건수 판정
기존 닫힌 매퍼와 fresh 검증으로 복원 1,573 stock/fixed/expert/GraphE 등 기존 계약과 현재 master를 모두 통과하는 행
DB 없이 추가 복원 가능 57 업종 fixed 24, 고정 시장·지수 2열판 33
현재 DB exact lookup 뒤 추가 복원 가능 228 NXT theme 48(복원 경로 적용, 현재 preview empty로 전부 차단), 비교 graph 41, 해외종목 78, 해외지수 candle 61
현재 identity를 안전하게 증명할 수 없음 325 KRX theme 300, 원본이 시장을 저장하지 않은 종목 2열판 25. 이름이나 과거 코드를 추정하지 않고 재선택이 필요함
whitelist 불일치로 자동 복원 금지 30 s5001 fixed-nearest 기존 집계가 재감사 후보 40건과 달라 명시적 CASE 확정 전까지 차단
합계 2,213 raw 행은 closed mapping과 fresh identity가 모두 성공해야만 playable entry가 됨

테마 635행은 별도로 다음과 같이 판정했다. KRX exact 문법 375행 중 현재 제목이 유일한 287행만 즉시 신뢰할 수 있고 88행은 stale이다. 정렬 토큰이 없는 199행과 기타 문법 13행은 원본 s5074/s5077/s5088의 최종 분기와 같이 모두 GAIN_ASC 의미지만, 현재 SB_LIST에서 제목이 사라져 playable하지 않다. NXT 48행은 24개 저장 제목으로 구성되고 raw grammar는 5단 표그래프 / 테마-현재가(입력순) 한 종류다. 48행 모두 제목의 현재 Maria identity는 유일하고 저장 code가 현재 code와 다르지만, 현재 validated preview가 0건이어서 전부 PreviewEmpty로 차단한다. live item이 생긴 경우에만 현재 code를 송출 selection에 사용하며, 원본과 같이 PREPARE 직전 로컬 시각 0012시는 PRE, 1323시는 AFTER로 다시 결정한다.

비교 후보 99행은 고정 지수쌍 33, 시장쌍이 보존된 KRX graph 41, 시장이 사라진 종목 2열판 25로 확정했다. 앞의 74행만 closed target 또는 Oracle의 시장+이름 exact lookup으로 복원한다. 마지막 25행은 오늘의 master에서 이름이 우연히 유일해도 원본 행이 KOSPI/KOSDAQ/NXT/해외 구분을 보존하지 않았으므로 자동 복원하지 않는다. NXT graph는 원본 UC1 자체가 지원하지 않았고 현재 graph loader도 Oracle KRX pair만 허용하므로 계속 차단한다.

해외지수 candle 61행은 UC5 고정 이름 세 개(Dow 22, Nasdaq 21, S&P500 18)와 5/20/60/120일 기간만 사용하며 240일 활성 행은 없다. 이름과 기간은 닫힌 표이지만 원본 LIST_TEXT가 symbol/nation을 저장하지 않으므로 DB-free로 분류하지 않는다. Oracle master에서 F_INPUT_NAME, expected symbol, F_NATC=US, F_FDTC=0의 exact identity를 다시 확인한 뒤에만 s8010/PRICE 선택을 발급한다.

이 수치는 “문자열을 해석할 수 있음”과 “현재 데이터로 송출할 수 있음”을 분리한다. identity 미확정 325행과 whitelist 미확정 30행에는 R... 임시 code나 가장 가까운 장면을 넣지 않는다. 화면에는 실패 행을 유지하고 PREPARE를 차단하며, 운영자가 현재 항목으로 다시 선택해야 한다.

s6001 asset 검사 보강 기준

s6001 해외지수 target은 다음 13개 파일을 요구한다.

  • 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

검사 보강은 다음 조건을 만족해야 한다.

  1. .t2s alias 결과와 asset 결과를 별도 필드로 보고한다.
  2. 상대 경로만 허용하고 Cuts root 탈출을 거부한다.
  3. 파일 존재, 0바이트 여부, reparse point를 검사한다.
  4. 누락된 상대 경로와 영향을 받는 builder를 운영자가 알 수 있게 하되 secret이나 외부 절대 경로를 출력하지 않는다.
  5. asset이 없는 현재 장비에서는 전체 migration 완료가 아니라 외부자산 필요로 끝나야 한다.
  6. 완전 fixture, 단일 누락, 복수 누락, 0바이트, reparse fixture를 자동화한다.

권장 검증 명령 형태:

powershell -NoProfile -ExecutionPolicy Bypass -File .\scripts\Test-LegacyCutCoverage.ps1 `
  -CutRoot "<승인된 읽기 전용 Cuts root>"

검사 보강 전의 Missing=0.t2s alias만 의미하며 asset-ready 증거로 사용하면 안 된다.

원본 I/O 조사에서 제외 판정한 항목

  • 활성 Print/Excel/FarPoint export/import 호출은 발견되지 않았다.
  • MainForm.cs:1767-1772,1796-1805의 CSV playlist save/load는 주석 처리돼 있다.
  • MainForm.GetThumnail과 preview watcher/SaveImageFile 호출도 활성 경로가 아니다.
  • s8086은 scene builder는 존재하지만 원본 MainForm active alias가 없어 의도적으로 unreachable이다. 이를 UI 누락으로 계산하지 않는다.
  • FarPoint의 표·선택·정렬·이동 자체는 Web table/workflow로 변환할 수 있지만, 변환 UI가 존재한다는 사실만으로 DB write나 PGM 동등성이 완료되지는 않는다.

기존 완료 문서 교정 후속

다음 문서는 구현 존재, 자동 계약 테스트, 실데이터 read smoke, 외부 asset readiness, 실제 DB write, 실제 PGM 검증을 서로 다른 열로 분리해야 한다.

문서 교정할 표현 후속 교정 내용
docs/MIGRATION.md:69-74 MainForm/UC1~UC7과 전용 화면을 포괄적으로 완료로 표현 화면·bridge 구현운영 동등성 검증을 분리한다. PList 한국어 복원, s6001 asset, 원본 파일 one-time import, DB write, 장면별 PGM 상태를 이 문서와 맞춘다.
docs/OPERATOR_UI_PARITY.md:48-62 다수 화면을 화면 통합 완료로 표현 해당 표현은 구조적 UI 도달성만 뜻한다고 명시하고 DB-W/PGM 미검증을 상단 요약과 각 행에 유지한다. 완료 판정은 실제 검증 열까지 충족할 때만 사용한다.
docs/OPERATOR_UI_PARITY.md:75,111-113,214-218 PList와 비교쌍 load/save를 완료로 표현 PList 한국어 실DB 복원과 종목비교.dat one-time import를 별도 미완료 항목으로 추가한다.
docs/OPERATOR_UI_PARITY.md:77 F2/F3 배경을 완료로 표현 별도 sibling 배경 root와 기본.vrv 코드/자동 검증은 반영됐다. 실제 자산이 없으므로 package/PGM 완료로 확대하지 않는다.
docs/SCENE_EQUIVALENCE.md:17,98 전체 real-data smoke 및 s6001을 asset 경고 없이 통과로 표현 DB→DTO→mutation smoke와 실제 asset preflight를 분리하고 s6001 국가 영상 13개를 외부자산 필요로 기록한다.
docs/PLAYOUT_OPERATIONS.md:86,94 s5025 환경 변수 안내와 alias-only cut 검사 정상 앱의 private manual store 경로와 one-time import 정책을 정확히 설명한다. cut coverage 결과에 asset 검사 상태를 추가한다.
docs/PLAYOUT.md:97,348-366 Web 배경 변경 불가 설명 및 자동 검증을 35개 완료 근거로 사용 F2/F3 native picker의 실제 경계를 반영한다. 5001/5074 PGM 성공과 나머지 scene 자동 검증을 명확히 분리한다.

이 교정은 기존 구현 성과를 취소하는 것이 아니라, 구현됨실제 방송 동등성 완료를 같은 의미로 사용하지 않기 위한 것이다.

완료 판정에 필요한 최종 증거

  1. s5006/s6001 포함 모든 reachable scene의 asset preflight 결과
  2. PList 한국어 DC_TITLE/LIST_TEXT 실DB read 비교
  3. 기존 종목비교.dat, FSell, VI 데이터의 안전한 one-time migration 결과
  4. 승인된 테스트 데이터로 수행한 GraphE/PList/ThemeA/EList 및 manual file write read-back
  5. Debug/Release x64 회귀와 Release MSIX package-context 실행
  6. 승인된 scene·회차의 Network Monitoring 명령, callback, PGM 화면
  7. timeout·OutcomeUnknown에서 재시도하지 않았다는 운영 기록

이 증거가 갖춰지기 전에는 전체 원본 UI 또는 35개 scene의 동등성 목표를 완료 처리하지 않는다.