60 · 실행설계 — 동작방식 · 실행방법 · 연동방법


1. 동작방식 — 무엇이 언제 도는가

1.1 세 갈래로 돈다

갈래 언제 누가 깨우나
사람이 부른다 대장 보기 · 찾기 · 공간 보기 · 걷이 계획 cli·gui
자동 바퀴 원천이 바뀌었을 때 watch(08 §2) — 기본은 꺼짐
소비자 사건이 왔을 때 ConsumerSink — 진실원 → 캐시(01 §3)

1.2 한 판의 흐름

얼굴 → L3 서비스 → (L2 계산) → 사건 발행 → [진실원] → ConsumerSink → 캐시
                       ↑                                          │
                       └────────────── 읽기(read-through) ────────┘

★★ 읽기는 사건을 내지 않는다. 그림에서 오른쪽 화살표가 한 방향인 것이 그 뜻이다.

1.3 프로세스는 몇 개인가

프로세스 하는 일 없어도 되나
얼굴(cli·gui·web) 사람이 쓰는 판 —
sink 유일 writer 있어야 캐시가 선다(없으면 진실원 직접 읽기)
watch 자동 바퀴 꺼도 된다(기본 꺼짐)
추론 모델 답하기 없으면 없다고 말한다

★★★ 형제 코드를 부르는 일은 프로세스를 하나 더 띄우는 일이다(00 §2.4).

2. 실행방법 — 트랙마다 다르다

2.1 연동 트랙(py)

dnarna --version            # 무엇으로 도는지 먼저 찍는다
dnarna doctor               # 자원 점검: kafka·redis·ainsbus·ollama·변환 도구·얼굴
dnarna catalog scan --dry-run
dnarna catalog scan
dnarna catalog stats

★★ doctor 가 첫 명령이다. 이 호스트의 실측(kafka 없음 · redis 있음 · ollama 있음)을 사람이 바로 볼 수 있어야 「왜 느린가 · 왜 안 되나」를 묻지 않는다.

2.2 독립형

dnarna --standalone catalog scan     # 인프라를 아예 찾지 않는다

★ 「인프라가 없어서 폴백」과 「독립형이라 안 찾음」은 다른 상태이고 화면이 다르게 말한다(31 §1).

2.3 네이티브

cmake -S cpp -B build && cmake --build build      # 구성 단계가 첫 검사다(43 §1)
./build/nvr_cli catalog ls

2.4 검사

verify/run_all.sh          # 열 칸 + 초록/붉음/건너뜀 세 수(40 §7)
verify/standalone.sh       # 독립형임을 증명한다(42 §2)
verify/faces.sh            # 얼굴 동형(40 §5)

3. 연동방법 — 바깥과 잇는 네 자리

자리 어떻게 잇나 없을 때
Kafka infra.kafka.brokers · 토픽은 운영이 만든다(코드가 안 만든다) 로컬 사건 로그
Redis infra.redis.url 진실원 직접
ainsbus infra.ainsbus.socket · framing 심볼 확인 먼저(10 §2) 직접 경로
ollama nvr.model.endpoint · nvr.embed.endpoint 「엔진 없음: <무엇이>」

3.1 형제와 잇는 법

형제 잇는 법
자료(34 저장소) 읽기만(09 §2)
코드 부르지 않는다. 필요하면 프로세스 경계
ObjectDB·VectorDB 파일만 읽는다 — 스키마를 안다고 가정하지 않는다(11 §4)
sigbrain 봉투 규약만 맞춘다 · 보내지 않는다(04 §1.2)

3.2 원격과 잇는 법

계획 → 닿음 확인 → 읽기 순서를 지킨다(09 §1). 자격은 참조로만(80).

4. 기동 때 반드시 찍는 것 — 다섯 줄

판:        nvrpipe <버전> · py <판> · 트랙 <연동|독립형|네이티브>
설정:      키 N 개 해결 · 출처(env/파일/mirror) 요약 · cfg 지문
진실원:    kafka <있음/없음> · 로컬 로그 <자리>
캐시:      redis <있음/없음>
엔진:      <있음 모델 N개 / 없음: 무엇이>

★★★ 이 다섯 줄이 없으면 나중에 아무도 원인을 못 찾는다. 특히 cfg 지문 — 같은 코드가 다른 답을 낸 까닭은 거의 여기에 있다(01 §2).

5. 멈추는 법

무엇 어떻게
자동 바퀴 nvr.watch.enabled 를 끈다 — 다음 바퀴가 시작되지 않는다
지금 도는 굽기 중단 신호 · 중간 산출은 승격하지 않는다(08 §7)
발현 발현 정지 — 계획이 실행되지 않는다
원격 걷이 계획 취소 · 이미 보낸 요청은 못 되돌린다

★★ 못 되돌리는 것을 되돌린다고 적지 않는다.

6. 이 호스트에 실제로 이식한 결과 (2026-09-29)

자원 어떻게 섰나 주소
캐시(redis) 사용자 systemd nvrpipe-redis.service · linger=yes [가림]:16408 우리 것
진실원(kafka) 형제 브로커를 토픽 앞머리로 나눠 쓴다(01 §6.1) [가림]:19200
엔진 호스트 ollama · 모델 30 [가림]:11434
변환 도구 LibreOffice·hwp5txt·PyMuPDF·pptx·docx·openpyxl·tesseract·ffmpeg 전부 있다 —
얼굴 cli·web·gtk·qt5·glx 5/5 + 네이티브 5 —

6.1 세우는 법 — 한 줄

bash systemd/install_user_services.sh              # 캐시를 세운다
bash systemd/install_user_services.sh --with-timer # 자동 갱신 타이머까지
bash systemd/install_user_services.sh --uninstall  # 뺀다

6.2 ★★★ docker 를 쓰지 않은 까닭 — 재서 골랐다

$ docker run --rm hello-world       # 120s 안에 아무것도 찍지 않는다
$ docker compose -p nvrpipe up -d   # 유령 이름 충돌(ps -a 에도 inspect 에도 없는 ID)

이 호스트의 daemon 은 이미지는 당기지만 컨테이너를 실행하지 못한다. 재시작하면 풀리지만 형제 컨테이너 20 개가 함께 내려간다 — 남의 것을 내리지 않는다.

★★ docker/docker-compose.yml 은 그대로 두었다. daemon 이 성한 기계에서는 그쪽이 낫다. 그때는 infra.kafka.brokers 를 [가림]:19202 로 되돌리면 우리 브로커를 쓴다. 어느 길로 섰는지는 nvr doctor 가 주소로 말한다 — 설정이 아니라 붙은 자리를 찍는다.

6.3 아직 할 수 없는 것

무엇 왜
원격 걷이(파트너·내부망·KUTA) 자격이 안 걸렸다 — 참조 자리만 두었다(80 §3)
논문·특허 조회 같은 까닭(50 §0)
벡터 색인 faiss 이 기계에 없다 — numpy 로 내려가고 내려갔다고 말한다
장비에게 규격 묻기 nvr.record.spec.source = device 가 아직 안 섰다

7. 지금 선 것