fenok-IB · 키움 창 미종료 · 재수집 안내

IB 키움 미종료 진단 v2

1차 수집은 엉뚱한 파일을 봤습니다. 이번에는 실행 로그를 봅니다. 그게 종료 결과가 남는 유일한 곳입니다.

버전 v2 작성 2026-09-02 대상 fenok-ib-portable-2026.08.30.1 성격 읽기 전용

1차 수집이 무효인 이유 — LLM이 먼저 읽어야 할 정정

  1. 잘못된 파일을 봤습니다. artifacts\runner\orchestrator_*_stdout.txt 는 원래 항상 0바이트입니다. 프로그램이 표준출력에 아무것도 찍지 않고 별도 로그 파일에만 기록하기 때문입니다. 비어 있는 것이 정상이며, 구버전 근거가 아닙니다.
  2. 버전은 이미 최신입니다. 설치·활성 버전 모두 2026.08.30.1 하나뿐이고, 그게 종료 수정이 들어간 바로 그 빌드입니다. "버전 스큐" 결론은 성립하지 않습니다.
  3. 증상이 없는 상태에서 수집했습니다. 키움 프로세스도 창도 없던 시점의 스냅샷은 아무것도 말해주지 않습니다.
  4. 구조상 확정된 사실 하나. 이 도구는 키움 창을 직접 닫지 않습니다. 프로세스를 종료시켜서 창이 따라 사라지게 할 뿐입니다. 그러므로 창이 남아 있다면 그 프로세스는 살아 있습니다. 창이 떠 있는 순간의 프로세스 목록 하나가 사실상 결론입니다.
이번엔 두 갈래로 나눠서

트랙 1은 지금 바로 할 수 있습니다. 키움 창이 없어도 됩니다. 과거 실행 로그만 읽으면 되고, 사실 여기서 답이 나올 가능성이 가장 큽니다.

트랙 2는 창이 남아 있는 그 순간에만 의미가 있습니다. 지금 창이 없으면 트랙 1만 하고, 다음에 증상이 나면 그때 트랙 2를 하면 됩니다.

TRACK 01

과거 실행 로그

설치 폴더 안 logs\ 의 실행 로그를 읽습니다. 종료 성공 여부, 죽인 프로세스 수, 남은 프로세스 수, 오류 사유가 전부 여기 남습니다.

지금 즉시 · 창 불필요

TRACK 02

남아 있는 창의 정체

도구는 창을 직접 닫지 않고 프로세스 종료로만 사라지게 합니다. 창이 남았다면 프로세스가 살아 있다는 뜻이고, 그 프로세스의 실제 이름이 곧 답입니다.

증상이 난 그 상태에서만 · 아무 창도 닫지 말 것

진단 프롬프트 v2 · 전체를 그대로 붙여넣기
[역할]
너는 읽기 전용 진단 요원이다. 아무것도 수정, 삭제, 종료, 재실행, 업데이트하지 마라. 증거 수집과 보고만 한다.

[먼저 읽어라 — 1차 수집이 무효였던 이유]
(1) 잘못된 파일을 봤다. artifacts\runner\orchestrator_*_stdout.txt 는 원래 항상 0바이트다.
    이 프로그램은 표준출력에 아무것도 찍지 않고 별도 로그 파일에만 기록한다.
    그 파일이 비어 있는 것은 정상이며 "구버전"의 근거가 아니다.
(2) 버전은 이미 최신이다. 설치된 버전은 2026.08.30.1 하나뿐이고 그게 종료 수정이 들어간 빌드다.
    "버전 스큐"라는 결론은 성립하지 않는다. 다시 그 결론을 내지 마라.
(3) 증상이 없는 조용한 상태에서 수집했다. 프로세스도 창도 없던 시점의 스냅샷은 증거가 아니다.
이번에 볼 곳은 <설치루트>\logs\ 안의 실행 로그다. 종료 결과는 오직 거기에만 남는다.

[구조상 확정된 사실 — 추측하지 말고 이걸 전제로 삼아라]
이 도구에는 키움 창을 직접 닫는 코드가 없다. 종료는 오직 프로세스 종료(nfrunlite.exe / nfstarter.exe)로만 이뤄지고,
창은 그 프로세스가 죽을 때 따라 사라진다. 화면 패널을 닫는 코드는 따로 있지만 영웅문 메인 창은 의도적으로 건드리지 않는다.
따라서: 창이 남아 있다 = 그 프로세스가 아직 살아 있다. 예외는 없다.
이 사실 때문에 "창이 떠 있는 순간의 프로세스 목록"(트랙 2 W2)이 사실상 결론이다.

