# 1.0.4 Release x64 MSIX 감사

기준일: 2026-07-12

소스 커밋: `af80c36cdee6f0e2cbd578a4c94359df10e9e222`

## 빌드와 자동 검증

- Visual Studio 2026 MSBuild `18.7.8.30822` Debug/Release x64 solution build 성공
- Core 1,377, Infrastructure 173, Playout 387 테스트를 Debug/Release에서 각각 통과
- Web 구문 27개, 테스트 413/413, scene catalog 35, reachable preset 34 통과
- 실제 Oracle/MariaDB SELECT-only smoke `REAL_DB_SMOKE: PASS`
- 활성 PList 23개 정의·2,213행 무손상, 기본 `selectionMapped=1,581`/차단 632
- 별도 GraphE fresh proof 22/36을 합친 통합 결과 `selectionMapped=1,603`/차단 610
- 해외종목 78/78, KRX theme 94/587 복원; NXT theme 48행은 현재 `v_all_stock` 정합성 때문에 fail-closed

## 패키지

| 항목 | 결과 |
|---|---|
| 버전·아키텍처 | `1.0.4.0`, x64 |
| package family | `Wickedness.MBNStockWebView_qbv3jkvsn3aj0` |
| 설치본 | `Wickedness.MBNStockWebView_1.0.4.0_x64__qbv3jkvsn3aj0` |
| SHA-256 | `E8DB3C0E94963130548FAEF1880A9F9B99829064257F7196F41B7B8F0EE50B6C` |
| 크기 | 48,468,090 bytes |
| 서명 | `CN=Comtrophy`, SignTool/Authenticode `Valid` |
| 내용 | 290개 항목, source Web 33개 전부 byte-for-byte 일치 |
| 제외 검사 | vendor DLL, license, certificate/private key, Cuts, `.t2s`, `.vrv`, 운영 local config 0건 |

패키지 자체는 `.gitignore`에 따라 Git에 넣지 않는다. 서명은 이 장비의 현재 사용자
인증서 저장소에서 수행했고 개인 키를 내보내지 않았다. 이 로컬 서명은 timestamp가
없으므로 인증서 만료 이후의 장기 유효성까지 주장하지 않는다.

## 설치·실행 확인

실행 중이던 1.0.3은 `CloseMainWindow` 뒤 기본 취소형 확인창의 `종료` 버튼을
명시적으로 호출해 정상 종료했다. 강제 종료와 app-data 삭제는 없었다. 같은 package
family에 1.0.4를 update 설치해 기존 private data를 유지했다.

설치된 WindowsApps 경로의 실행 파일로 package context를 확인했고 WebView2 하위
프로세스 5개와 함께 창이 열렸다. 두 번째 activation 뒤에도 프로세스·창은 각각
하나였다.

패키지 화면에서 다음을 확인했다.

- 초기 업무 화면은 원본과 같은 `해외`
- 독립 종목 패널에 31개 컷 표시
- `삼성` 실제 DB 검색 63건
- 해외·환율·지수·코스피·코스닥·비교·테마·해외종목·전문가·정지 10개 업무 탭 방문
- 탭 순회 뒤에도 `삼성`, 63건 결과와 31개 컷 유지
- 비교 화면의 기존 8쌍과 one-time import 영속성 유지
- 버전 `MSIX · v1.0.4`, Oracle/MariaDB `Healthy`, `DRY RUN`

외부 playout 설정 파일과 `MBN_STOCK_PLAYOUT_MODE`/Live authorization override는
없었다. 영구 로그는 `Startup → DryRunReady → Oracle Healthy → MariaDb Healthy`만
기록했고 PREPARE/TAKE IN/NEXT/TAKE OUT, PROGRAM, `OutcomeUnknown` 이벤트는 없었다.
따라서 이 패키지 회차에서는 Tornado2/PGM 명령을 보내지 않았다.

## 남은 외부·승인 항목

- 승인 Cuts의 45 active alias는 모두 존재하지만 `s5006` 영상 1개와 `s6001` 국가별
  영상 13개가 없다. 자산 제공 전 해당 장면 PREPARE를 실행하지 않는다.
- PList 차단 610행은 시장 identity 유실, KRX/NXT 현재 데이터, GraphE 무효/중복,
  unique mapper 부재를 추정 없이 보존한 결과다.
- GraphE/PList/AList/ThemeA/EList 운영 DB write는 정확한 테스트 식별자, 사전 snapshot,
  read-back과 rollback이 있는 별도 승인 회차에서만 수행한다.
- 새 실제 PGM 검증은 이 패키지 SHA-256을 포함한 새 계획과 회차별 Gate A/B 승인을
  받아야 한다. timeout/결과 불명확 상태에서는 명령을 반복하지 않는다.

장애 시 앱 설정을 `DryRun`/`Disabled`로 유지하거나 조직 절차로 직전 승인 패키지를
복원한다. package rollback 과정에서 app data를 초기화하지 않고, vendor DLL·COM 등록·
라이선스·Cuts는 변경하지 않는다.

다음 실제 회차는 아래 값이 모두 고정된 별도 계획 파일을 만든 뒤 그 파일의 SHA-256을
Gate A로 승인받아야 한다.

- 고유 회차 ID와 이 패키지 SHA-256
- 대상 Tornado2/PGM 및 허용 scene·page·command 예산
- 각 PREPARE에 사용할 승인 asset과 DB read 전제조건
- 운영 DB write가 있으면 정확한 테스트 program/entity ID, 사전 snapshot, 예상 mutation,
  별도 read-back과 결정적 rollback
- timeout/`OutcomeUnknown` 시 반복 금지와 사람이 확인할 authoritative 증거
- 정상 종료 시 허용된 TAKE OUT/unload/disconnect 범위

실제 TAKE IN 직전에는 같은 회차와 package hash를 다시 적은 Gate B 즉시 승인이
필요하다. 위 값이 비어 있거나 package/source가 바뀌면 기존 승인을 재사용하지 않는다.
