Arda 개발 보고서
2026. 09. 29. github.com/Seuk-Team/Arda

목차 › 12. 부록

부록

본문에 실제로 쓰인 용어 · 산출물이 따르는 서식 · 근거 자료의 원문 위치 · 기준 저장소 Seuk-Team/Arda · 최종 갱신 2026. 09. 22.

1. 용어 정의

일반 IT 용어 사전이 아니라 이 보고서 본문에 실제로 나온 말만 모았고, 그 말이 Arda 안에서 가리키는 좁은 뜻을 적었다. 같은 단어라도 범위가 다르기 때문이다 — 예를 들어 "무결성 원장"은 블록체인 일반이 아니라 이력서·자소서의 SHA-256 을 쌓는 추가 전용 테이블 하나를 가리키고, "참고 지표"는 화면에 수치로 보이되 점수 재료가 아닌 값만을 말한다.

시스템명 — Arda

Arda(아르다)는 톨킨의 요정어(퀘냐)로 "영역(Realm)"을 뜻한다. 톨킨 세계관에서 모든 종족이 살아가는 터전의 이름이고, 보통명사로는 "경계가 정해진 하나의 영역"을 가리킨다(ADR-0014).

이 이름을 고른 이유는 둘이다. 하나는 "사람들이 모여 사는 터전"이라는 뜻이 채용과 곧바로 이어진다는 것이다. 다른 하나는 심판자가 아니라는 것이다 — 후보였던 Argus(감시자)·Themis(정의의 여신)를 뺀 이유가 "판정하는 존재라서 우리 원칙과 충돌한다"였다. Arda 는 판단하는 주체가 아니라 판단이 일어나는 장소다. AI 요약·파싱·에이전트는 심사를 돕는 무대를 깔 뿐이고, 최종 합격·불합격을 가르는 것은 언제나 채용 담당자다(ADR-0003 → 0034).

1-1. 채용 프로세스 본문 3·6장에서 쓰인 말

용어정의
ATS Applicant Tracking System — 지원자 추적 관리 시스템. 공고 등록부터 접수 · 단계별 심사 · 합불 통보까지를 하나의 시스템에서 다룬다
칸반 보드 지원자 카드를 단계별 열에 놓고 드래그로 옮기는 화면. 모든 이동은 누가 · 언제 · 왜까지 단계 이력으로 남는다
채용 단계 지원 접수(applied) → 서류 검토(screening) → 면접(interview) → 최종 합격(accepted) / 불합격(rejected) 다섯. DB enum 이 아니라 코드 상수 + 체크 제약이고, 전환 규칙은 서비스 레이어가 강제한다
전환 규칙 전진은 한 칸씩 · 역행은 항상 허용 · 불합격은 어느 단계에서든 가능하되 사유 없으면 422 · 일괄 변경은 전부 아니면 전무(부분 실패 시 409 전체 롤백) · 사용자는 삭제하지 않고 비활성화만
3축 채점 서류 심사 점수 체계 — 자격요건 60 · 우대사항 10 · 인재상 30 = 100점. 임계(기본 60) 이상은 면접으로, 미만은 서류 탈락으로 자동 이동한다(ADR-0034)
수동 우선 사람이 한 번 손댄 지원자는 이후 자동 판정 대상에서 빠지는 규칙. AI 판정을 사람이 되돌릴 수 있게 하는 안전장치다
확인 카드 에이전트의 쓰기 도구(단계 변경 · 면접관 배정 · 메일 발송)가 즉시 실행되지 않고 초안(pending_action)으로 반환되어 사람 승인을 받는 UI. 읽기 도구는 즉시 실행된다
fit-check 지원자 24명으로 3축 판정이 사람이 매긴 기대 등급(A/B/C)과 같은 순서로 나오는지 본 실측(docs/07_eval/fit-check-2026-09.md). 이 분석이 PR #182 가중치 개정으로 이어졌다
인적성 설문 접수 · 서류 검토 단계 지원자에게 메일로 보내는 10문항 5점 척도 설문. 카테고리 통계는 코드가 계산하고 AI 는 응답을 관찰 문장으로 재서술만 한다 — 성격 유형 판정 · 점수화 금지, 미응답 불이익 없음(ADR-0027)
게이트 일정을 끊는 두 판정 시점 — 초기 버전 2026. 09. 04. · 1차 완성 09. 30. 문서 근거가 아니라 배포본 대조와 관통 테스트로 판정한다
수직 슬라이스 초기 버전 게이트의 합격 조건 하나 — 공개 지원 폼 제출 → DB 저장 → 담당자 확인까지 실데이터로 관통하는 경로. 화면 · API 를 따로 세는 대신 끝에서 끝까지 하나를 뚫었는지로 본다

