2026년 7월 5주차(2026-07-27 ~ 2026-08-03, ISO week 32) 주간 리뷰. 한 주 동안 푼 문제 중심으로 정리한다.
이번 주 GitHub 커밋이 0건인 커널 드라이버 파트는 이번 주 활동이 코드 커밋이 아닌 고객사 현장 이슈 분석·조사였기에 카운트가 0인 것이 정상이며, 아래 별도 섹션에서 정리한다.
원격 진단·제어 기반 배선과 대규모 부하 검증
프로세스 증상 확산 예측 배치 구현·배포 — TIPS ML 지표 충족 + systemd timer 결함 격리 (OR-1680). 한 PC에서 난 증상이 같은 원인 프로그램을 쓰는 다른 PC로 번질지를 매시 예측하는 기능을 구현·배포했다. TIPS 사업계획서의 '머신러닝 예측 시스템'(예측 항목 10개 이상·타 Endpoint 발생 예측·정확도 제공) 지표를 sprocess 단독 10종으로 충족했고, 증상 계열은 8개월 소급 재연 적중률이 5.6%에 그쳐 데이터가 쌓일 때까지 휴면 처리하는 판단을 내렸다. 실행 구조를 cron→aggregator 통합을 거쳐 독립 systemd timer+oneshot로 재분리해, 예측만 개별로 끄고 저널로 관측하며 배치가 죽어도 집계에 무영향인 결함 격리를 확보했다.
정팀장 AI 원격 진단 Phase 1 — LLM이 자료를 읽고 필요한 명령만 노드에 발행 (OR-1716). 노드 위젯에 관리자가 궁금한 것을 물으면 서버가 이미 수집한 자료를 먼저 읽고 확인이 필요한 것만 그 PC에 직접 명령을 보내 원인을 알려주는 AI 원격 진단 탭을 붙였다. 사람이 LLM과 LiveCMD 사이에서 명령을 나르던 일을 없애는 것이 목표이며, 대화형 LiveCMD 세션이 종료 시점·종료 코드가 없다는 조사 결과로 get.CMD/get.POWERSHELL 단발 실행으로 전환했다. 1차 서버 자율 진단 설계가 세션 takeover·브로커 ACL·감사 귀속 문제를 지적받자 브라우저 주도로 재설계해 교차검증에서 '아키텍처 문제 대부분을 제거했다'는 평가와 제안 모드 조건부 GO 판정을 받았다.
자체 원격 화면 제어 배선 + coturn 표준화 — 하드코딩 제거·서버 발급 ICE 크레덴셜 (OR-1703). 에이전트 원격 화면 제어를 단일 세션·인계 확인(busy/takeover 통지) 구조로 새로 배선하고, WebRTC ICE가 의존하는 coturn(STUN/TURN 릴레이)을 Orange 표준 서버 구성에 편입했다. 코드에 하드코딩돼 있던 coturn 주소·포트·크레덴셜을 매니저 서버 설정 항목으로 빼고, 서버가 발급하는 ICE 크레덴셜(use-auth-secret)로 cut-over해 배포마다 매니저에서 지정하도록 했다. UDP가 막힌 기업망을 위한 TURN-over-TCP 경로까지 고려한 실제 원격 지원 인프라의 토대다.
가상 Agent(vorange) 서버 부하 테스트 도구 구현 — 실 에이전트 패킷 캡처·재생 (OR-1749). 실 에이전트 없이 서버 확장성을 검증하려고, 실제 에이전트가 보내는 MQTT 패킷을 캡처해 수천 대 규모로 재생하는 가상 Agent(vorange) 부하 테스트 도구를 만들었다. 접속·status·system·detect·sprocess 등 토픽별 트래픽을 실물과 동일한 스키마로 흉내 내 브로커·서비스·MongoDB가 대량 동시 접속에서 어떻게 견디는지 실측할 수 있게 했고, 티켓 헤더 인증이 어긋나던 문제를 바로잡아 인증 경로까지 실환경과 일치시켰다. 이 도구가 곧바로 OR-1759(브로커 FD 고갈 crash loop)를 재현·확정하는 계측 기반이 됐다.
자동복구 인스톨러 자기종료 버그 수정 — KillProcessInPath가 부모 설치기를 종료 (OR-1760). 자동복구 설치 과정에서 인스톨러가 스스로 죽어버리는 버그를 추적해 고쳤다. 설치 경로의 잔여 프로세스를 정리하는 KillProcessInPath가, 같은 경로에서 돌고 있는 설치기(부모) 프로세스까지 함께 종료 대상으로 잡아 자기 자신을 죽이던 것이 원인이었다. 실행 바이너리를 %TEMP%로 복사해 설치 경로 밖에서 구동하도록 바꿔, 경로 정리 대상과 실행 주체를 분리해 자기종료를 원천 차단했다.
MongoDB 계측·서버 안정성과 운영 자동화
MongoDB 운영 통계 계측 — 상시·추세·온디맨드 3계층 + 워커 4벌 baseline 결함 선수정 (OR-1720). 제품의 주축 저장소인 MongoDB가 서버 모니터링 위젯에서 버전·연결수 4개 값만 노출하던 것을, serverStatus·dbStats·$indexStats에서 운영 판단에 직결되는 지표를 상시·추세·온디맨드 3계층으로 계측하도록 확충했다. 운영 서버 실측으로 sprocess가 전체 스토리지의 76%(4.86GB)를 차지하고 스캔 효율이 70:1(scannedObjects 577M vs returned 8.2M, COLLSCAN 51만회)임을 화면에 드러내, 쿼리 퇴화를 단일 숫자로 감시할 수 있게 했다. 선행 결함으로 rate baseline이 uvicorn 워커 4개에 4벌 따로 존재해 워커 첫 요청마다 값이 NULL로 사라지던 것을 Redis 단일 baseline(최소 구간 가드+GETSET 원자 교체)으로 고치고, /v3/health/system을 인증 뒤로 옮겨 무인증 노출을 막았다.
node.detect 실시간 반영 책임 분리 — producer/consumer 안티패턴 제거, event-driven 전환 (OR-301). 노드별 증상 가짓수(node.detect)의 실시간 broadcast를, 데이터 owner가 아닌 system.py가 주기 텔레메트리(status3)에 얹어 흘려보내던 producer/consumer 분리 안티패턴에서 걷어내 detect.py가 직접 발행하도록 재설계·배포했다. 값 하나 읽자고 노드 1만·60초 하트비트 기준 하루 findAndModify 1,440만 회를 paho 콜백 스레드에서 동기로 치던 hot-path 비용을 없애고, 신규 event_type 필드로 텔레메트리와 detect 갱신을 구분(에이전트 프로토콜 어휘인 command 오염 회피), day_start를 UTC 절대시각으로 실어 자정에 DB와 화면이 어긋나던 문제까지 정리했다. 모델 시뮬레이션 적대검증 후 실 MQTT 트래픽으로 동작을 확인했고, write 결과 의존을 없애 system.py 노드 write의 배치화(OR-1747) 길을 열었다.
mosquitto 2.1 watchdog 오탐 crash loop 규명·해소 — FD 1024 고갈 시 sd_notify 유실 (OR-1759). 가상 agent ~1,000대 동시 접속 부하 테스트 중 브로커가 8분 주기로 SIGABRT를 반복하는 crash loop를 인과 체인 끝까지 추적했다. mosquitto 2.1 벤더 유닛이 LimitNOFILE을 설정하지 않아 soft 1024 FD로 동작 → 접속 1개=FD 1개라 ~1,000 접속에서 고갈되고, sd_notify()가 호출마다 새 유닉스 소켓을 만드는데 EMFILE로 조용히 실패하자 systemd watchdog이 정상 동작 중인 브로커를 hang으로 오판해 사살한 것이 근본 원인이었다. drop-in에 LimitNOFILE=65536(MongoDB 64000·redis 65535 급, 재접속 폭풍 시 half-open 공존까지 산정)을 추가해 crash loop를 끝내고 setup.sh/update.sh heredoc에 1:1 동기했다. 고객사 노드 1,000대 초과 시 재발하는 지뢰였다.
폐쇄망 무인 서버 업데이트 스크립트 update.sh 신설 — 8단계 무인·오류 시에만 중단 (OR-1062). 매 단계 enter 입력을 기다리고 오류 확인을 설치자에게 맡기던 setup.sh update 모드가 고객사 현장 빠른 업데이트에 부적합한 문제를, sudo ./update.sh 한 줄로 끝까지 자동 진행하는 무인 업데이트 스크립트로 풀었다. 서비스 중지 확인 루프·@manager/dist 백업 후 교체·복사 실패 시 자동 복원·웹서버 경로 권한 검증·MongoDB ping 30초 생존 루프·7개 systemd 서비스 is-active 확인까지 각 단계 성공/실패를 명시 검증하고 실패 시에만 로그 출력 후 중단하도록 했다. 인터넷 불필요(USB 복사 후 실행)로 폐쇄망에 대응하며, 고객사 방문 전 임시 수단으로 서버 고도화 전까지의 공백을 메웠다.
Network Zone 운영자 UI 초기형 — 브라우저로 운용 체감 + gateway_mac 제안 UX (OR-1630). 서버 API가 완성된 Network Zone을 브라우저 UI만으로 직접 운용해보며 UX·워크플로·API 갭을 발굴하는 운영자 UI 초기형을 manager-web에 만들었다. zone 트리 CRUD·노드 리뷰 리스트(certainty·drift·route)·pin/unpin·recompute에 더해, 운영자가 12-hex 라우터 MAC을 손으로 치는 부담을 없애기 위해 노드가 이미 측정한 라우터에서 골라 확인하는 gateway_mac 제안 UX(근거 카드+명시 확인 가드)를 얹었다. 'measure-before-polish'를 운영자 경험에 적용해 본사 실규모 리허설을 거쳐 목표 고객사 투입 전 단계로 삼는 접근이다.
노드 자산 인벤토리 API — nodeinfo 노드×카테고리 최대 2,100요청을 단일 번들 1콜로 (OR-1761). OR-1641 그룹 요약 위젯의 서버측으로, 위젯 진입 시 노드×7~8 카테고리를 개별 호출(300노드 상한 silent truncation, 최대 2,100요청)하던 것을 노드 자산 원자료를 묶어 캐시로 주는 번들 엔드포인트 5종으로 교체했다. 서버는 파싱·판정을 하지 않고 분포·EOL·용도 적합 판정은 프론트가 하도록 프론트와 6라운드로 계약(CONTRACT.md v1.5)을 확정했고, node 컬렉션 기준 순회로 삭제 노드 고아 문서(본사 56%)를 배제, isSystem을 OS.SystemDirectory 드라이브 결합으로 산출(한 고객사 61% 오판 방지), ETag/304·gzip·stale-while-revalidate 캐시로 매시간 첫 진입자 대기까지 없앴다. AdapterRAM signed 32-bit 함정 등 데이터 지뢰를 사전 차단했다.
AI 진단 감사·Node baseline·원격 배포
감사 로그에 AI 진단(정팀장) 범주 신설 — live_response 고정 category 분기 (OR-1721). 정팀장(AI 원격 진단, OR-1716) 명령은 브라우저가 서버를 거치지 않고 노드에 직접 발행해 감사 레코드가 남지 않던 것을, 매니저가 public/audit/live-response로 함께 발행하도록 이미 이어 붙였으나, live_response_audit.py가 category를 payload와 무관하게 live_response로 못박아 정팀장 명령까지 Live CMD 배지로 뭉뚱그려지던 문제를 갈랐다. payload.category를 존중하되 없으면 기존값 유지하도록 바꾸고 AuditCategory에 AI_DIAGNOSIS를 신설, Beanie class_id 조회 누락을 피하기 위한 ai_diagnosis_log Document까지 설계해, 사고 조사·고객사 감사 대응에서 '정팀장이 실행한 것만' 필터링할 수 있게 했다. 브라우저 발행 방식의 위조·유실 한계와 에이전트 직접 기록으로 옮겨야 할 후속까지 명시했다.
Node 자원 일상 분류 서버 baseline 서비스 — EWMA+CUSUM 지속 이탈 판정 (OR-1613). 노드 자원사용량을 '그 노드가, 그 시간대에, 평소와 지속적으로 다르면 비일상'으로 판정하는 서버 baseline 서비스를 별도 격리 프로세스로 구현했다. 8지표×3통계(mean/std/p95)별로 (노드,지표,시간대) EWMA 평균·분산을 학습하고 CUSUM으로 지속 이탈을 누적하되, z를 z_cap으로 winsorize해 단일 스파이크는 임계(cusum_h)를 못 넘고 ~15분 지속·레벨 시프트만 발화하도록 했다. 꺼진 노드는 요약을 안 보내 지표로 못 보므로 presence(가동 패턴) 신호로 '평소 켜짐인데 다운/평소 꺼짐인데 새벽 가동'을 별도로 잡아 노드당 verdict 1개+top_reason으로 max-severity 롤업하고, 임계값을 store로 빼 shadow 캘리브레이션이 가능하게 했다.
고객사 서버 원격 배포 스크립트 신설 — 다중 서버 무인 배포 자동화 (OR-1733). 신규 패키지를 서버마다 SFTP 업로드 후 SSH로 설치 스크립트를 하나씩 돌리던 수동 과정을, packages/에 넣고 deploy 스크립트 1회 실행으로 여러 서버에 업로드→압축 해제→update.sh/setup.sh 무인 실행까지 처리하도록 자동화했다. Windows(plink/pscp, 없으면 자동 설치)·Mac/Linux(sshpass) 양쪽을 제공하고, 버전을 압축파일 내부 최상위 폴더명에서 읽어 로컬 VERSION이 낡아도 정확히 인식하며, 업로드 계정과 sudo 실행 계정 분리·번호 선택 대화형·서버당 로그·한 서버 실패해도 나머지 계속 진행·원격 실행 stdin 차단으로 무인 중 프롬프트 무한대기까지 막았다. 제품 스크립트(update.sh/setup.sh)는 무변경으로 업로드·실행만 대행한다.
패치노트와 부하 위젯 확장
릴리즈 노트/패치노트 1.6.242.0724 작성 — 컴파일 산출물 diff로 커밋 로그 없이 기능 교차검증 (OR-1730). 빌드 지점(매니저 buildHash·service·rest-api·에이전트·migration)을 체크포인트로 고정하고, 그 이후 변경만 추적하는 릴리즈 노트/패치노트(1.6.242.0724)를 작성했다. git 커밋 로그 직접 조회가 아니라 (1) 컴파일된 @manager/dist i18n 키/값 diff(신규 1,732키·변경 68·제거 14)와 (2) 0724 패키지 @server 파이썬 소스로 위젯 기능·live 여부를 교차검증하는 방식으로, 사용자 관점의 실제 노출 기능만 골라 신규 5(프로세스·부하 요약·일상 증상 감지·네트워크·파일함)+개선 2(1:N 명령 전면 개편·부하 요약 차트 10지표 확장)로 정리했다. 8쪽 PDF와 편집용 source.html을 산출하고 다음 패치노트의 시작점까지 문서로 남겼다.
전체 노드 부하 위젯 프로세스 탭 + '왜 올랐나' 원인 추적으로 범위 확장 (OR-1675). 전체 노드 부하 위젯에 '프로세스' 탭을 더하는 작업으로 시작했으나, 진행 중 '부하가 왜 올랐는지를 데이터로 답한다'는 문제로 범위가 확장됐다. 부하 캔들(5분 단위)에서 클릭한 시각이 속한 hour 버킷의 프로세스별 자원 랭킹을 CPU/Memory/I/O/Handle과 신규 Disk·유선·Wi-Fi 지표로 보여주고, Δ직전 시간·Δ어제 컬럼으로 '왜 이 시각이 고점인가'의 비교 대상을 제공한다. 조사 과정에서 전사 average가 '메시지 1장당 평균'이고 online과 count가 서로 다른 출처(status 1회성 vs system 60초)라는 지표 정의를 소스·운영 MongoDB 실측으로 규명해, count÷5가 실제 보고 노드 수임을 확인했다. '추정하지 않는다(관측된 값·항등식만)'와 '우리 것만 건드린다'는 두 원칙을 세우고 진행했다.
고객사 현장 이슈 분석
고객사 콜센터 PC명 중복·Delivery Optimization 분석 — 마스터 이미지 복제 공통 원인 규명 (OR-1737). 고객사 콜센터 환경에서 다수 PC의 Windows 컴퓨터 이름(hostname/NetBIOS)이 중복 설정된 문제와 다운로드 최적화(Delivery Optimization) 정책 검토, 두 사안을 조사·정리했다. PC명 중복은 마스터 이미지 복제 시 Sysprep /generalize 미실행으로 컴퓨터 이름·Machine SID·MachineGUID가 그대로 복제된 것이 원인으로, Orange Manager가 PC명을 식별 키로 쓰면 자산 오귀속으로 포렌식·모니터링 신뢰성이 훼손됨을 짚고 (이름/MachineGUID/SID/HW-UUID/MAC) 중복 매트릭스로 어느 계층까지 복제됐는지 판별하는 조사법을 제시했다. DO는 피어 식별이 PC명이 아니라 랜덤 GUID 기반이라 PC명 중복이 DO 오작동을 직접 유발하지 않음을 MS 공식 문서로 규명하고, 폐쇄망 우선이면 DODownloadMode 99/0, 대역폭 절감이면 그룹(2)+서브넷 제한을 택일 권고안으로 냈다. 두 사안이 '동일 사양 단말 대량 배포'라는 공통 원인에서 갈라짐을 결론으로 정리했다.
대시보드 요약·편집·시간대 정비
그룹별 노드 현황 요약 랜딩 신규 개발 — 노드 그리드 대신 공간·조직 단위 3단 구조 (OR-1641). 노드 위젯 진입 시 수백 개 노드 그리드 대신 그룹(강의실·부서) 단위 요약 카드가 먼저 뜨고, 카드→그룹 상세 리포트→노드 목록으로 좁혀 들어가는 3단 구조를 신규 개발했다(기존 그리드는 제거하지 않고 한 단계 뒤로). '제1실습실에 AI 수업 돌릴 수 있나(GPU·RAM·설치SW)' '올해 교체할 PC가 몇 대인가(EOL·설치 경과)' 같은 관리자의 실제 질문에 노드를 하나씩 열지 않고 공간·조직 단위 집계·필터로 답하는 것이 목표다. 요구사양 필터로 충족 그룹만 강조하고 미충족 노드의 사유(GPU 내장·RAM 8GB)까지 드릴다운하며, BIOS 제조일(SYSTEM) 수집을 요청서에 반영해 교체 검토 근거를 확보하고 서버 요구사항을 문서로 통합했다.
위젯 레이아웃 편집 화면 전면 개선 — 디자인 시스템 정합·미리보기 제거·다중배치 옵션 (OR-1753). 계정 메뉴 > 위젯 레이아웃 편집 화면을 5개 묶음으로 전면 개선했다. 가장 큰 위반이던 '편집 진입 시 화면 전체 bg-orange-300'을 '오렌지는 강조/선택 전용' 규칙에 맞춰 중립 slate 캔버스+헤더 오렌지 하단선+편집 중 배지로 바꾸고, 툴바 그라디언트·드롭 타겟·삭제 아이콘(xmark→trash)·버튼 위계·회색 글씨 금지까지 디자인 시스템 전반에 정합시켰다. 정적 수정에 그치지 않고 1920·1440 실화면에서 앞선 수정이 무효화되던 캔버스 색(실측 rgb 확인)·탭 41px 초과 잘림·배지 쭈그러짐 3건을 잡았고, 미리보기 기능과 6.1MB 스크린샷·메타데이터를 제거, 섹션 다중배치 옵션을 신설했다(값 없으면 다중=하위 호환, 마이그레이션 불필요).
시간대(UTC→로컬) 표시 규칙 전수 점검 및 위반 수정 — Playwright로 마커 실측 확정 (OR-1727). 화면 시각이 설정의 시간대(브라우저 자동 감지 로컬)로 표시되는지 사용처를 전수 조사하고 위반을 고쳤다. Playwright로 로그인 후 실제 응답을 캡처해 detect·node·audit·baseline·sprocess 등 7개 계열의 datetime이 전부 UTC 마커(Z/+00:00)로 옴을 확정했고, 마커가 있으므로 다수의 bare dayjs() 사용이 실제로는 정상(false positive)임을 가려냈다. 실제 위반은 두 유형 — API 원문 ISO를 포맷 없이 그대로 노출(그리드/상세패널)한 것과 new Date().toISOString()이 UTC 날짜라 KST 00~09시에 어제로 밀리던 기본 조회일/읽음처리 기준일 — 만 골라 로컬 변환으로 수정하고, 시간대 관례를 CLAUDE.md·위젯·Playwright 검증 문서에 남겼다.
히트맵 눈금 정렬 수정 — 축 눈금과 셀 경계 어긋남 해소 (OR-1731). 노드 현황 히트맵에서 축 눈금(시간대·항목) 라벨이 실제 셀 경계와 어긋나 어느 칸이 어느 값인지 오독되던 문제를 바로잡았다. 눈금 위치 계산을 셀 폭·오프셋 기준으로 정렬해 라벨과 셀이 정확히 대응하도록 고쳤다.