# 아이서티 오프라인 유지보수 준비: 사이드 대화 이관

작성: 2026-09-28 12:52:38 KST · profile ltb1021 · test
상태: **사용자 요청으로 보류. 다음 세션의 첫 행동은 마지막 답변 재출력과 질답 재개다. 구현 재개가 아니다.**

## 먼저 읽기

1. 이 문서: 상태, 확인 사실, 사용자 의도와 적용 경계.
2. `last-answer.ko.md`: 사용자가 새 세션에서 그대로 다시 받기를 요청한 마지막 답변 전문.
3. `conversation.ko.md`: 사이드 경계 이후 사용자 질문/assistant 답변/진행 메시지 전문.
4. `inspection.md`: 앞서 남긴 짧은 영문 교차 확인 기록.
5. `resume-prompt.txt`: 작업 세션 또는 fork 세션에 붙여 넣을 첫 요청문.

대화 전문은 사용자에게 보인 내용이다. 이 문서는 비공개 내부 사고 과정이 아니라,
후속 판단에 필요한 관측 사실, 설명 근거 요약, 제안과 미결정 사항을 전달한다.
이 디렉터리는 Git 밖의 전달 자료다. 부모 작업 세션의 Owner/코드/Git 문서는 수정하지 않았다.

## 7줄 재개 요약

- 목표: 외부망 단절 뒤에도 si 계정으로 Contextra를 쉽게 확인/수정/연결/관리할 수 있도록 준비.
- 사용자 의도: 노트북 SSH 우선, 실패하면 현장 서버의 GUI 또는 순수 콘솔로 직접 작업.
- 방향 동의: 수동 GUI, 짧은 ct 한글/영어 번호 메뉴, scoped 권한, 호스트 소스 연결, 현장 CA/주소 설정 도우미.
- 보류: image 생성/다운로드/보관과 실제 소스 연결 전환은 긴급 Crowd 패치가 끝난 뒤.
- 확인: LLM GGUF 파일 존재, 상주 LLM 서버 미확인; SSH UTF-8 정상; 물리 tty 한글은 미확인.
- 정정: Web의 Redis 접속정보 자동 등록/WSS 연결과 AI 호스트의 Redis IP 허용 규칙은 별개.
- 최신 지시: 질답 전체 보류 및 이관. 마지막 답변을 그대로 재출력한 뒤 사용자 후속 질문을 기다릴 것.

## 사용자 목표와 합의 방향

### 실행 편의

- 대상 서버를 외부망 단절 장소로 이동할 예정이라고 사용자가 설명했다. 일정 표현은 대화 당시 기준이다.
- CLI에 익숙하지 않으므로 긴 명령보다 `ct` 같은 짧은 진입점과 번호 메뉴를 원한다.
- 상태, 로그, 파일 편집, CA/네트워크 검사, 정상 Start/Stop, 변경 반영, 복구가 핵심 메뉴 후보다.
- 기존 guarded service와 배포 도구를 재사용한다. 별도의 경쟁하는 scheduler/service 체계를 만들지 않는다.
- GUI는 OS 재설치 없이 패키지 추가로 준비 가능하다고 설명했다. Xfce/VSCode 등을 설치하되
  자동 실행하지 않고 필요할 때만 켜는 방향에 사용자가 동의했다. 실제 설치는 아직 없다.
- GUI 미실행 시 상시 부하는 작게 유지할 수 있으나 설치 중 CPU/IO와 부가 서비스 자동 실행은 별도로 통제해야 한다.
- 실제 디스플레이/키보드/GUI 수용은 SSH만으로 확인되지 않는다.

### 코드 반영 방식

