60 · 실행설계 — 동작방식 · 실행방법 · 연동방법
- 작성일: 2026-09-25 · readme 141~144 줄(「실행 — 동작방식 · 실행방법 · 연동방법」)에 답한다
- 상태(2026-09-25 · 전체 스프린트 뒤): 섰다 —
bin/nvr·doctor· 열 갈래 하위 명령이 돈다. 남은 것은 마지막 절.
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. 지금 선 것
doctor가 첫 명령이다 — 자원 점검부터.- 캐시가 사용자 systemd 로 산다. 로그아웃·재부팅에도 돈다(linger=yes).
- 연동 관문의 건너뜀이 0 이다 — 검사 342 전부 초록.
- 자동 갱신 타이머가 있다(
--with-timer). 다만nvr.watch.enabled가 꺼져 있으면 타이머가 깨워도 걷지 않고 꺼져 있다고 말한다 — 한쪽만 켜고 「돈다」고 믿지 않게. - 원격 걷이는 계획·닿음까지다(접속은
--run이고 사람이 켠다).