[설치 루트 찾기 — 경로에 한글과 공백이 있으니 직접 타이핑하지 말고 변수를 써라]
$root = Get-ChildItem -Path $env:USERPROFILE -Directory -Recurse -Depth 4 -Filter "fenok-ib-portable-*" -ErrorAction SilentlyContinue | Sort-Object LastWriteTime -Descending | Select-Object -First 1 -ExpandProperty FullName
$root
비어 나오면 사용자에게 설치 폴더 경로를 물어라.
참고로 알려진 형태는 다음과 같다: %USERPROFILE%\OneDrive\Documents\(카카오톡 받은 파일)\fenok-ib-portable-2026.08.30.1

=====================================================================
트랙 1 — 지금 바로 실행. 키움 창이 없어도 된다. 이게 핵심이다.
=====================================================================

L1. 로그 폴더 존재와 목록
$logdir = Join-Path $root "logs"
Test-Path $logdir
Get-ChildItem $logdir -Filter "log_*.log" -ErrorAction SilentlyContinue | Sort-Object LastWriteTime -Descending | Select-Object Name,Length,LastWriteTime | Format-Table -AutoSize

L2. L1이 비었거나 폴더가 없으면 — 이 경우가 매우 중요하다
Get-ChildItem $root -Filter "log_*.log" -Recurse -Depth 3 -ErrorAction SilentlyContinue | Select-Object FullName,Length,LastWriteTime | Format-Table -AutoSize
Get-ChildItem $env:LOCALAPPDATA,$env:APPDATA,$env:TEMP -Filter "log_*.log" -Recurse -Depth 3 -ErrorAction SilentlyContinue | Select-Object FullName,Length,LastWriteTime | Format-Table -AutoSize
전부 없음이면 "로그 파일이 생성되지 않았음"이라고 명확히 적어라. 그 사실 자체가 결정적 증거다.

L3. 종료 관련 줄 전문 (최근 10개 파일)
실전 실행 로그는 이름에 _dry 가 없다. 이름에 _dry 가 있으면 모의 실행이니 구분해서 적어라.
$files = Get-ChildItem $logdir -Filter "log_*.log" -ErrorAction SilentlyContinue | Sort-Object LastWriteTime -Descending | Select-Object -First 10
$files | ForEach-Object { "=== " + $_.Name + " ===" ; Select-String -Path $_.FullName -Pattern "SHUTDOWN|hts_process_kill|remaining_count|killed_count|nfrunlite|nfstarter|AccessDenied|psutil" -Encoding UTF8 | ForEach-Object { $_.Line } }

L4. 최신 로그 마지막 60줄
$newest = $files | Select-Object -First 1
$newest.FullName
Get-Content $newest.FullName -Tail 60 -Encoding UTF8

L5. 증상이 난 시각의 줄을 로그 내용으로 직접 찾아라 (파일 수정시각 말고 로그 안의 타임스탬프 기준)
로그 줄의 타임스탬프 형식은 2026-08-31 23:35:12,345 이다.
Select-String -Path (Join-Path $logdir "log_*.log") -Pattern "2026-08-31 2[23]:" -Encoding UTF8 | ForEach-Object { $_.Path + " :: " + $_.Line }
증상 시각이 다른 날이면 위 패턴의 날짜를 바꿔서 다시 실행해라. Q3에서 받은 날짜를 전부 이렇게 훑어라.

L6. 설치 위치와 OneDrive 상태
$root
$root -like "*OneDrive*"
Get-ChildItem $root -Force | Select-Object Name,Attributes,Length,LastWriteTime | Format-Table -AutoSize

L7. 참고 — 아티팩트 폴더 (0바이트는 정상이다. 결론 근거로 쓰지 마라)
Get-ChildItem (Join-Path $root "artifacts\runner") -ErrorAction SilentlyContinue | Sort-Object LastWriteTime -Descending | Select-Object -First 6 Name,Length,LastWriteTime | Format-Table -AutoSize

=====================================================================
트랙 2 — 키움/영웅문 창이 지금 화면에 떠 있을 때만
=====================================================================
창이 안 떠 있으면 이 트랙 전체를 건너뛰고, 사용자에게 이렇게 안내해라:
"평소대로 한 번 더 돌려주세요. 키움 창이 안 닫히고 남아 있는 그 상태에서 저를 다시 불러주세요. 그때까지 아무 창도 닫지 마세요."
그리고 트랙 2는 "창 미출현으로 미수집"이라고 보고에 명시해라. 조용한 상태 스냅샷을 채워 넣지 마라.

W1. 창을 가진 프로세스 전수
Get-Process | Where-Object { $_.MainWindowTitle } | Select-Object Id,ProcessName,MainWindowTitle,Path | Format-List