- 현재 애플리케이션은 image 내부이며 호스트에 편집용 전체 Git repo가 있다고 가정하면 안 된다.
- 사용자에게 image 방식과 bind-mount 방식의 차이를 설명했다. 현재 목적에는 혼합 방식이 추천되었다.
- 제안: SDK/Python 의존성/native 모듈은 image, 변경이 잦은 Python 앱 소스는 호스트 source에서 연결.
- 호스트는 편집 가능, 컨테이너 쪽 source mount는 read-only 가능. 전체 /opt/contextra를 덮어 가리지 않는다.
- Python 편집 뒤 대상 재시작은 가능하지만 C++/의존성은 build, Compose env/address 변경은 recreate가 필요하다.
- 적용 전 문법/계약 검사와 소스 snapshot/hash/복구점을 메뉴가 관리하는 방향. 아직 구현/전환 안 됨.
- **긴급 Crowd 패치가 우선. image 관련 준비와 source activation은 패치 후 최종 배포본에 맞춰 진행.**

### 권한

- si가 일반 source/setup/data를 편하게 읽고 쓰는 데 동의했다.
- `/workspace` 전체 chmod777, 전체 chown, 인증/DB/배포 원장 일괄 개방은 제안하지 않았다.
- 기존 service UID, private 파일 보호, 활성 모델 release와 DB 내부 보호를 유지한다.
- 새 파일도 접근되는지 생성 모드와 ACL/group 상속을 확인해야 한다. default ACL만으로 모든 명시0600 파일이 열린다고 단정하지 않는다.
- Artifact/training 파일 이동·삭제는 원장 정합성이 있으므로 관리 도구를 거치는 것으로 안내했다.
- 최종 경로별 권한 표는 last-answer에 있으며 사용자 확인을 기다리던 시점에 이관됐다.

### 현장 연결

- 사용자는 CA 전달, 주소/port 변경, 최초 로그인/WSS, Redis 허용을 반자동으로 쉽게 처리하길 원한다.
- 제안 수신 경로 `/workspace/contextra/setup/inbox/manager-ca.crt`는 **아직 미생성**이다.
- 사용자는 공개 CA를 수신 경로에 복사, 도구가 형식/기간/지문 확인 후 private 운영 위치에 적용한다.
- 자동 주소 탐색/무조건 적용보다 입력 -> 검사 -> 변경 계획 확인 -> 적용을 추천했고 사용자가 동의했다.
- 새 IP라면 AI 공개 주소, Redis publish 주소, Web source IP, login connectionConfigVersion, 인증서 SAN이 함께 정합해야 한다.
- 인증서 개인키는 AI에 유지하며 Web CA private key를 받지 않는다. TLS 검증 해제/무조건 재로그인은 금지.
- 실제 현장 인증서 삭제나 네트워크 차단 없이 격리 모의시험을 먼저 하고, 승인된 test/101 계정으로 비교하는 방향이다.
- 현장 서비스는 다른 사람이 사용 중일 수 있으므로 임의 Stop/restart/login/방화벽 변경을 하지 않는다.

### 관측 도구와 프로그램

- 추가 후보: mc, micro, ripgrep, fzf, Meld, acl, Xfce/VSCode/필수 확장. 정확한 package/version은 아직 잠그지 않았다.
- 기존 btop/ncdu/tree/tmux/htop/nvtop/ffmpeg/git/rsync/jq/build tools 등은 재사용한다.
- Grafana/Prometheus는 별도 optional container이며 현재 현장 image/container가 없었다.
- 원본 Compose에는 observability profile과 latest tag, Prometheus 15초 scrape 및 analytics:5000/metrics가 있다.
- 제안: 버전 고정/자동기동Off/용량상한/외부 plugin 다운로드 없는 dashboard. CPU/GPU exporter는 별도 필요.
- 관련 image 다운로드/보관도 Crowd 패치 후로 보류했다. 지금까지 pull/build/install 모두 없음.

## 실제 읽기 전용 확인

### 호스트와 경로

- 아이서티 AI: Ubuntu 24.04.5 LTS, si uid1001, sudo/docker 그룹.
- si는 Docker 직접 접근 가능. `sudo -n true`는 비밀번호 필요로 실패했다.
- `/workspace`는 root:root 0700으로 si가 하위 통합 root를 탐색하지 못한다.
- `/backup/contextra/artifacts`, `/backup/contextra/training`도 root 전용0700이었다.
- 설치 root `/workspace/contextra/runtime`, 통합 data `/workspace/contextra/data`.
- 호스트 bind view: data/artifacts -> /backup/contextra/artifacts;
  data/training -> /backup/contextra/training; data/models -> /training/contextra/models.