1-2. AI · 모델 본문 7장에서 쓰인 말

용어정의
아르 도구 호출 에이전트의 이름. 담당자 화면에서는 채팅 패널(Ctrl+K)로, 지원자 메일에서는 서명 "채용 에이전트 아르"로 나타난다. 도구 12종을 쓰고 쓰기 작업은 확인 카드를 거친다
도구 호출 (Tool-Calling) 자연어 한 문장을 검색 → 조회 → 단계 변경 같은 도구 호출로 분해해 순차 실행하는 방식. "백엔드 공고에서 3년차 이상 찾아서 상위 2명 면접으로 올려줘"가 한 단위다
RAG Retrieval-Augmented Generation — 먼저 문서를 찾아 근거로 붙이고 그 근거 안에서 LLM 이 답하는 방식. Arda 는 ko-sroberta 임베딩 + pgvector 시맨틱 검색에 키워드 폴백을 병행한다(ADR-0021)
프롬프트 체이닝 한 번에 묻지 않고 요약 → 평가 → 추천 3단으로 나눠 호출하는 구성(ADR-0022). 프롬프트 18개는 코드로 버전 관리한다(v2 · v3)
규칙 의도 라우터 인사 · 능력 · 기본 FAQ 처럼 뻔한 요청을 LLM 없이 코드로 답하는 앞단. 기본 질문 구간은 $0 이고, LLM 을 타는 아르 호출은 실측 평균 $0.0075 다
STT Speech-to-Text — 음성을 글로 옮기는 것. 프로덕션 기본은 OpenAI Whisper API(whisper-1)이고 STT_BACKEND=faster_whisper 면 서버 내 로컬 전사로 바뀐다(ADR-0038)
sLLM 경량 LLM. 지원자 개인정보를 외부 API 로 내보내지 않는 온프레미스 자체 서빙의 후보였고, 실측 후 심사 서빙에서는 뺐다
QLoRA 4-bit 양자화 + 저랭크 어댑터로 대형 모델을 작은 GPU 에서 파인튜닝하는 기법. Qwen3-8B 어댑터 3갈래(chat · summary · interview) 학습에 썼다
judge.py 모델이 무엇이든 같은 규칙(도구 이름 · no-tool 위반 · 확인 문구 · 인자 · 응답)으로 채점하는 자체 채점기(ai/qwen-training/judge.py). 같은 23건으로 학습 전 26.1% → Claude Haiku 69.6% → Qwen v9 73.9% 를 쟀다
회귀 하네스 띄워 둔 로컬 백엔드의 /agent/chat 에 시나리오 40개(정형 10 + 표현 변형 30)를 실호출해 정답 · 속도 · 창작 여부를 보는 자체 도구(backend/tests/prompt_regression/). 모델 · 프롬프트를 바꿀 때마다 돌리고, 운영 주소로는 돌리지 않는다 — 만든 지원서 · 평가가 추가 전용 원장에 영구히 남기 때문이다
ko-sroberta 한국어 문장 임베딩 모델. 스킬 · 학력 · 경력 문장을 768차원 벡터로 만들어 저장한다
pgvector PostgreSQL 확장 — 벡터 임베딩 저장과 유사도 검색. 운영 DB 이미지도 pgvector/pgvector:pg16 으로 맞췄다
ViT · MediaPipe 표정 분류(Vision Transformer)와 얼굴 랜드마크 추출. lie-detection 서비스가 쓰며 결과는 담당자 참고 지표로만 표시된다(ADR-0029 · 0032)
참고 지표 담당자 화면에 수치로 보이되 점수 · 합불 판정의 재료가 아닌 값. 표정 · 음성 신호가 여기에 해당한다
AI 추정 지원자가 폼에 적지 않아 이력서에서 추출해 채운 값에 붙이는 표식. 사람이 적은 값과 구분하기 위한 것이다