W2. 키움 프로세스 — 이 항목이 가장 중요하다
Get-Process -Name nfrunlite,nfstarter -ErrorAction SilentlyContinue | Select-Object Id,ProcessName,Path,StartTime | Format-List
tasklist | findstr /i "nf"
여기서 아무것도 안 나오는데 화면에는 키움 창이 떠 있다면, 그 창의 프로세스는 다른 이름이라는 뜻이다.
그 경우 W1 목록에서 그 창을 찾아 실제 ProcessName 을 반드시 따로 크게 적어라. 그게 답이다.

W3. 남아 있는 창의 정체 (W1에서 영웅문/키움으로 보이는 창을 찾았을 때)
그 창의 ProcessName, Path, Id를 따로 적고 아래도 실행해라. <PID> 자리에 실제 숫자를 넣어라.
Get-CimInstance Win32_Process -Filter "ProcessId = <PID>" | Select-Object ProcessId,Name,ExecutablePath,ParentProcessId,CommandLine | Format-List

W4. 사용자에게 그 창의 화면 캡처를 요청해라. 창 제목 표시줄이 보이게 찍어달라고 해라.

=====================================================================
사용자에게 직접 물어볼 것 — 답을 받아 보고에 넣어라
=====================================================================
Q1. 도구를 실행할 때 파란 관리자 확인창(UAC)이 떴습니까? (예 / 아니오 / 기억 안 남)
Q2. 이 프로그램 폴더를 OneDrive 밖으로 옮겨도 됩니까? 예를 들어 C:\fenok-ib 로. (예 / 아니오)
Q3. 증상이 난 날짜와 대략 시각을 알려주세요. 여러 번이면 전부.

=====================================================================
판별표 — 수집이 끝나면 이 표로 결론 한 줄
=====================================================================
- 창이 떠 있는데 W2에서 nfrunlite/nfstarter 가 살아 있음
    -> 종료가 실패한 것. 같은 실행의 SHUTDOWN done 줄에서 success 와 remaining_count 를 확인해 사유를 확정해라.
- 창이 떠 있는데 W2에는 아무것도 없고 W1에는 키움 창이 보임
    -> 종료 대상 이름이 실제와 다름. W1에서 찾은 실제 ProcessName 이 답.
- logs 폴더가 없거나 log_*.log 가 하나도 없음
    -> 로그가 기록되지 않는 환경 문제. OneDrive 동기화 폴더 안이라는 점을 확인 대상으로 함께 보고해라.
- SHUTDOWN done success=True, killed_count=0, remaining_count=0 인데 창은 떠 있음
    -> 종료 대상 프로세스명이 실제 창의 프로세스와 다름. W1/W3에서 찾은 실제 이름이 답.
- SHUTDOWN done success=False 이고 errors 에 AccessDenied
    -> 권한 문제. Q1 답변과 함께 보고.
- SHUTDOWN done success=False 이고 errors 에 psutil
    -> 패키징 누락.
- SHUTDOWN done 이 있고 killed_count 가 1 이상이며 창도 사라졌음
    -> 그 실행은 정상. 증상이 난 실행의 로그를 찾아야 한다. L5를 다시 확인해라.
확신도(높음/중간/낮음)를 함께 적어라. 근거가 없으면 "근거 없음"이라고 쓰고 추측하지 마라.

=====================================================================
보고 형식
=====================================================================
1) 트랙 1 결과를 L1~L7 항목명과 함께 명령 출력 전문 그대로
2) 트랙 2는 실행했으면 W1~W4, 안 했으면 "창 미출현으로 미수집"
3) Q1~Q3 답변
4) 판별표 결론 한 줄 + 확신도
5) 판단이 안 서면 결론을 지어내지 말고 "판정 불가"와 부족한 증거 항목을 써라
완성된 보고 전문을 사용자에게 보여주고 "이대로 복사해서 보내주면 된다"고 안내해라.

=====================================================================
절대 금지
=====================================================================
- taskkill, 프로세스 종료, 창 닫기, 도구 재실행, "IB 업데이트.bat" 실행, 설정 파일 수정
- settings 폴더의 계좌번호, 비밀번호, 인증서 값을 보고에 포함하는 것 (파일 이름 언급까지만 허용)
- 로그가 없을 때 "정상"이라고 쓰는 것. 없으면 없다고 써라.
- 0바이트 stdout 파일을 근거로 버전 문제라고 쓰는 것. 그건 정상이다.

수집 항목은 파일 몇 개 읽기와 프로세스 목록 조회뿐입니다. 계좌번호와 비밀번호 값은 보고에 들어가지 않도록 프롬프트가 막고 있습니다.

트랙 1만 해도 됩니다. 창이 남아 있는 상황을 억지로 만들 필요는 없고, 다음에 증상이 나면 그때 트랙 2를 하면 됩니다.

IB 키움 미종료 진단 v2 · 읽기 전용 증거 수집 안내 · 2026-09-02