- data/debug와 data/offline도 /backup 쪽 bind view로 확인됐다. 복사본이 아니므로 삭제가 원본에 반영된다.
- Analytics image cf2cb9359575..., 내부 workdir /opt/contextra. 앱 source bind는 없고 데이터/설정/모델만 host mount.
- guarded `contextra-runtime.service`가 이미 있다. Docker와5개 mount 이후 site_guard가 검사/Start/Stop한다.
- 해당 service는 `NeedDaemonReload=yes`였다. 원인/다른 작업자 변경 여부 미확정이며 reload하지 않았다.

### GUI와 한국어

- default target은 graphical.target이나 display-manager unit/session 및 desktop shell은 없었다.
- 일부 Xorg/NVIDIA Xorg 패키지와 Firefox snap이 있어도 GUI 사용 준비 완료를 뜻하지 않는다.
- 현재 콘솔 session은 tty, code/codium 명령 없음. si의 .vscode-server 폴더는 있음.
- SSH: LANG=en_US.UTF-8, 실제 LC_ALL=C.UTF-8, Python 입출력/파일명 UTF-8, 한글 왕복/출력 PASS.
- 생성된 locales는 C/C.utf8/POSIX/en_US.utf8. 한국어 locale 유무와 한글 UTF-8 표시는 별개다.
- fonts-nanum 설치. 물리 console은 UTF-8/Fixed/8x16, fbterm/kmscon 없음. 물리 화면의 한글은 미확인.
- 제안: SSH/GUI 한글, 물리 console 영어/숫자 fallback. 명령·핵심 파일명 ASCII.
- 시각은 Asia/Seoul, NTP=yes, NTPSynchronized=yes, LocalRTC=no였다. 이동 후 내부 NTP/수동 확인 필요.
- systemd-networkd active, NetworkManager 없음. 네트워크 관리자 교체하지 않는다.

### LLM

- si Hugging Face cache에 실제 GGUF 파일 존재. 대표 main 파일은 Gemma4 약17.0GB,
  Qwen3.8 약17.6GB, Muse-Glimmer 약15.9GB, MiniMax 계열 약9.6/18.2GB.
- 이름은 현장 filesystem 관측값이며 공개 모델 진위/품질/완전성/실행 가능성을 검증한 것이 아니다.
- bounded PATH/process/service/container/image 조사에서 Ollama/vLLM/llama-server 상주 실행 미확인.
- 임의 LLM inference, 모델 로드/이동/삭제는 하지 않았다. Contextra와 공유 GPU 영향을 추후 따로 판단.
- 별도101 Web 호스트에는 Ollama listener가 관측됐지만 아이서티 AI 호스트와 혼동하지 않는다.

### 101 Web 교차 검증

- 실제 Java 프로세스 cwd는 `/mnt/workspace/mhj/projects/icerti_poc`였다.
- 처음 확인한 ssims_con_dev_fork 및 iCerti 플랫폼 이전 폴더는 현재 AI 연결 구현의 근거가 아니다.
- 현재 Java source에서 확인:
  - ManagedTokenService.java:424-435, 로그인 transaction에서 AI connection 등록 및 endpoint observation.
  - DefaultAiConnectionRegistrar.java:40-67, Redis 접속정보/버전/CA fingerprint 등록·갱신.
  - RecManagedConfiguration.java:201-207, advertised AI endpoint에 openIfNotReady 호출.
- Web source checkout의 Git HEAD 확인은 빈 결과로 확정하지 못했다. 소스의 동작을 읽었으며
  실제 로드된 class와 전체 재빌드 동등성, 현장 Web 서버와101의 버전 동일성은 검증하지 않았다.
- AI의 auth.py는 POST /api/v1/auth/login; bootstrap은 필요시 POST /api/v1/ai-control/certificates.
- WSS는 Web -> AI 방향이며, 첫 WSS 전 인증·Gateway 준비가 필요하다. connection success만으로 Redis를 증명하지 않는다.

### 실제 Redis 방화벽