1-3. 아키텍처 · 운영 · 보안 본문 4·5·9장에서 쓰인 말

용어정의
ADR Architecture Decision Record — 결정 하나를 문제 · 결정 · 결과로 남긴 문서. 36편이며 "안 한 것"에도 ADR 이 있다(Kubernetes 제외 0001 · 실시간 공동편집 제외 0005)
도메인 오너제 한 사람이 도메인(폴더) 하나를 소유하고 그 로드맵이 작업의 기준이 되는 운영 방식(ADR-0007). 도메인 안의 판단은 묻지 않고 진행하며 승인 게이트가 없다
계약 우선 ERD(01-erd.md)와 API 문서(02-api.md)를 전원의 계약으로 두고, 코드와 같은 커밋에서 갱신하는 규칙. 문서 갱신 없는 스키마 변경은 금지다
헥사고날 (Ports & Adapters) 도메인이 요구하는 계약을 포트(ports/output/* ABC)로 두고 구현을 어댑터(adapter/outbound/{pg,llm,mail})로 갈아끼우는 구조. 전면이 아니라 부분 적용이다(ADR-0035)
Bounded Context 용어와 모델이 일관되게 통하는 경계. Arda 는 허브가 하나가 아니라서 hiring · talent · application · interview 4개로 나눴다
alembic 스키마 이행(마이그레이션) 도구. 리비전 26개이며 스키마 변경은 코드 · ERD 와 같은 커밋에 리비전을 함께 넣는다. 배포 때는 서버의 deploy-arda.sh 가 pull → build → alembic upgrade head → up 순으로 돌리고, 이행이 실패하면 거기서 멈춰 기존 컨테이너가 계속 산다
드리프트 검사 모델 정의와 alembic 이행 결과를 CI 가 비교해 이행 누락을 잡는 검사(2026-09-17 도입). 손 SQL 로 스키마를 맞추던 시절의 사고를 막기 위한 것이다
자동 CD main 머지 → 서버 systemd 타이머가 2분마다 확인 → pull · build · up -d. 머지가 곧 배포이므로 CI 빨간불인 PR 은 머지하지 않는다
CI 5잡 push · PR 마다 도는 GitHub Actions — 백엔드 린트(ruff --select F) · 백엔드 pytest(실제 PostgreSQL + pgvector 에 이행 후) · 프론트 oxlint + tsc -b + vite build · AI 면접 서버 pytest · flutter test
presigned URL S3 가 발급하는 일회성 업로드 URL. 브라우저가 S3 로 직접 올리므로 이력서 파일이 API 서버를 거치지 않는다
n8n 오픈소스 워크플로 자동화 도구. API 가 쏘는 웹훅을 받아 SMTP 로 메일을 보내고, n8n 이 멈춰도 API 가 5분마다 밀린 메일을 최대 3회 재발송한다(ADR-0030)
Caddy 리버스 프록시 · 인증서 자동 발급. 443 을 받아 FastAPI · lie-detection(/ai/) · n8n(/n8n/)으로 경로를 나눈다
SES · SQS AWS 메일 발송 · 메시지 큐 서비스. 초기 메일 경로였으나 폐기했고 현재는 n8n 웹훅 + SMTP 단일 경로다(ADR-0031 · 0036)
무결성 원장 이력서 · 자소서의 파일 지문(SHA-256)을 해시 사슬로 쌓는 추가 전용 테이블. DB 트리거가 UPDATE · DELETE · TRUNCATE 를 거부한다(ADR-0028)
앵커링 사슬 머리 해시를 외부 체인에 올려 그 시점 이후의 위 · 변조를 밖에서 검증할 수 있게 하는 것. 서명 개인키는 서버가 아니라 GitHub Actions 에 둔다
Sepolia · OpenTimestamps 못 박는 곳이 둘이다 — Sepolia(이더리움 테스트넷)는 탐색기 링크로 보여주는 쪽, OpenTimestamps 는 비트코인에 남기는 쪽. 운영 체인은 Polygon Amoy 무료 가스가 말라 Sepolia 로 옮겼다(2026-09-07)
JWT 담당자 인증 토큰(12시간). 비활성 계정은 이미 발급된 토큰이어도 401 이다
RBAC Role-Based Access Control — 역할 기반 접근 제어. Arda 의 등급은 위계가 아니라 조작 권한의 유무이며 admin · member 둘뿐이다(ADR-0017). 조회는 로그인만 하면 전부 허용된다
서비스 토큰 n8n · 판정 워커 같은 기계가 /internal/* 를 부를 때 쓰는 토큰. 사람 계정과 경로가 분리돼 있다

2. 관련 서식

사람 승인 게이트가 없는 팀이라 기록이 곧 리뷰다(2026-08-28 리뷰 게이트 폐지 → 09-04 브랜치→PR→자체 머지). 서식은 그 기록이 사람마다 다른 모양이 되지 않게 하는 장치이고, 아래 아홉 중 여덟은 코드 저장소에 파일로 있어 복사해 쓴다(마지막 칸반 · 피드백 YAML 만 팀 문서 사이트 저장소에 있다). 서식을 문서로 정한 이유는 단순하다 — 나중에 왜 그렇게 했는지 묻는 사람이 읽을 것이 PR 본문과 이 문서들밖에 없기 때문이다.

서식원본 위치반드시 들어가는 것
작업 지시서 docs/02_tasks/_template.md 배경 / 선행 조건 — 없으면 중단 / 측정 가능한 완료 조건 / 완성 예시 실물 하나 / 진행 원장 표 / 참고 문서 / Claude 에게 붙여넣을 지시문 / 검증 방법 / 막히면 · 되돌리기 / PR 체크리스트. 지시서 하나 = PR 하나이고, 2026-08-24 오너제 전환(ADR-0007) 뒤로는 각 도메인 오너가 자기 지시서를 쓴다
결정 기록 (ADR) docs/03_decision/NNNN-제목.md 머리말에 상태 · 확정일 · 작성 도메인 · 개정 대상 ADR 번호 · 연계 문서, 본문은 문제 → 결정(채택 / 거부) → 결과. 개정할 때 원문을 지우지 않고 절을 덧붙인다 — 반박되지 않은 근거는 "남은 숙제"로 그대로 남긴다
주차 계획 docs/00_overview/06-weekly.md §양식 주 마감 게이트 하나 + 도메인별 이번 주 한 줄 + 도메인 간 조율 표. 한 번 쓴 절은 고치지 않고 하위 절(WN-2)로 덧붙이며, 하위 절이 3개를 넘으면 그 주 계획이 틀렸다는 신호로 다음 주차 절에 원인을 한 줄 적는다
커밋 메시지 docs/00_overview/03-conventions.md <type>(<기능번호|도메인>): <한국어 요약> — type 은 feat · fix · docs · test · chore · refactor 여섯. 무엇이 왜 바뀌었는지와 실행 · 테스트 결과 한 줄을 넣는다
브랜치 · PR docs/00_overview/03-conventions.md 브랜치 <type>/<주제> → 실행 · 테스트 → push → PR 오픈 → CI 초록 확인 → 자체 머지. main 직접 push · force push 는 GitHub 브랜치 보호가 차단한다. PR 본문이 곧 기록이라 무엇을 왜 바꿨는지와 검증 결과를 붙인다
QA 시나리오 docs/00_overview/qa-scenarios.md 항목마다 전제(어떤 상태에서) → 절차(누가 뭘 클릭 · 입력) → 기대 결과(무엇이 보이면 성공) 셋. 확정되지 않은 UI 는 "(화면 확정 후 갱신)"으로 표시해 빈칸을 상상으로 채우지 않는다
메일 문구 docs/00_overview/email-templates.md 단계별 4종 + 접수 확인 1종의 제목 · 본문. 변수는 {{지원자명}} {{공고명}} {{회사명}} {{면접일시}} {{서명}} 다섯이고, 서명은 발송 주체에 따라 사람 · 아르 · 채용팀 세 갈래로 채워지되 합격 · 불합격은 주체와 무관하게 사람 이름이다. 운영 문구는 설정 화면에서 편집하며 email_templates 테이블의 오버라이드가 우선한다
스키마 이행 backend/alembic/ 스키마를 바꾼 커밋에 리비전 하나. 손 SQL 을 문서에 적던 방식은 2026-09-01 에 끝냈다 — 그날 로컬 테스트 101건 error 와 운영 AI 요약 전건 실패를 손 SQL 로 수습한 것이 도입 이유다. 남들은 uv run alembic upgrade head 한 줄로 따라온다
칸반 · 피드백 팀 문서 사이트의
_data/kanban/<아이디>.yml
_data/feedback/<아이디>.yml
규약은 03-conventions.md
사람마다 자기 파일만 고친다 — 소유 파일을 갈라 충돌을 구조적으로 없앴다. 칸반은 "지금 무엇을 하고 있나", 로드맵(docs/01_role/)은 "범위 · 마일스톤 · 큐 순서"로 역할을 나눠 진행률을 이중 관리하지 않는다

2-1. 지시서 골격

절 이름이 곧 체크리스트다. "완성 예시"에 형식을 글로 설명하지 않고 완성된 실물 하나를 붙이는 것이 이 서식의 핵심이다 — 나머지는 그것과 똑같이 만들면 되기 때문이다.

# [기능번호] 제목 > 담당: (이름) · 브랜치: feat/<기능번호>-<슬러그> · PR 단위: (어디까지 끝내고 PR 을 올리는지) ## 배경 ← 전체 그림에서 어디에 끼는지 2~3줄 ## 선행 조건 — 없으면 중단 ← 하나라도 없으면 시작하지 않는다. 없는 것을 상상해서 만들지 않는다 ## 완료 조건 ← "POST /… 호출 시 …가 저장된다" 처럼 측정 가능하게 ## 완성 예시 ← 설명이 아니라 완성품 하나(경로 + 내용) ## 진행 원장 ← 배치로 나눠 맡는 작업에만. 이어받는 사람은 이 표만 보면 된다 ## 참고 문서 ← 01-erd.md 의 해당 테이블 · 02-api.md 의 해당 경로 ## Claude에게 시키기 ← 그대로 붙여넣을 지시문. 한 번에 안 되면 완료 조건을 하나씩 ## 검증 방법 ← 실행 명령 + 무엇이 보이면 성공인지 ## 막히면 · 되돌리기 ← 30분 룰 · git checkout -- . · 브랜치째 버리기 ## PR 체크리스트

2-2. 브랜치 · 커밋 실물

기능 번호가 있는 작업은 번호를, 없으면 도메인명을 접두어로 쓴다. 아래는 실제 main 이력에서 가져온 것이다.

git switch -c feat/front-logout-in-account-menu feat(J7): 더미 지원서 10만 건 생성기 feat(front): React 라우팅 뼈대 fix(agent): 무관 질문 거절을 '데이터 근거' 기준으로 명확화 fix(front): PC 에서 AI 면접 카메라가 얼굴만 확대돼 보이던 것 (도메인 밖 편집)

마지막 줄처럼 남의 도메인 폴더를 고쳤으면 커밋 메시지에 명시하고 팀 채널에 사후 한 줄 공지한다. 스키마 · API · 공용 문서(docs/00_overview/ · CLAUDE.md · .github/)도 같은 취급이다.

3. 참고 자료

이 보고서의 수치와 판단은 아래 원문에서 왔다. 배포본 · 저장소 · 결정 기록 순으로 적었고, 서로 어긋날 때 무엇이 진실인지도 함께 적었다 — 요청 · 응답의 진실은 Swagger 이고, 스키마의 진실은 01-erd.md 이며, 담당 배정의 진실은 04-team.md 다.

3-1. 서비스 · 저장소

3-2. 저장소 안의 원문

3-3. 결정 기록 (ADR) 36편 2026-09-22 기준

번호 0018~0020 은 결번이고, 0030 은 같은 번호로 두 건이 있다(n8n 분리 · 거짓말 탐지 미결 확정). 개정된 ADR 도 목록에서 빼지 않는다 — 원 결정과 개정 결정이 함께 남아야 "왜 뒤집었나"를 설명할 수 있기 때문이다. 원문은 docs/03_decision/ 에 있다.

번호결정비고
0001Kubernetes 제외 — "한 달 안에 굴렸다고 말할 수 없는 것은 넣지 않는다"—
0002실시간 표정분석 제외개정 0029 로
0003AI 는 추천까지만 — 확정은 사람개정 0034 로 범위 조정(서류 · 면접 자동 판정, 최종 합불만 사람)
0004음성은 STT + 기존 텍스트 에이전트 (speech-to-speech 제외)—
0005실시간 공동편집 제외 — 메모는 행 추가 방식—
0006프론트 React 확정 — 서버 템플릿(Jinja) 기각—
0007작업 분배를 도메인 오너제로 전환—
0008에이전트 · 앱 정식 트랙 승격—
0009에이전트 UI 위치 (+ 음성 입력 위치)—
0010앱 Flutter 확정—
0011에이전트 모델 · 비용 (Haiku · 원가 실측)2026-09-15 실측으로 채팅 · 요약 기본 모델을 claude-haiku-4-5 로 유지하기로 했고, 그 개정은 후속으로 남았다
0012서류심사 AI 분류 기준—
0013면접관 배정 정책—
0014프로젝트 이름 — Arda위 1절 "시스템명" 참조
0015엔티티 리졸버 한글 수사 오탐 방지—
0016면접 일정 자동화 — 토큰 공개 페이지 + 기존 메일 파이프라인 재사용—
0017역할을 admin · member 2종으로 이분화 — 면접관 조회 제한 폐지—
0021RAG 파이프라인 — 임베딩 기반 시맨틱 검색—
0022프롬프트 체이닝 — 요약 → 평가 → 추천 단계별 파이프라인—
0023에이전트 평가 프레임워크 — 답변 품질 자동 측정—
0024sLLM 로컬 모델 전략 — 하이브리드 구성Qwen 어댑터는 R&D 자산으로 보존, 프로덕션은 Claude
0025운영 권한을 팀장 개인 계정에서 떼어낸다—
0026AI 면접은 한다 — 단 음성으로 긴장도 · 거짓말을 판별하지 않는다개정 0029 로
0027인적성 검사는 한다 — AI 는 응답 요약만, 성격 판정 금지—
0028이력서 · 자소서는 해시 사슬로 못 박는다공개 체인(Sepolia) 앵커는 2단계
0029표정 · 음성으로 진위를 판별한다 — 0002 · 0026 개정점수 미반영 참고 지표까지만
0030알림 · 메일 자동화를 n8n 워크플로로 분리AWS 를 떠나도 돌게
0030거짓말 탐지 운영 전 미결 사항 확정 — 0029 보완동일 번호 두 건
0031AWS 를 EC2 · S3 로 줄이고 나머지는 self-host 교체 가능하게—
0032추론 모델 3종 확정 — ViT · Whisper large-v3-turbo · Qwen3-8B온프레미스 기준
0033지원자 앱 로그인 — 이메일 + 생년월일 8자리—
0034에이전트 자동 심사 — 서류 · 면접은 아르가 판정, 최종 합불만 사람—
0035헥사고날 부분 적용 · Bounded Context 다중 스타 · Full DDD 는 안 함—
0036SQS 메일 워커 폐기 — n8n 단일 발송 경로로 고정—
0037회사 통합 API · 지원자 흡수 경로 4갈래 · 코어는 API push 하나—
0038실시간 면접 전사 — 프로덕션 기본을 OpenAI API 로STT_BACKEND 한 변수로 결정

3-4. 외부 근거

"안 한다"는 결정에 붙은 바깥 근거들이다. 기능을 뺀 이유를 발표에서 질문받았을 때 구현 난이도가 아니라 이 근거로 답하기 위해 ADR · 기획 문서 본문에 그대로 적어 두었다.

← 목차로