- 현장 DOCKER-USER chain에서 지정된 AI publish 주소/port16379를 CTX-ICERTI-REDIS로 전달.
- 전용 chain은 현재 설정된 Web source IP 한 개만 RETURN, 나머지 DROP.
- `contextra-redis-access.service`는 `/workspace/contextra/data/site/redis-access.sh`를 실행하며 Docker에 연동.
- 이 네트워크 허용은 Web의 endpoint 저장 및 Redis command/key ACL과 서로 다른 층이다.
- 최신 정정: **화이트리스트 작업을 생략하지 않는다. 사용자가 외우지 않도록 현장 메뉴에 포함한다.**

## 경로와 참고 자료

- 코드 repo: `/workspace/contextra-analytics-runtime-lifecycle-refactor`.
- branch 역할: `task/runtime-lifecycle-refactor`; 다음 세션에서 actual HEAD/status/ownership 확인.
- 부모 Owner: `docs/profiles/ltb1021/topics/runtime-lifecycle/README.ko.md`. 사이드에서는 수정하지 않았다.
- 운영: `docs/deployment/ICERTI_PROVIDER_OPERATIONS.ko.md`.
- 최초 인증: `docs/integration/SECURE_BRIDGE_PROVISION.ko.md`.
- 기존 재로그인: `tools/icerti_login_once.py`; CA 지문 고정이 있으므로 새 현장용으로 그대로 실행하지 않는다.
- 설정 읽기: `control_sidecar/config.py`, 인증: `auth.py`, WebSocket: `websocket.py`.
- 메뉴/배포: `deployment_kit/cli.py`, guarded 기동은 현장 deploy-tools의 site_guard.
- 현재 CA host `/workspace/contextra/data/site/bridge/manager-ca.crt`, container `/run/bridge/manager-ca.crt`.
- host TLS `/workspace/contextra/data/site/tls`, Gateway mount `/run/ai-tls`.

## 접근 정보와 보안

- ICERTI SSH: si@58.233.207.31:1023; key `/root/.ssh/ltb1021_contextra_icerti_si_ed25519`;
  known_hosts `/root/.ssh/contextra_icerti_known_hosts`.
- 101 SSH: root@192.168.50.101:2222; key `/root/.ssh/ltb1021_contextra_101_ed25519`;
  known_hosts `/root/.ssh/contextra_101_known_hosts`.
- 사용자 제공 임시 sudo 파일: `/run/contextra-icerti-sudo.BO8eSj/password`.
- 직전 root700 parent/root600 regular file 확인. 암호 내용은 문서/로그/프롬프트에 기록하지 않았다.
- 이 파일은 사용자 생성이며 이번 보류/이관에서 임의 삭제하지 않았다. /run은 휘발성이므로 재개 시 존재·권한부터 확인한다.
- 이전 AvkYeS/DTs47d 파일을 현재 인증으로 가정하지 않는다. SSH 키/현장 인증은 보존한다.

## 다음 세션의 첫 응답 계약

1. handoff를 읽어 보류/안전 경계를 인지한다.
2. `last-answer.ko.md` 본문을 요약·정정·문체 변경 없이 그대로 재출력한다. 당시 관측값의 재출력이지 실시간 재확인 결과가 아니다.
3. 이관 요청 자체를 설치/권한/Runtime 변경 승인으로 해석하지 않는다. 사용자 다음 질문을 기다린다.
4. 구현이 재승인되면 Crowd 패치 완료 여부와 부모 작업 ownership부터 확인한다. 중복 Runtime 조작 금지.
5. 필요한 결정만 다시 묻고 이미 승인된 방향을 처음부터 재질문하지 않는다.

## 아직 하지 않은 일

GUI/패키지 설치, si 권한/ACL 변경, ct 메뉴 생성, 소스 복사/연결, image 생성/다운로드,
Grafana/Prometheus 준비·실행, CA 교체/로그인/CSR 발급, 방화벽 변경, daemon-reload,
서비스/채널 Start·Stop·재시작, 실제 오프라인/모의 연결 시험, LLM 실행을 하지 않았다.
기존 서버 코드는 모두 읽기 전용이었다. 로컬 side evidence와 이번 전달 문서만 생성했다.
